在本文中,您可以探索 Nitro 的最新更新,这是一个用于构建平台无关的服务器端和后端应用程序的强大工具。Nitro 为 Nuxt 提供了支持,并且对所有人都是可用的!
🌊 原生响应流
Nitro 2.6 包括 h3 1.8,支持原生 Web Streams 和 Response。它还包括运行时和类型安全的请求验证工具、基于对象格式的事件处理程序以及其他功能!
Read more:
H3 v1.8 - 走向网络边缘
新版 H3 发布,支持 Web 和 Plain 适配器,Web 流支持,对象语法事件处理器,类型化事件处理器请求等更多功能!
Web Streams 现在支持 Node.js、Bun、Deno、Cloudflare Workers 和 Vercel。对于不兼容的平台,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 Composition API 的启发,由 unjs/unctx 提供支持。
您可以通过设置 experimental.asyncContext: true
启用此功能。
注意: 目前,此功能仅支持 Bun 和 Node.js 环境,它们支持 AsyncLocalStorage
。我们的目标是根据 AsyncContext 提案增加平台覆盖范围。
🚀 捆绑运行时依赖项
在构建生产应用程序时,Nitro 使用了一个名为 vercel/nft 的工具,以跟踪 node_modules
文件夹中使用的文件,并将它们复制到 .output/server/node_modules
文件夹中。这种方法有一些优点,比如很好地与不能用 rollup 捆绑的本地模块工作。然而,这种方法也有一些缺点:
- 复制到输出目录中的额外数据,如
package.json
文件。 - 由于
node_modules
解析导致的启动开销增加。 - 通过文件级别而不是逐出口导出进行树摇摆优化。
- 当存在多个版本时,可能存在错误的导出条件解析和提升问题。
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 存储层,由 unjs/unstorage 提供支持。默认存储后端是内存中的,您可以在开发和生产环境中配置并组合多个存储后端。
Nitro 包含一个标准的 cache:
存储,它在开发时内部用于缓存层和缓存路由规则。在 Nitro 2.6 中,引入了一个新的标准持久存储,data:
(#1352)。这适用于 Node.js 兼容的运行时预设的开发和生产模式。
为了最小化 bundle 大小,我们在 unstorage 中创建了一个新的紧凑且适合生产环境的fs-lite
驱动。数据将存储在项目中新的 .data/kv
目录中,并在构建之间保持持久。它已经准备好使用 useStorage('data')
使用,您总是可以配置 data:
挂载点,并将其在运行时使用!
🗺️ 更轻的源地图
在 Nitro 2.6 中,已删除的遗留 source-map-support
polyfill,并且已经引入了一个优化,自动在 .output/server
目录中去除库中的 node_modules
目录中的内容映射条目。这些更改显著有助于减少生产 bundle 大小。
为了利用 Node.js 的本地源地图支持,您可以设置环境变量 NODE_OPTIONS=--enable-source-maps
。在即将发布的 Nuxt 和 Nitro CLI 版本中,这将自动为 nitro build
启用 --minify
/--no-minify
参数。
如果您需要禁用新的优化,您可以使用 experimental.sourcemapMinify: false
标志。
💻 更好的 CLI 体验
Nitro CLI 现在支持 --preset
参数和 --minify
/--no-minify
参数。
最新的 nitro CLI 随附有最新的 unjs/listhen,它具有由 unjs/untun 和 unjs/uqr 提供支持的 Cloudflare Quick Tunnels(--tunnel
)和 QR 支持(--host --qr
)。
开发服务器已经迁移到使用 unjs/httpxy,这是 http-proxy
的 TypeScript 分支。这一举动旨在为未来提高性能和稳定性。
🔥 Firebase 第二代预设
感谢社区的大量努力,Nitro 现在支持 Firebase 第二代预设 (#1500)。
虽然默认目标仍然是 v1,但我们强烈建议通过设置 firebase.gen: 2
配置(了解更多)来迁移。
🔓 升级到 2.6
升级时,请确保更新项目包管理器的锁文件和 node_modules
目录,以避免托管问题。
✨ 其他改进
- 失败预渲染路线的控制台输出格式已经改进。(#1471)
event.waitUntil
API 与 Cloudflare 集成。(#1421)- 支持
ignore
以排除扫描的文件。(#1430) - 能够忽略公共资产
ignore
选项。(#945) - 新
iis
服务器预设。(#1436) - 新
prerender:config
、prerender:init
和prerender:done
钩子。(#1519) - 支持缓存具有变量
host
和标头的事件处理程序。(#1184) - 支持预渲染查询链接探索。(#1474)
- 支持通过
NITRO_UNIX_SOCKET
监听 UNIX 套接字。(#1201) - Cookie 标头自动分割。(#1452)
还有很多其他改进和修复。您可以在变更日志中找到详细的项目更改列表。