在本文中,您可以探索 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-supportpolyfill,并且已经引入了一个优化,自动在 .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.waitUntilAPI 与 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)
还有很多其他改进和修复。您可以在变更日志中找到详细的项目更改列表。