迁移指南
Nitro v3 引入了有意的不向后兼容更改。本指南将帮助你从 Nitro v2 迁移。
Note
这是一份关于从 Nitro 2 迁移到 3 的动态文档。在使用测试版期间,请定期查看。
大多数迁移遵循相同的顺序:
#nitropack 已重命名为 nitro
NPM 包 nitropack(v2)已重命名为 nitro(v3)。
迁移: 在 package.json 中将 nitropack 依赖更新为 nitro:
{
"dependencies": {
-- "nitropack": "latest"
++ "nitro": "latest"
}
}有关 nightly 构建的更多信息,请参阅 nightly channel 指南。
迁移: 搜索你的代码库,并将所有 nitropack 实例重命名为 nitro:
-- import { defineNitroConfig } from "nitropack/config"
++ import { defineConfig } from "nitro"#最低支持的 Node.js 版本:20
Nitro 现在要求最低 Node.js 版本为 20,因为 Node.js 18 已于 2025 年 4 月结束生命周期。
请升级到最新的 LTS 版本(>= 20)。
迁移:
- 使用
node --version检查本地 Node.js 版本,并在必要时进行更新。 - 如果你使用 CI/CD 系统进行部署,请确保你的流水线运行的是 Node.js 20 或更高版本。
- 如果你的托管服务商管理 Node.js 运行时,请确保其设置为版本 20、22 或更高版本。
#自动导入已移除
Nitro v2 会自动让 defineEventHandler、useStorage、useRuntimeConfig、defineCachedFunction 和 defineNitroPlugin 等工具在服务器代码中无需导入即可使用(由 unimport 提供支持),同时还会公开 server/utils/ 的导出内容和虚拟的 #imports 模块。
Nitro v3 中已移除自动导入。imports 配置选项、#imports 模块和生成的 nitro-imports.d.ts 声明均不再可用。使用这些全局变量将导致构建或运行时错误。
迁移: 在所有位置添加显式导入。常用工具及其来源:
import { defineHandler, definePlugin, defineErrorHandler, HTTPError } from "nitro";
import { useKV } from "nitro/kv";
import { useRuntimeConfig } from "nitro/runtime-config";
import { defineCachedFunction, defineCachedHandler } from "nitro/cache";
import { useDatabase } from "nitro/database";
import { defineTask, runTask } from "nitro/task";
import { useNitroApp, useNitroHooks } from "nitro/app";
import { getQuery, getCookie } from "nitro/h3";你自己的 utils/ 目录中的工具也需要显式的(相对)导入:
import { defineHandler } from "nitro";
import { makeGreeting } from "../utils/hello.ts";
export default defineHandler(() => makeGreeting("Nitro"));#类型导入
Nitro 类型现在仅从 nitro/types 导出。
迁移: 从 nitro/types 导入类型,而不是从 nitro 导入:
-- import { NitroRuntimeConfig } from "nitropack"
++ import { NitroRuntimeConfig } from "nitro/types"#更改后的 Nitro 子路径导入
Nitro v2 引入了多个子路径导出,其中一些已被移除或更新:
nitropack/rollup、nitropack/core(使用nitro/builder)nitropack/runtime/*(使用nitro/*)nitropack/kit(已移除)nitropack/presets(已移除)
此前引入了实验性的 nitropack/kit,但现在已将其移除。未来可能会推出独立的 Nitro Kit 包,并明确其目标。
迁移:
- 使用来自
nitro/types的NitroModule,而不是 kit 中的defineNitroModule。 - 优先使用内置的 Nitro 预设(外部预设仅用于评估)。
#服务器目录扫描需选择性启用
在 Nitro v2 中,srcDir 默认为项目根目录,并且始终会扫描 routes/、api/、middleware/、plugins/ 和 tasks/ 等目录。
在 Nitro v3 中:
srcDir选项已弃用,推荐使用serverDir(继续使用srcDir仍然有效,但会记录警告)。serverDir默认为false,这意味着在显式启用之前不会进行目录扫描。否则,扫描到的路由、中间件、插件和任务不会被注册。
迁移: 在 Nitro 配置中设置 serverDir:
import { defineConfig } from "nitro";
export default defineConfig({
serverDir: "./server", // or "." to keep the v2 root layout
});将 serverDir 设置为 true 等同于设置为 "server"。路径将相对于项目根目录解析。
#已移除 App Config 支持
Nitro v2 支持捆绑的 app config,可以在 app.config.ts 中定义配置,并通过 useAppConfig() 在运行时访问这些配置。
此功能已被移除。
迁移:
在服务器目录中使用常规的 .ts 文件,并直接导入它。
#路由规则
路由规则的匹配和处理已移至 h3-rules。redirect、proxy、cors、headers、cache 和 swr 的规则形状现在由 h3-rules 定义,而 isr、prerender 和 static 仍是 Nitro 特有的规则。
NitroRouteConfig 和 NitroRouteRules 类型已弃用,推荐使用从 nitro/types 重新导出的 RouteRuleConfig 和 RouteRules:
-- import { NitroRouteConfig, NitroRouteRules } from "nitropack/types"
++ import { RouteRuleConfig, RouteRules } from "nitro/types"#运行时工具
运行时工具已移至单独的 nitro/* 子路径导出。有关用法,请参阅文档。
-- import { useStorage } from "nitropack/runtime/storage"
++ import { useKV } from "nitro/kv"| 工具 | Nitro v3 导入 |
|---|---|
useKV(原为 useStorage) | nitro/kv |
defineCachedFunction、defineCachedHandler | nitro/cache |
useDatabase | nitro/database |
useRuntimeConfig | nitro/runtime-config |
defineTask、runTask | nitro/task |
useNitroApp、useNitroHooks、getRouteRules | nitro/app |
Note
useStorage 已重命名为 useKV,nitro/storage 已重命名为 nitro/kv。storage 配置选项已重命名为 kv,而 devStorage 已由 $development 中的 kv 替代(如果你在预渲染期间依赖 devStorage,也请将其添加到 $prerender 中)。旧名称仍可作为已弃用的别名使用,并将在未来版本中移除。
#内部服务器请求
要向你自己的服务器发起内部请求(v2 的 useNitroApp().localFetch 模式),请使用从 nitro 导出的 serverFetch 工具。此外,还有一个 fetch 导出,它会将绝对路径(以 / 开头)路由到服务器,并将其他所有内容路由到全局 fetch。
import { serverFetch } from "nitro";
const res = await serverFetch("/api/hello"); // returns a web Response#插件
defineNitroPlugin 工具已重命名为 definePlugin,现在从 nitro 中导入。
-- export default defineNitroPlugin((nitroApp) => {
++ import { definePlugin } from "nitro"
++
++ export default definePlugin((nitroApp) => {#可选钩子
如果你之前在 Nitro 插件之外使用 useNitroApp().hooks,它可能是未定义的。使用新的 useNitroHooks() 可以确保获得一个实例。
import { useNitroHooks } from "nitro/app";
useNitroHooks().hook("request", (event) => {
/* ... */
});#错误处理器
defineNitroErrorHandler 工具已重命名为 defineErrorHandler,现在从 nitro 导入。
-- export default defineNitroErrorHandler((error, event) => {
++ import { defineErrorHandler } from "nitro"
++
++ export default defineErrorHandler((error, event) => {#H3 v2
Nitro v3 升级到 H3 v2,其中包含 API 更改。所有 H3 工具从 nitro/h3 导入。
#Web 标准
H3 v2 基于 Web 标准原语(URL、Headers、Request 和 Response)重写。
仅在 Node.js 运行时中可访问 event.node.{req,res}。event.web 已重命名为 event.req(Web Request 的实例)。
#响应处理
你应该始终显式地 return 响应体或 throw 一个错误:
-- import { send, sendRedirect, sendStream } from "nitro/h3"
-- send(event, value)
-- sendStream(event, stream)
-- sendRedirect(event, location, code)
++ import { redirect } from "nitro/h3"
++ return value
++ return stream
++ return redirect(event, location, code)其他更改:
sendError(event, error)→throw error(或throw new HTTPError(...))sendNoContent(event)→return noContent(event)sendProxy(event, target)→return proxy(event, target)
#请求体
大多数 body 工具可以被原生的 event.req 方法替代:
-- import { readBody, readRawBody, readFormData } from "nitro/h3"
++ // 使用原生 Request 方法
++ const json = await event.req.json()
++ const text = await event.req.text()
++ const formData = await event.req.formData()
++ const stream = event.req.body#请求头
H3 现在使用标准 Web Headers。请求头的值始终是纯 string(没有 null、undefined 或 string[])。
-- import { getHeader, setHeader, getResponseStatus } from "nitro/h3"
-- getHeader(event, "x-foo")
-- setHeader(event, "x-foo", "bar")
++ event.req.headers.get("x-foo")
++ event.res.headers.set("x-foo", "bar")
++ event.res.status // 替代 getResponseStatus(event)#处理器工具
-- import { eventHandler, defineEventHandler } from "nitro/h3"
++ import { defineHandler } from "nitro"lazyEventHandler→defineLazyEventHandleruseBase→withBase
#错误工具
-- import { createError, isError } from "nitro/h3"
++ import { HTTPError } from "nitro"
++ throw new HTTPError({ status: 404, message: "未找到" })
++ HTTPError.isError(error)#Node.js 工具
-- import { defineNodeListener, fromNodeMiddleware, toNodeListener } from "nitro/h3"
++ import { defineNodeHandler, fromNodeHandler, toNodeHandler } from "nitro/h3"#预设更新
Nitro 预设已针对最新兼容性进行更新。
一些(旧版)预设已被移除或重命名。
| 旧预设 | 新预设 |
|---|---|
node(Node.js 中间件) | node_middleware(导出已更改为 middleware) |
cloudflare、cloudflare_worker、cloudflare_module_legacy | cloudflare_module |
deno-server-legacy | 使用 Deno v2 的 deno_server |
netlify-builder | netlify 或 netlify_edge |
vercel-edge | 启用 Fluid compute 的 vercel |
azure、azure_functions | azure_swa |
firebase | firebase_app_hosting |
iis | iis_handler |
deno(Deno Deploy) | deno_deploy |
edgio | 已停止维护 |
cli | 因缺乏使用而移除 |
service_worker | 因不稳定而移除 |
Warning
node 和 deno 预设名称在 v3 中仍然存在,但它们现在指向不同的目标:
- 在 v2 中,
node预设会生成可复用的 Node.js 中间件。在 v3 中,node是node_server的别名,会构建一个完整的独立 Node.js 服务器。如果保留preset: "node",现在将获得一个独立服务器。使用node_middleware以保留 v2 的中间件输出。 - 在 v2 中,
deno预设面向 Deno Deploy。在 v3 中,deno是deno_server的别名,会构建一个自托管的 Deno 服务器。使用deno_deploy以继续部署到 Deno Deploy。
#Cloudflare 绑定访问
在 Nitro v2 中,可以通过 event.context.cloudflare.env 访问 Cloudflare 环境变量和绑定。
在 Nitro v3 中,Cloudflare 运行时上下文改为附加到请求的运行时对象上。
迁移:
-- const { cloudflare } = event.context
-- const binding = cloudflare.env.MY_BINDING
++ const { env } = event.req.runtime.cloudflare
++ const binding = env.MY_BINDING