
# Nitro v3 候选发布版来了！ {#nitro-v3-release-candidate-is-here}

> Nitro v3 RC 已发布，API 现已稳定。安装体积缩小 5 倍，支持运行时模式和 Vitest，还有更多更新。

自从[上一个测试版](https://github.com/nitrojs/nitro/releases/tag/v3.0.260903-beta)以来，40 多位贡献者提交了 240 多个变更；为 Nitro 提供支持的 [H3](https://github.com/h3js) 和 [UnJS](https://github.com/unjs) 生态也进行了许多改进。我们补齐了最后几项重要功能，完善了 API 的各个细节，并清理了遗留代码，让 v3 正式版有一个干净的起点。下面是本次更新的重点。

[开始使用 ↓](#-get-started)

## 📦 运行时模式 {#-runtime-mode}

Nitro 一直是服务器构建工具。现在，你可以**完全跳过构建步骤**，直接将其用作运行时（实验性功能）。

```sh
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` 仍只提供构建输出。

[阅读更多 →](/docs/cli#nitro-serve)

### 开发模式下的运行时模式 {#runtime-mode-in-development}

若要在 `nitro dev` 中也使用运行时模式，请设置 `builder: false`：

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  builder: false,
});
```

此时源文件会在 worker 中运行，并在每次变更时替换 worker。未安装 `rolldown` 时，`nitro dev` 现在会自动回退到运行时模式。若要以运行时模式创建新项目，请在 `nitro create` 中选择 **Runtime** 模板（参见下方“开始使用”）。

[阅读更多 →](/config/build#builder)

### nitro fetch {#nitro-fetch}

如果只需要获取一次响应，而不是启动服务器，可以使用 `nitro fetch` 或 `nitro curl`：它会从源文件启动服务器，发送单个请求，打印响应后退出。

```sh
npx nitro fetch /api/hello
```


[阅读更多 →](/docs/cli#nitro-fetch)

## 🧩 构建插件 {#-build-plugins}

新的 `buildPlugins` 选项接收一个插件列表，适用于所有构建器：`rollup`、`rolldown`、`vite`，甚至运行时模式。

```ts [nitro.config.ts]
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!"`,
      },
    },
  ],
});
```


[阅读更多 →](/config/build#buildplugins)

## 🪶 安装体积缩小 5 倍 {#-5×-smaller-install}

Nitro 现在只有 **6 个直接依赖**。构建器、polyfill 和驱动（`rolldown`、`unenv`、`unstorage`、`db0`）会在项目需要时按需安装。

与 Nitro v2（`nitropack`）相比，安装体积现在约**缩小了 15 倍**：外部依赖从 338 个减少到 6 个，安装文件从 7000 多个减少到 600 个以内。

<svg viewBox="0 0 768 160" role="img" aria-label="安装体积：nitropack@2 为 69 MB，nitro@beta 为 26 MB，nitro@rc 为 4.7 MB。外部依赖：nitropack@2 为 338 个，nitro@beta 为 20 个，nitro@rc 为 6 个。安装文件：nitropack@2 为 7,102 个，nitro@beta 为 1,418 个，nitro@rc 为 558 个。" style="width:100%;height:auto;font-family:inherit;font-size:14px">
  <text x="0" y="54" style="fill:var(--muted-foreground,currentColor)">nitropack@2</text>
  <text x="0" y="98" style="fill:var(--muted-foreground,currentColor)">nitro@beta</text>
  <text x="0" y="142" style="fill:var(--muted-foreground,currentColor)">nitro@rc</text>
  <line x1="320" y1="4" x2="320" y2="152" style="stroke:var(--muted-foreground,#888);opacity:.25" />
  <line x1="544" y1="4" x2="544" y2="152" style="stroke:var(--muted-foreground,#888);opacity:.25" />
  <text x="108" y="18" style="fill:var(--foreground,currentColor);font-weight:600">安装体积</text>
  <rect x="108" y="40" width="140" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="256" y="54" style="fill:var(--foreground,currentColor)">69 MB</text>
  <rect x="108" y="84" width="53" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="169" y="98" style="fill:var(--foreground,currentColor)">26 MB</text>
  <rect x="108" y="128" width="10" height="18" rx="4" style="fill:var(--brand,#e0427f)" />
  <text x="126" y="142" style="fill:var(--foreground,currentColor);font-weight:600">4.7 MB</text>
  <text x="332" y="18" style="fill:var(--foreground,currentColor);font-weight:600">外部依赖</text>
  <rect x="332" y="40" width="140" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="480" y="54" style="fill:var(--foreground,currentColor)">338</text>
  <rect x="332" y="84" width="8" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="348" y="98" style="fill:var(--foreground,currentColor)">20</text>
  <rect x="332" y="128" width="3" height="18" rx="1.5" style="fill:var(--brand,#e0427f)" />
  <text x="343" y="142" style="fill:var(--foreground,currentColor);font-weight:600">6</text>
  <text x="556" y="18" style="fill:var(--foreground,currentColor);font-weight:600">安装文件</text>
  <rect x="556" y="40" width="140" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="704" y="54" style="fill:var(--foreground,currentColor)">7,102</text>
  <rect x="556" y="84" width="28" height="18" rx="4" style="fill:var(--muted-foreground,#888);opacity:.35" />
  <text x="592" y="98" style="fill:var(--foreground,currentColor)">1,418</text>
  <rect x="556" y="128" width="11" height="18" rx="4" style="fill:var(--brand,#e0427f)" />
  <text x="575" y="142" style="fill:var(--foreground,currentColor);font-weight:600">558</text>
</svg>

<sub>在 linux-x64 上通过全新安装 `npm i` 测得（v2 使用 `nitropack@2.13.5`）。</sub>

开发错误页现在已内置。Nitro 仍然**没有 peer 依赖**。框架可以通过新的 [`deps`](/config/build#deps) 选项传入自己的可选依赖副本。

## 🧪 使用 Vitest 零配置测试 {#-zero-config-testing-with-vitest}

在 Vite 配置中添加 `nitro()`，然后运行 `vitest` 即可。

```ts [api.test.ts]
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` 可以正常工作，并且监听模式会在路由变化时重新运行测试。

[阅读更多 →](/docs/testing)

完整项目请参阅 [Vitest 示例](/examples/vitest)。

## 🔌 服务器入口选项 {#-server-entry-options}

现在可以在 `server.ts` 中配置其运行的服务器。将默认导出包装在 `defineServerEntry()` 中，即可获得类型化选项：

```ts [server.ts]
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](https://srvx.h3.dev/)：`port`、`hostname`、`reusePort`、`protocol`、`tls`、`silent`、`gracefulShutdown`、`maxRequestBodySize`、`trustProxy`，以及运行时专属的 `node`、`bun` 和 `deno` 设置。`NITRO_PORT` 和 `NITRO_HOST` 等环境变量仍具有更高优先级，因此仍可在运行时配置服务器。

[阅读更多 →](/docs/server-entry#server-options)

## 🏷️ 自定义环境 {#-custom-environments}

Nitro 之前已支持 `$development` 和 `$production` 配置覆盖。现在，你可以通过 `nitro dev`、`nitro build`、`nitro serve` 和 `nitro deploy` 的新 `--envName` 标志选择任意环境名称：

```ts [nitro.config.ts]
import { defineConfig } from "nitro";

export default defineConfig({
  $env: {
    staging: { runtimeConfig: { apiBase: "https://staging.example.com" } },
  },
});
```

```sh
npx nitro build --envName staging
```

服务器代码可以通过 `import.meta.envName` 获取环境名称，该值会由所有构建器在构建时替换。预渲染路由也使用相同的名称，因此会获得与服务器相同的配置覆盖。

```ts [routes/env.ts]
import { defineHandler } from "nitro";

export default defineHandler(() => ({ env: import.meta.envName })); // "staging"
```

[阅读更多 →](/docs/configuration#environment-specific-config)

## 🥟 运行时原生开发服务器 {#-runtime-native-dev-server}

`nitro dev` 现在可以原生运行在 Bun 和 Deno 上。开发服务器会使用运行时自带的服务器（`Bun.serve()`，或通过 [srvx](https://srvx.h3.dev/) 调用 `Deno.serve()`），而不再经过 `node:http` 兼容层。

```sh
bun --bun nitro dev
```

WebSocket 会使用代码运行所在运行时的适配器， [`devProxy`](/config/dev#devproxy) 也可正常工作：HTTP 请求通过 `fetch` 代理，WebSocket 则通过 crossws 代理。在 Node.js 上没有变化。

## ▲ Vercel

- **显式 ISR。** 只有 [`isr`](/deploy/providers/vercel#on-demand-incremental-static-regeneration-isr) 路由规则会启用 ISR。与其他平台一样，`swr` 和 `cache` 规则会使用 Nitro 内置缓存。
- **查询参数。** 设置 `allowQuery` 后，这些参数现在也会传递给处理器。
- **路由行为与应用一致。** Vercel 路由配置使用 rou3 构建，因此按请求方法匹配的规则、仅匹配标头的规则和 `redirect: false` 例外都会在运行时按预期匹配。
- **从 `package.json` 选择运行时。** 函数运行时会像 Vercel 一样从 `engines.node` 或 `engines.bun` 读取。
- **`waitUntil` 和可观测性。** `event.waitUntil()` 可在 Node.js 运行时中使用，并且始终会生成可观测性路由。

[阅读更多 →](/deploy/providers/vercel)

## ☁️ 本地 Cloudflare {#-local-cloudflare}

Durable Objects、Workflows 和 RPC 服务绑定现在可在 `nitro dev` 和 `vite dev` 中使用，并支持热重载。请在 `server.ts` 中导出它们，并在 Wrangler 配置中声明：

```ts [server.ts]
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，并支持发布/订阅和休眠。

[阅读更多 →](/deploy/providers/cloudflare#durable-objects)

## 🎁 更多更新 {#-and-much-more}

- **H3 v2 和 rou3 v1：** Nitro 现在基于它们的稳定版本运行。
- **KV 存储：** `useStorage` 现在是 `nitro/kv` 中的 [`useKV`](/docs/storage)。旧名称仍可使用。
- **缓存存储：** 缓存处理器和函数现在拥有独立的 [`cache`](/docs/cache#cache-storage) 存储。
- **异步插件：** `definePlugin(async (nitroApp) => {})` 现在适用于所有运行时。
- **HTTP：** 支持 `QUERY` 方法路由、带 `Allow` 标头的 `405`，以及由 `GET` 路由处理的 `HEAD` 请求。
- **中间件：** 现在也会在缓存路由上运行。
- **更快的 Node.js：** 全局 `Response` 使用 srvx 的 [`FastResponse`](/config/features#fastresponse)。
- **通过 URL 引用资源：** 通过 `new URL("./file.wasm", import.meta.url)` 加载的文件会随构建[输出](/docs/assets#files-referenced-by-url)。
- **tsconfig `paths`：** 所有构建器在开发和生产环境中都会解析这些路径。
- **平台路由：** Vercel、Netlify、Cloudflare Pages 和 EdgeOne 配置使用 rou3，因此路由行为与应用一致。
- **开发体验：** Chrome DevTools 工作区、Unix 套接字、[`devServer.drain`](/config/dev#devserver) 以及 Vite 8 内置开发模式。
- **其他更新：** `db0` 追踪、`prerender.ignoreStatusCodes`，以及 `nitro/builder` 中的 `startPreview()`/`deploy()`。

完整变更列表请参阅[更新日志](https://github.com/nitrojs/nitro/releases/tag/v3.0.261029-rc)。

## 🏁 开始使用 {#-get-started}

Nitro 现在内置了 `nitro create` 命令，用于取代 `create-nitro-app`：

::code-group
```sh [npm]
npx --min-release-age=0 nitro@latest create
```
```sh [pnpm]
pnpm dlx --config.minimum-release-age=0 nitro@latest create
```
::

::note
`--min-release-age=0`（npm）和 `--config.minimum-release-age=0`（pnpm）标志会跳过你配置的最低发布时间限制，因此可以在 RC 发布当天获取它。
::

选择一个模板：

- **Vite：** 带前端的全栈应用。
- **Rolldown：** 为生产环境打包的 API 服务器。
- **Runtime：** 使用运行时模式且无需构建步骤的 API 服务器（实验性功能）。

## ⬆️ 从测试版升级 {#-upgrading-from-beta}

大多数测试版应用无需修改即可升级。请先检查以下内容。

**要求**

- 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`）会导致[构建失败](/docs/routing#reserved-suffixes)。请重命名文件，或将后缀添加到 `scanSuffixes`。
- 配置中的钩子会在预设钩子之后运行，而不是替换它们。
- Node.js 预设会将 srvx `FastResponse` 用作全局 `Response`。设置 `features: { fastResponse: false }` 可禁用此行为。
- 使用 `rollup` 和 `rolldown` 时，tsconfig `paths` 指向包名对应源文件的路径现在会将这些源文件打包。

**重命名**

| 之前                                           | 之后                                             |
| ---------------------------------------------- | ------------------------------------------------ |
| `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` 前缀。

更多详情请参阅[迁移指南](/docs/migration)。

---

欢迎试用 RC，并[报告遇到的问题](https://github.com/nitrojs/nitro/issues)。正式版即将发布！🚀

- [GitHub](https://github.com/nitrojs/nitro)：提交问题和参与讨论
- [Discord](https://discord.nitro.build)：与社区交流
