在这篇博文中,您可以探索 Nitro 的最新更新,这是一个用于构建平台无关的服务器端和后端应用程序的强大工具。Nitro 为 Nuxt 提供支持,并对所有人开放!
🌊 原生响应流
Nitro 2.6 集成了 h3 1.8,以支持原生 Web Streams 和 Response。它还包括运行时和类型安全的请求验证工具、对象格式的事件处理器等等!
阅读更多
H3 1.8 - 迈向 Web 边缘
H3 新版本带来了 Web 和普通适配器、Web 流支持、对象语法事件处理器、类型化事件处理器请求等等!
现在 Node.js、Bun、Deno、Cloudflare Workers 和 Vercel 都支持 Web Streams。对于不兼容的平台,Nitro 会自动读取完整流(#1624)并将其转换为兼容格式。我们正在与各个团队紧密合作,以在所有层面扩展流支持。
📦 运行时键兼容的导出条件
Nitro 2.6 现在基于 运行时键提案 (Runtime Keys Proposal)(#1401)自动添加导出条件。
通过使用平台导出条件,Nitro 可以智能地为每个部署目标使用您的项目库的适当构建。运行时键兼容的条件已引入到 unjs 包中,例如 unjs/node-fetch-native 和 unjs/ofetch,旨在将此方法标准化到更多包中。
对于高级用例,您可以使用 exportConditions
标志覆盖导出条件。
🧩 异步上下文和组合式 API
Nitro 2.6 引入了一个新的实验性 useEvent()
API,使请求事件在所有异步上下文中都可用,无需显式地将其作为参数传递给所有函数(#1546)。
这开启了一种强大的新设计模式,使得服务器事件可以使用 useEvent()
在任何异步上下文中访问。此功能的灵感来自 Vue 组合式 API (Composition API),并由 unjs/unctx 提供支持。
您可以通过设置 experimental.asyncContext: true
来启用此功能。
注意: 目前,此功能支持 Bun 和支持 AsyncLocalStorage
的 Node.js 环境。我们计划在 AsyncContext 提案 (proposal)
之后增加平台覆盖率。
🚀 打包运行时依赖
在构建生产应用程序时,Nitro 使用一个名为 vercel/nft 的工具来追踪 node_modules
文件夹中使用的文件,并将它们复制到 .output/server/node_modules
文件夹。这种方法有其优点,例如与无法通过 rollup 打包的原生模块良好协作。然而,这种方法也存在一些缺点:
- 诸如
package.json
文件等额外数据会被复制到输出目录。 - 由于
node_modules
解析,增加了启动开销。 - 追踪允许我们将 tree-shaking 输出优化到文件级别,而不是每个导出进行 tree-shaking。
- 当存在多个版本时,可能出现错误的导出条件解析和提升(hoisting)问题。
Nitro 2.6 现在会自动捆绑其自身依赖项,例如 h3
、defu
、hookable
、ofetch
等。虽然其中许多都很小巧,但将它们捆绑起来可显著提高性能!
测量 / 模式 | 外部依赖 (2.5) | 捆绑依赖 (2.6) |
---|---|---|
文件数量 | 60 | 9 |
磁盘大小 | 508K | 292K |
磁盘大小 (gzip) | 100Kb | 72Kb |
启动 | 34.7ms | 18ms |
抓取 | 17.2 ms | 14.6ms |
启动到抓取 | 53.2ms | 34.7ms |
(注意:基准测试在 MBA M2 上使用 Node.js v18.16.1 进行。有关基准测试脚本详情,请参阅 #1554。)
如果因任何原因需要之前的行为,您可以设置 experimental.bundleRuntimeDependencies: false
配置。
🪝 错误捕获和生命周期钩子
Nitro 2.6 引入了对两个新 API 的支持:useNitroApp().captureError()
和 event.captureError()
(#1463),并且它会自动捕获生命周期错误!
您可以使用 Nitro 插件来钩入自动捕获和手动捕获的错误。这使得与您的自定义日志基础设施集成变得容易。
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('error', async (error, { event }) => {
console.error(`${event.path} Application error:`, error)
})
})
此外,还引入了三个全局钩子:request
、beforeResponse
和 afterResponse
(#1545),允许通过 Nitro 插件全局拦截请求生命周期。
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('request', (event) => {
console.log('on request', event.path)
})
nitroApp.hooks.hook('beforeResponse', (event, { body }) => {
console.log('on response', event.path, { body })
})
nitroApp.hooks.hook('afterResponse', (event, { body }) => {
console.log('on after response', event.path, { body })
})
})
💾 默认持久化数据存储
Nitro 提供了一个多功能的键值存储层 (Key-Value storage layer),由 unjs/unstorage 提供支持。默认存储后端是内存中的,您可以配置和组合多个存储后端,用于开发和生产环境。
Nitro 包含一个标准 cache:
存储,内部用于缓存层和缓存路由规则。数据在开发过程中将存储在 .nitro/cache
(或 .nuxt/cache
)中。在 Nitro 2.6 中,引入了一个新的标准持久化存储 data:
(#1352)。这在开发和生产模式下都适用于兼容 Node.js 的运行时预设。
为了最小化捆绑包大小,我们在 unstorage 中创建了一个新的紧凑且可用于生产的 fs-lite 驱动程序 (driver)
。数据将存储在您项目内新的 .data/kv
目录中,并跨构建持久化。您可以直接使用 useStorage('data')
,并且您始终可以配置 data:
挂载点与您想要的后端,并在运行时使用它!
🗺️ 更轻的源代码映射
在 Nitro 2.6 中,已移除旧版 source-map-support
polyfill,并引入了一项优化,通过移除 node_modules
中库的内容映射,自动对 .output/server
目录内的 sourcemap 条目进行 tree-shaking。这些更改显著有助于减小生产捆绑包的大小。
为了利用 Node.js 的原生 sourcemap 支持,您可以设置 NODE_OPTIONS=--enable-source-maps
环境变量。此选项将在即将发布的版本中自动为 Nuxt 和 Nitro CLI 启用。
如果您需要禁用新的优化,可以使用 experimental.sourcemapMinify: false
标志。
💻 更好的 CLI 体验
Nitro CLI 现在支持 --preset
参数以及 --minify
/--no-minify
参数用于 nitro build
(#1621)。
最新的 nitro CLI 搭载了最新版的 unjs/listhen,其特色是 Cloudflare Quick Tunnels (--tunnel
) 由 unjs/untun 提供支持,以及 QR 支持 (--host --qr
) 由 unjs/uqr 提供支持。
开发服务器已迁移至使用 unjs/httpxy,这是一个 http-proxy
的 TypeScript 分支。此举旨在提升未来的性能和稳定性。
🔥 Firebase 第二代预设
得益于广泛的社区努力,Nitro 现在支持 Firebase 第二代函数(#1500)。
虽然默认目标仍为 v1,但我们强烈建议通过设置 firebase.gen: 2
配置进行迁移(了解更多)。
🔓 升级到 2.6
升级时,请确保更新项目的包管理器锁定文件和 node_modules
目录,以避免托管问题。
✨ 其他增强功能
- 已改进失败的预渲染路由的控制台输出格式。(#1471)。
- 带有 Cloudflare 集成的
event.waitUntil
API(#1421)。 - 支持使用
ignore
排除扫描文件(#1430)。 - 能够使用
ignore
选项忽略公共资产(#945)。 - 新增
iis
服务器预设(#1436)。 - 新增
prerender:config
、prerender:init
和prerender:done
钩子(#1519)。 - 支持带有可变
host
和头部信息的缓存事件处理器(#1184)。 - 支持预渲染查询链接探索(#1474)。
- 支持使用
NITRO_UNIX_SOCKET
监听 UNIX 套接字(#1201)。 - Cookie 头信息自动拆分(#1452)。
还有许多其他改进和错误修复。您可以在更新日志 (changelog) 中找到详细的更改列表。