Node servers
要生成一个独立的 Node 服务器,请使用adapter-node。
使用
安装 npm i -D @sveltejs/adapter-node 后,将适配器添加到您的svelte.config.js中:
import import adapteradapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: any;
}
kit: {
adapter: anyadapter: import adapteradapter()
}
};部署
首先,使用npm run build构建您的应用。这将创建在适配器选项中指定的输出目录的生产服务器,默认为build。
您需要输出目录、项目的package.json以及node_modules中的生产依赖来运行应用程序。可以通过复制package.json和package-lock.json并运行npm ci --omit dev来生成生产依赖(如果您的应用程序没有依赖项,可以跳过此步骤)。然后,您可以使用以下命令启动您的应用程序:
node 编译
开发依赖将被打包到您的应用中,使用Rollup。要控制是否将某个包打包或外部化,请将其分别放置在您的package.json中的devDependencies或dependencies中。
压缩响应
通常您会希望压缩来自服务器的响应。如果您已经在部署使用 SSL 或负载均衡的反向代理服务器,由于 Node.js 是单线程的,因此在那个层面处理压缩通常可以获得更好的性能。
然而,如果您正在构建一个自定义服务器并且确实想在那里添加压缩中间件,请注意我们建议使用@polka/compression,因为 SvelteKit 流式传输响应,而更受欢迎的compression包不支持流式传输,可能会在使用时引发错误。
环境变量
在dev和preview中,SvelteKit 将从您的.env文件(或.env.local,或.env.[mode],由 Vite 确定。)中读取环境变量。
在生产中,.env 文件不会被自动加载。要实现这一点,请在您的项目中安装 dotenv...
npm 安装 dotenv
...在运行构建的应用程序之前调用它:
node -r dotenv/config build如果您使用 Node.js v20.6+,可以使用--env-file标志:
node --env-file=.env build端口,主机和SOCKET_PATH
默认情况下,服务器将在0.0.0.0上使用端口 3000 接受连接。这些可以通过PORT和HOST环境变量进行自定义:
HOST=127.0.0.1 PORT=4000 node build另外,服务器可以被配置为在指定的套接字路径上接受连接。当使用 SOCKET_PATH 环境变量执行此操作时,将忽略 HOST 和 PORT 环境变量。
SOCKET_PATH=/tmp/socket node buildORIGIN,PROTOCOL_HEADER,HOST_HEADER和PORT_HEADER
HTTP 不提供一种可靠的方法让 SvelteKit 知道当前正在请求的 URL。告诉 SvelteKit 应用正在被服务的最简单方法是将 ORIGIN 环境变量设置:
ORIGIN=https://my.site node build
# or e.g. for local previewing and testing
ORIGIN=http://localhost:3000 node build使用此方法,对/stuff路径名的请求将正确解析为https://my.site/stuff。或者,您可以指定头信息,告知 SvelteKit 请求协议和主机,从而构建原始 URL:
PROTOCOL_HEADER=x-forwarded-proto HOST_HEADER=x-forwarded-host node build[注意]
x-forwarded-proto和x-forwarded-host是事实上的标准头信息,用于在您使用反向代理(例如负载均衡器和 CDN)时转发原始协议和主机。只有当您的服务器位于受信任的反向代理后面时,才应设置这些变量;否则,客户端可能会伪造这些头信息。如果您在非标准端口上托管代理且反向代理支持
x-forwarded-port,您还可以设置PORT_HEADER=x-forwarded-port。
如果 适配器节点无法正确确定您的部署的 URL,您在使用表单操作时可能会遇到此错误:
[注意] 禁止跨站 POST 表单提交
地址头 和 xff 深度
The RequestEvent 对象传递给钩子和端点时,包括一个 event.getClientAddress() 函数,该函数返回客户端的 IP 地址。默认情况下,这是连接的 remoteAddress。如果您的服务器位于一个或多个代理(如负载均衡器)后面,则此值将包含最内层的代理的 IP 地址而不是客户端的,因此我们需要指定一个 ADDRESS_HEADER 来读取地址:
ADDRESS_HEADER=True-Client-IP node build[!注意] 标题很容易被伪造。例如,与
PROTOCOL_HEADER和HOST_HEADER一样,在设置这些之前,你应该 了解你在做什么。
如果 ADDRESS_HEADER 是 X-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。
[注意] 如果您需要读取最左侧的地址(并且不关心欺骗)——例如,提供地理位置服务,在这种情况下,IP 地址的真实性比可信性更重要,您可以通过检查您的应用程序中的
x-forwarded-for头来实现这一点。
BODY_SIZE_LIMIT
最大可接受请求体大小(以字节为单位,包括流式传输时),也可以使用单位后缀指定千字节(K)、兆字节(M)或千兆字节(G)。例如,512K 或 1M。默认值为 512kb。您可以通过将值设置为Infinity(在适配器旧版本中为 0)来禁用此选项,并在需要更高级功能时在handle中实现自定义检查。
SHUTDOWN_TIMEOUT
等待在接收到 SIGTERM 或 SIGINT 信号后强制关闭任何剩余连接的秒数。默认为 30。内部适配器调用 closeAllConnections。有关更多详细信息,请参阅 优雅关闭。
空闲超时
当使用 systemd 套接字激活时,IDLE_TIMEOUT指定了在收到无请求后应用自动休眠的秒数。如果没有设置,应用将连续运行。请参阅套接字激活获取更多详细信息。
选项
适配器可以配置为各种选项:
import import adapteradapter from '@sveltejs/adapter-node';
export default {
kit: {
adapter: any;
}
kit: {
adapter: anyadapter: import adapteradapter({
// default options are shown
out: stringout: 'build',
precompress: booleanprecompress: true,
envPrefix: stringenvPrefix: ''
})
}
};出
服务器构建目录。默认为 build — 即 node build 将在创建后本地启动服务器。
预压缩
启用使用 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优雅关机
默认情况下,当接收到 adapter-node 或 SIGTERM 或 SIGINT 信号时,它会优雅地关闭 HTTP 服务器。它将:
- 拒绝新的请求(
server.close) - 等待已完成但尚未收到响应的请求完成,并在它们变为空闲时关闭连接(
server.closeIdleConnections) - 最后,关闭在
SHUTDOWN_TIMEOUT秒后仍然活跃的任何剩余连接。(server.closeAllConnections)
[!注意] 如果您想自定义此行为,可以使用自定义服务器。
您可以在 HTTP 服务器关闭所有连接后监听 sveltekit:shutdown 事件。与 Node 的 exit 事件不同,sveltekit:shutdown 事件支持异步操作,并且当所有连接关闭时始终会触发,即使服务器有悬挂的工作,如打开的数据库连接。
var process: NodeJS.Processprocess.NodeJS.Process.on(event: string | symbol, listener: (...args: any[]) => void): NodeJS.Process (+12 overloads)Adds the listener function to the end of the listeners array for the event
named eventName. No checks are made to see if the listener has already
been added. Multiple calls passing the same combination of eventName and
listener will result in the listener being added, and called, multiple times.
server.on('connection', (stream) => {
console.log('someone connected!');
});
Returns a reference to the EventEmitter, so that calls can be chained.
By default, event listeners are invoked in the order they are added. The emitter.prependListener() method can be used as an alternative to add the
event listener to the beginning of the listeners array.
import { EventEmitter } from 'node:events';
const myEE = new EventEmitter();
myEE.on('foo', () => console.log('a'));
myEE.prependListener('foo', () => console.log('b'));
myEE.emit('foo');
// Prints:
// b
// a
on('sveltekit:shutdown', async (reason: anyreason) => {
await jobs.stop();
await db.close();
});参数 reason 有以下几种值:
SIGINT- 关闭操作由SIGINT信号触发SIGTERM- 关闭操作由SIGTERM信号触发空闲- 关闭由空闲超时触发
套接字激活
大多数 Linux 操作系统今天使用名为 systemd 的现代进程管理器来启动服务器并运行和管理服务。您可以将服务器配置为分配套接字并在需要时启动和扩展您的应用程序。这被称为套接字激活。在这种情况下,操作系统将传递两个环境变量到您的应用程序中——LISTEN_PID和LISTEN_FDS。然后适配器将在文件描述符 3 上监听,该描述符指向您必须创建的系统 d 套接字单元。
[注意] 您仍然可以使用
envPrefix与 systemd 网络套接字激活一起使用。LISTEN_PID和LISTEN_FDS总是带前缀读取。
利用套接字激活,请按照以下步骤操作。
- 运行您的应用作为systemd 服务。它可以直接在主机系统上运行,或者在容器内运行(例如使用 Docker 或 systemd 便携式服务)。如果您向应用传递一个
IDLE_TIMEOUT环境变量,当没有请求持续IDLE_TIMEOUT秒时,它将优雅地关闭。当有新请求到来时,systemd 将自动重新启动您的应用。
[Service]
Environment=NODE_ENV=production IDLE_TIMEOUT=60
ExecStart=/usr/bin/node /usr/bin/myapp/build- 创建一个配套的套接字单元。适配器仅接受一个套接字。
[Socket]
ListenStream=3000
[Install]
WantedBy=sockets.target- 确保 systemd 已识别这两个单元,通过运行
sudo systemctl daemon-reload。然后,在启动时启用套接字并立即使用sudo systemctl enable --now myapp.socket启动它。一旦对localhost:3000发起第一个请求,应用程序将自动启动。
自定义服务器
适配器在您的构建目录中创建两个文件——index.js和handler.js。运行index.js——例如node build,如果您使用默认的构建目录——将在配置的端口上启动服务器。
或者,您可以导入 handler.js 文件,该文件导出一个适用于与 Express、Connect 或 Polka(甚至只是内置的 http.createServer)一起使用的处理器,并设置自己的服务器:
import { import handlerhandler } from './build/handler.js';
import import expressexpress from 'express';
const const app: anyapp = import expressexpress();
// add a route that lives separately from the SvelteKit app
const app: anyapp.get('/healthcheck', (req, res) => {
res: anyres.end('ok');
});
// let SvelteKit handle everything else, including serving prerendered pages and static assets
const app: anyapp.use(import handlerhandler);
const app: anyapp.listen(3000, () => {
var console: ConsoleThe console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
- A
Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
- A global
console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object’s methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
See util.format() for more information.
log('listening on port 3000');
});Edit this page on GitHub llms.txt