SvelteKit 最新中文文档教程(8)—— 部署 Node 服务端

news/2025/3/21 21:49:39/文章来源:https://www.cnblogs.com/yayujs/p/18785901

前言

Svelte,一个语法简洁、入门容易,面向未来的前端框架。

从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

image.png

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手等特性,非常适合构建轻量级 Web 项目

为了帮助大家学习 Svelte,我同时搭建了 Svelte 最新的中文文档站点。

如果需要进阶学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。

Node 服务端

要生成独立的 Node 服务端,请使用 adapter-node

使用方法

使用 npm i -D @sveltejs/adapter-node 安装,然后将适配器添加到您的 svelte.config.js

// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-node';export default {kit: {adapter: adapter()}
};

部署

首先,使用 npm run build 构建您的应用。这将在适配器选项中指定的输出目录(默认为 build)中创建生产服务端。

要运行应用程序,您需要输出目录、项目的 package.jsonnode_modules 中的生产依赖项。生产依赖项可以通过复制 package.jsonpackage-lock.json 然后运行 npm ci --omit dev 来生成(如果您的应用没有任何依赖项,可以跳过此步骤)。然后您可以使用以下命令启动您的应用:

node build

开发依赖项将使用 Rollup 打包到您的应用中。要控制某个包是打包还是外部化,请将其分别放在 package.jsondevDependenciesdependencies 中。

压缩响应

通常您会希望压缩来自服务端的响应。如果您已经在为 SSL 或负载均衡部署了反向代理服务端,那么在该层处理压缩通常会带来更好的性能,因为 Node.js 是单线程的。

但是,如果您正在构建自定义服务端并确实想在那里添加压缩中间件,请注意我们建议使用 @polka/compression,因为 SvelteKit 会流式传输响应,而更流行的 compression 包不支持流式传输,使用时可能会导致错误。

环境变量

devpreview 模式下,SvelteKit 将从您的 .env 文件(或 .env.local,或 .env.[mode],由 Vite 决定)中读取环境变量。

在生产环境中,不会自动加载 .env 文件。要做到这一点,请在您的项目中安装 dotenv...

npm install dotenv

...并在运行构建的应用之前调用它:

node +++-r dotenv/config+++ build

如果您使用的是 Node.js v20.6+,您可以使用 --env-file 标志代替:

node +++--env-file=.env+++ build

PORT, HOSTSOCKET_PATH

默认情况下,服务端将使用 0.0.0.0 并在端口 3000 上接受连接。可以使用 PORTHOST 环境变量对其进行自定义:

HOST=127.0.0.1 PORT=4000 node build

或者,还可以配置服务端在指定的 socket 路径上接受连接。如果您使用 SOCKET_PATH 环境变量来执行此操作,则会忽略 HOSTPORT 环境变量。

SOCKET_PATH=/tmp/socket node build

ORIGIN, PROTOCOL_HEADER, HOST_HEADERPORT_HEADER

HTTP 并不会为 SvelteKit 提供一种可靠的方法来获取当前请求的 URL。最简单的方式是设置 ORIGIN 环境变量来告诉 SvelteKit 应用在哪里被提供服务:

ORIGIN=https://my.site node build# 或者,例如本地预览和测试
ORIGIN=http://localhost:3000 node build

这样,当请求 /stuff 路径名时,就能正确解析到 https://my.site/stuff。或者,您可以指定用于告诉 SvelteKit 关于请求协议和主机的标头,由此 SvelteKit 可以构建 origin URL:

PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build

[!NOTE] x-forwarded-protox-forwarded-host 是事实上的标准请求头,用于在使用反向代理(如负载均衡器和 CDN)时转发原始协议和主机。只有在您的服务端位于受信任的反向代理之后时,才应设置这些变量;否则,客户端可能会伪造这些标头。
如果您在非标准端口托管代理,并且您的反向代理支持 x-forwarded-port,您也可以设置 PORT_HEADER=x-forwarded-port

如果 adapter-node 无法正确确定您的部署的 URL,在使用 表单 actions 时可能会出现以下错误:

[!NOTE] Cross-site POST form submissions are forbidden

ADDRESS_HEADERXFF_DEPTH

传递给 hooks 和端点的 RequestEvent 对象包含一个 event.getClientAddress() 函数,用于返回客户端的 IP 地址。默认情况下,这是发起连接的 remoteAddress。如果您的服务器位于一个或多个代理(如负载均衡器)之后,这个值将包含最内部代理的 IP 地址,而不是客户端的 IP 地址,因此我们需要指定一个 ADDRESS_HEADER 读取地址:

ADDRESS_HEADER=True-Client-IP node build

[!NOTE] 标头很容易被伪造。与 PROTOCOL_HEADERHOST_HEADER 一样,只有在您了解相关风险的情况下才应设置这些变量。

如果 ADDRESS_HEADERX-Forwarded-For,其值会包含用逗号分隔的 IP 地址列表。此时应通过 XFF_DEPTH 环境变量指定在您的服务器前有多少个受信任的代理。例如,如果有三个受信任的代理,代理 3 会转发客户端原始连接和前两个代理的地址:

<client address>, <proxy 1 address>, <proxy 2 address>

有些指南会告诉您读取最左边的地址,但这样会容易被伪造:

<spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>

因此,我们从右侧读取,并依据受信任的代理数量进行处理。在这个示例里,我们会使用 XFF_DEPTH=3

[!NOTE] 如果您确实需要读取最左侧的地址(并且不在意被伪造)——例如提供地理位置服务,在此情况下,IP 地址“真实性”比“可信度”更重要,您可以在应用中自行检查 x-forwarded-for 标头来实现这一点。

BODY_SIZE_LIMIT

接受的最大请求体大小,以字节为单位(包括流式传输时)。

请求体大小也可以使用单位后缀指定,包括千字节(K)、兆字节(M)或千兆字节(G)。例如 512K1M。默认值为 512kb。

您可以设置值为 Infinity(在适配器的旧版本中为 0)来禁用此选项,如果需要更高级的功能,可以在 handle 中自行实现更高级的检查逻辑。

SHUTDOWN_TIMEOUT

接收到 SIGTERMSIGINT 信号后,在强制关闭任何剩余连接之前等待的秒数。默认值是 30。在内部,适配器会调用 closeAllConnections。更多细节请参见 优雅关闭。

IDLE_TIMEOUT

在使用 systemd 套接字激活时,IDLE_TIMEOUT 用于指定当应用在没有请求的情况下经过多少秒会自动休眠。如果未设置,则应用会一直运行。详见 套接字激活 获取更多信息。

Options

该适配器可以通过多种选项进行配置:

// @errors: 2307
/// file: svelte.config.js
import adapter from '@sveltejs/adapter-node';export default {kit: {adapter: adapter({// 以下为默认选项out: 'build',precompress: true,envPrefix: ''})}
};

out

构建服务端输出的目录,默认为 build —— 也就是说,如果您使用默认目录,执行 node build 将在本地启动服务端。

precompress

使用 gzip 和 brotli 对资源和预渲染页面进行预压缩。默认值为 true

envPrefix

如果您需要更改用于配置部署的环境变量名称(例如,与您无法控制的环境变量冲突),可以指定一个前缀:

envPrefix: 'MY_CUSTOM_';
MY_CUSTOM_HOST=127.0.0.1 \
MY_CUSTOM_PORT=4000 \
MY_CUSTOM_ORIGIN=https://my.site \
node build

优雅关闭

默认情况下,当接收到 SIGTERMSIGINT 信号时,adapter-node 会优雅地关闭 HTTP 服务器。它将:

  1. 拒绝新的请求(server.close
  2. 等待已经发出的请求但尚未收到响应的请求完成,并在连接变为空闲后关闭连接(server.closeIdleConnections
  3. 最后,在超过 SHUTDOWN_TIMEOUT 秒后强制关闭所有仍处于活动状态的连接(server.closeAllConnections)。

[!NOTE] 如果您想自定义这一行为,您可以使用自定义服务端。

您还可以监听 sveltekit:shutdown 事件,该事件会在 HTTP 服务器关闭全部连接后触发。与 Node 的 exit 事件不同,sveltekit:shutdown 事件支持异步操作,并且无论服务器是否有未完成的任务(如未关闭的数据库连接),在所有连接都关闭后都会被触发:

// @errors: 2304
process.on('sveltekit:shutdown', async (reason) => {await jobs.stop();await db.close();
});

参数 reason 的可能取值包括:

  • SIGINT - 关机由 SIGINT 信号触发
  • SIGTERM - 关机由 SIGTERM 信号触发
  • IDLE - 关机由 IDLE_TIMEOUT 触发

套接字激活

当今大多数 Linux 操作系统都使用名为 systemd 的现代进程管理器来启动、运行和管理服务。您可以配置服务器来分配一个套接字,并在需要时按需启动应用。这被称为 套接字激活。在这种情况下,操作系统会向您的应用传递两个环境变量:LISTEN_PIDLISTEN_FDS。然后,适配器会在文件描述符 3 上进行监听,该描述符对应您创建的 systemd 套接字单元。

[!NOTE] 您仍然可以在 systemd 套接字激活中使用 envPrefixLISTEN_PIDLISTEN_FDS 始终无需前缀即可读取。

要利用套接字激活,请按以下步骤操作:

  1. 让您的应用作为一个 systemd 服务 运行。它既可以直接运行在主机系统上,也可以在容器内(例如使用 Docker 或 systemd 可移植服务)运行。

如果您额外向应用传递一个 IDLE_TIMEOUT 环境变量,它将在没有请求持续 IDLE_TIMEOUT 秒时,优雅地关闭。之后如果有新的请求到来,systemd 将自动重新启动您的应用。

/// file: /etc/systemd/system/myapp.service
[Service]
Environment=NODE_ENV=production IDLE_TIMEOUT=60
ExecStart=/usr/bin/node /usr/bin/myapp/build
  1. 创建一个配套的 socket 单元。适配器仅接受单个 socket。
/// file: /etc/systemd/system/myapp.socket
[Socket]
ListenStream=3000[Install]
WantedBy=sockets.target
  1. 通过运行 sudo systemctl daemon-reload 确保 systemd 识别了这两个单元。然后使用 sudo systemctl enable --now myapp.socket 在启动时启用该 socket 并立即启动它。这样当第一个请求到达 localhost:3000 时,应用将自动启动。

自定义服务端

该适配器会在您的构建目录中创建两个文件——index.jshandler.js。运行 index.js(例如,如果您使用默认 build 目录,那么执行 node build)将会在指定端口上启动服务器。

或者,您可以导入 handler.js 文件,它导出一个兼容 Express、Connect 或 Polka (甚至是内置的 http.createServer)的处理程序,并且设置你自己的服务器:

// @errors: 2307 7006
/// file: my-server.js
import { handler } from './build/handler.js';
import express from 'express';const app = express();// 添加一个独立于 SvelteKit 应用的路由
app.get('/healthcheck', (req, res) => {res.end('ok');
});// 让 SvelteKit 处理其他所有内容,包括提供预渲染页面和静态资源
app.use(handler);app.listen(3000, () => {console.log('listening on port 3000');
});

Svelte 中文文档

点击查看中文文档 - SvelteKit Node 服务端。

系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902657.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第四篇:本地私有化部署大模型(Ollama、vLLM、LMDeploy)

魔塔社区平台介绍 量化:将高精度数值转换成低精度表示的过程(通常用于减少模型的内存和提高推理速度) Ollama部署大模型 linux安装miniconda# 下载 Miniconda 安装脚本 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh # 运行安装脚本 bash…

用Adobe Illustrator编辑ArcGIS地图的方法

本文介绍在ArcGIS下属的ArcMap软件中,将绘制好的地图导出为.ai或者.eps格式文件,并在Adobe Illustrator软件中进一步编辑地图,并最终导出为图片格式的结果文件的方法~本文介绍在ArcGIS下属的ArcMap软件中,将绘制好的地图导出为.ai或者.eps格式文件,并在Adobe Illustrator软…

协议版iM蓝号检测,批量筛选iMessages数据,无痕检测是否开启iMessage服务

一、实现iMessage数据检测的两种方式:1.人工筛选,将要验证的号码输出到文件中,以逗号分隔。再将文件中的号码粘贴到iMessage客户端的地址栏,iMessage客户端会自动逐个检验该号码是否为iMessage账号,检验速度视网速而定。红色表示不是iMessage账号,蓝色表示iMessage账号。2…

记录项目调用链路

记录项目调用链路 内容 要理清项目中执行链路的调用关系,可以通过以下工具分类实现,涵盖从代码静态分析到运行时动态追踪的全链路管理:一、代码层调用关系分析 1. 静态代码分析工具PyCallGraph(Python) 生成代码调用关系图,直观展示函数调用链路。 pip install pycallgra…

部署kibana

获取kibana安装包 [root@elk1 ~]# wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.28-amd64.deb[root@elk1 ~]# ls kibana-7.17.28-amd64.deb kibana-7.17.28-amd64.deb# 安装kibana [root@elk1 ~]# dpkg -i kibana-7.17.28-amd64.deb 配置kibana [root@elk…

多线程程序设计(四)——Balking

本文摘要了《Java多线程设计模式》一书中提及的 Balking 模式的适用场景,并针对书中例子(若干名称有微调)给出一份 C++ 参考实现及其 UML 逻辑图,也列出与之相关的模式。 ◆ 适用场景 当线程访问的共享数据没有准备好时,就放弃后续的操作。 ◆ 解决方案 在临界区中判断共享…

A preLaunchTaskC/C++:g++.exe 生成活动文件已终止,退出代码为1。找到一个有点呆的bug

之前突然弹出这个问题,百思不得其解,今天突然发现,因为之前顺便命名了一个c++文件用来暂时装代码的,名字叫做a.cpp,编译器编译的过程中会生成一个可执行文件叫做a.exe,就冲突了,太傻了:-(

2025/3/21 【二叉树】二叉树理论基础节笔记

代码随想录 解题过程中二叉树主要有两种形式: 1. 满二叉树2. 完全二叉树 优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。 二、二叉搜索树 三、平衡二叉搜索树

C语言程序实验二

实验任务1:#include <stdio.h> #include <stdlib.h> #include <time.h>#define N 5int main() {int number;int i;srand(time(0));for(i = 0; i<N; ++i){number = rand()%100 +1;printf("20490042%04d\n", number);}return 0;} 问题1:生成一…

智慧工地合规穿戴监测系统

智慧工地合规穿戴监测系统基于计算机视觉的未佩戴安全帽检测算法通过实时视频流分析,可突破人工监管的物理局限,实现724小时全场景覆盖。该技术通过深度学习模型对人体姿态、头部特征进行精准识别,快速定位违规行为,为安全监管提供数据化、智能化的升级路径。核心算法模型采…

停车场立体车库人员滞留报警系统

停车场立体车库人员滞留报警系统采用AI算法,通过大量真实的场景样本训练后,能够在各种应用场景下及时准确的对场景中发生的人员入侵行为发出告警信息。通过对实时视频图像进行智能分析识别,可实现图像全屏周界防护、划定区域周界防护等功能。前端智能AI预警摄像机设备嵌入AI…

解决:按钮被禁用--Popconfirm 气泡确认框仍然可以弹出来展示

按钮被禁用,仍然可以点击,并弹出提示框 <template><a-popconfirmtitle="Are you sure delete this task?"ok-text="Yes"cancel-text="No"@confirm="confirm"@cancel="cancel"> <!-- 按钮被禁用 -->&l…