自从上一个测试版以来,40 多位贡献者提交了 240 多个变更;为 Nitro 提供支持的 H3 和 UnJS 生态也进行了许多改进。我们补齐了最后几项重要功能,完善了 API 的各个细节,并清理了遗留代码,让 v3 正式版有一个干净的起点。下面是本次更新的重点。
#📦 运行时模式
Nitro 一直是服务器构建工具。现在,你可以完全跳过构建步骤,直接将其用作运行时(实验性功能)。
npx nitro serve新的 nitro serve 命令(别名 nitro start)可以在任意 Nitro 项目中直接从源文件启动生产服务器,与配置的构建器无关:
- 无需构建。 源文件会直接运行,无需提前编译。
- 适用于生产环境。 支持 WebSocket、定时任务、公共资源、
.env文件,并会在收到SIGINT/SIGTERM时平稳关闭。 - 运行迅速。 它会在内存中使用相同的编译路由器;在我们的基准测试中,其每秒请求数与 srvx 上直接运行 h3 的结果相近。
- 适合开发。 运行
nitro serve --dev可监听源文件变化并自动重启。
源文件会加载到主进程中;使用 buildPlugins 时,则会加载到 Node.js worker 中。TypeScript、JSX、别名、import.meta.*、raw/text/bytes 导入以及 WebAssembly 都与打包构建一样可用。文件会按需转换,虚拟模块由内存提供。nitro preview 仍只提供构建输出。
#开发模式下的运行时模式
若要在 nitro dev 中也使用运行时模式,请设置 builder: false:
import { defineConfig } from "nitro";
export default defineConfig({
builder: false,
});此时源文件会在 worker 中运行,并在每次变更时替换 worker。未安装 rolldown 时,nitro dev 现在会自动回退到运行时模式。若要以运行时模式创建新项目,请在 nitro create 中选择 Runtime 模板(参见下方“开始使用”)。
#nitro fetch
如果只需要获取一次响应,而不是启动服务器,可以使用 nitro fetch 或 nitro curl:它会从源文件启动服务器,发送单个请求,打印响应后退出。
npx nitro fetch /api/hello#🧩 构建插件
新的 buildPlugins 选项接收一个插件列表,适用于所有构建器:rollup、rolldown、vite,甚至运行时模式。
import { defineConfig } from "nitro";
export default defineConfig({
buildPlugins: [
{
name: "my-virtual-module",
resolveId: {
filter: { id: /^virtual:my-module$/ },
handler: (id) => `\0${id}`,
},
load: {
filter: { id: /^\0virtual:my-module$/ },
handler: () => `export default "Hello!"`,
},
},
],
});#🪶 安装体积缩小 5 倍
Nitro 现在只有 6 个直接依赖。构建器、polyfill 和驱动(rolldown、unenv、unstorage、db0)会在项目需要时按需安装。
与 Nitro v2(nitropack)相比,安装体积现在约缩小了 15 倍:外部依赖从 338 个减少到 6 个,安装文件从 7000 多个减少到 600 个以内。
在 linux-x64 上通过全新安装 npm i 测得(v2 使用 [email protected])。
开发错误页现在已内置。Nitro 仍然没有 peer 依赖。框架可以通过新的 deps 选项传入自己的可选依赖副本。
#🧪 使用 Vitest 零配置测试
在 Vite 配置中添加 nitro(),然后运行 vitest 即可。
import { expect, test } from "vitest";
import { serverFetch } from "nitro";
test("GET /api/hello", async () => {
const res = await serverFetch("/api/hello");
expect(await res.json()).toEqual({ hello: "world" });
});测试会在 nitro 环境中运行,路由、插件、运行时配置和 KV 的行为与服务器中完全相同。无需启动开发服务器。每个测试文件都会获得独立应用,vi.mock 可以正常工作,并且监听模式会在路由变化时重新运行测试。
完整项目请参阅 Vitest 示例。
#🔌 服务器入口选项
现在可以在 server.ts 中配置其运行的服务器。将默认导出包装在 defineServerEntry() 中,即可获得类型化选项:
import { defineServerEntry } from "nitro";
export default defineServerEntry({
port: 8080,
maxRequestBodySize: 1024 * 1024,
fetch(req) {
return new Response("Hello from server entry!");
},
});在 Node.js、Bun 和 Deno 预设中,这些选项会直接传给 srvx:port、hostname、reusePort、protocol、tls、silent、gracefulShutdown、maxRequestBodySize、trustProxy,以及运行时专属的 node、bun 和 deno 设置。NITRO_PORT 和 NITRO_HOST 等环境变量仍具有更高优先级,因此仍可在运行时配置服务器。
#🏷️ 自定义环境
Nitro 之前已支持 $development 和 $production 配置覆盖。现在,你可以通过 nitro dev、nitro build、nitro serve 和 nitro deploy 的新 --envName 标志选择任意环境名称:
import { defineConfig } from "nitro";
export default defineConfig({
$env: {
staging: { runtimeConfig: { apiBase: "https://staging.example.com" } },
},
});npx nitro build --envName staging服务器代码可以通过 import.meta.envName 获取环境名称,该值会由所有构建器在构建时替换。预渲染路由也使用相同的名称,因此会获得与服务器相同的配置覆盖。
import { defineHandler } from "nitro";
export default defineHandler(() => ({ env: import.meta.envName })); // "staging"#🥟 运行时原生开发服务器
nitro dev 现在可以原生运行在 Bun 和 Deno 上。开发服务器会使用运行时自带的服务器(Bun.serve(),或通过 srvx 调用 Deno.serve()),而不再经过 node:http 兼容层。
bun --bun nitro devWebSocket 会使用代码运行所在运行时的适配器, devProxy 也可正常工作:HTTP 请求通过 fetch 代理,WebSocket 则通过 crossws 代理。在 Node.js 上没有变化。
#▲ Vercel
- 显式 ISR。 只有
isr路由规则会启用 ISR。与其他平台一样,swr和cache规则会使用 Nitro 内置缓存。 - 查询参数。 设置
allowQuery后,这些参数现在也会传递给处理器。 - 路由行为与应用一致。 Vercel 路由配置使用 rou3 构建,因此按请求方法匹配的规则、仅匹配标头的规则和
redirect: false例外都会在运行时按预期匹配。 - 从
package.json选择运行时。 函数运行时会像 Vercel 一样从engines.node或engines.bun读取。 waitUntil和可观测性。event.waitUntil()可在 Node.js 运行时中使用,并且始终会生成可观测性路由。
#☁️ 本地 Cloudflare
Durable Objects、Workflows 和 RPC 服务绑定现在可在 nitro dev 和 vite dev 中使用,并支持热重载。请在 server.ts 中导出它们,并在 Wrangler 配置中声明:
import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject {
async fetch() {
const count = ((await this.ctx.storage.get<number>("count")) || 0) + 1;
await this.ctx.storage.put("count", count);
return Response.json({ count });
}
}
export default { fetch() {} };开发模式下也支持绑定和 waitUntil。cloudflare_durable 预设已合并到 cloudflare_module:添加 $DurableObject 绑定后,WebSocket 升级请求就会转发给共享的 Durable Object,并支持发布/订阅和休眠。
#🎁 更多更新
- H3 v2 和 rou3 v1: Nitro 现在基于它们的稳定版本运行。
- KV 存储:
useStorage现在是nitro/kv中的useKV。旧名称仍可使用。 - 缓存存储: 缓存处理器和函数现在拥有独立的
cache存储。 - 异步插件:
definePlugin(async (nitroApp) => {})现在适用于所有运行时。 - HTTP: 支持
QUERY方法路由、带Allow标头的405,以及由GET路由处理的HEAD请求。 - 中间件: 现在也会在缓存路由上运行。
- 更快的 Node.js: 全局
Response使用 srvx 的FastResponse。 - 通过 URL 引用资源: 通过
new URL("./file.wasm", import.meta.url)加载的文件会随构建输出。 - tsconfig
paths: 所有构建器在开发和生产环境中都会解析这些路径。 - 平台路由: Vercel、Netlify、Cloudflare Pages 和 EdgeOne 配置使用 rou3,因此路由行为与应用一致。
- 开发体验: Chrome DevTools 工作区、Unix 套接字、
devServer.drain以及 Vite 8 内置开发模式。 - 其他更新:
db0追踪、prerender.ignoreStatusCodes,以及nitro/builder中的startPreview()/deploy()。
完整变更列表请参阅更新日志。
#🏁 开始使用
Nitro 现在内置了 nitro create 命令,用于取代 create-nitro-app:
npx --min-release-age=0 nitro@latest createNote
--min-release-age=0(npm)和 --config.minimum-release-age=0(pnpm)标志会跳过你配置的最低发布时间限制,因此可以在 RC 发布当天获取它。
选择一个模板:
- Vite: 带前端的全栈应用。
- Rolldown: 为生产环境打包的 API 服务器。
- Runtime: 使用运行时模式且无需构建步骤的 API 服务器(实验性功能)。
#⬆️ 从测试版升级
大多数测试版应用无需修改即可升级。请先检查以下内容。
要求
- Node.js
>=22.22.0。 - 将构建器(
rolldown、rollup或vite)添加到devDependencies。
行为变化
- 缓存条目默认存储在内存中。设置
cache: { driver: "kv" }可继续使用 KV 存储。 routes/docs/[...slug].ts这样的捕获所有路由现在也会匹配/docs。- 扫描文件名中的点分后缀必须是方法(
.get)、环境(.dev)或已知文件扩展名(.xml、.json等)。其他后缀(例如routes/hello.world.ts)会导致构建失败。请重命名文件,或将后缀添加到scanSuffixes。 - 配置中的钩子会在预设钩子之后运行,而不是替换它们。
- Node.js 预设会将 srvx
FastResponse用作全局Response。设置features: { fastResponse: false }可禁用此行为。 - 使用
rollup和rolldown时,tsconfigpaths指向包名对应源文件的路径现在会将这些源文件打包。
重命名
| 之前 | 之后 |
|---|---|
rollup:before / rollup:reload 钩子 | build:config / build:reload |
experimental.vite.* | vite.* |
unenv 选项 | alias、inject、polyfills、builtinModules |
cloudflare_durable 预设 | cloudflare_module |
deno_deploy 预设 | deno_server |
platform_sh 预设 | upsun |
exports.cloudflare.ts / cloudflare.exports | 从 server.ts 导出 |
Vercel future.nativeSWR | isr 路由规则 |
已移除
winterjs预设。netlify.images、vercel.regions、prerender.retry和prerender.retryDelay选项。cloudflare:email和cloudflare:queue钩子中的event字段。
预设输出
- Netlify 输出已移至
.netlify/v1。 - Azure 默认使用 Functions v4 编程模型。
- Cloudflare Pages 和 EdgeOne 不再为相对
redirect目标添加baseURL前缀。
更多详情请参阅迁移指南。
欢迎试用 RC,并报告遇到的问题。正式版即将发布!🚀
