宣布 Nitro 2.6

Published at
-
Categories
Authors

在本文中,您可以探索 Nitro 的最新更新,这是一个用于构建平台无关的服务器端和后端应用程序的强大工具。NitroNuxt 提供了支持,并且对所有人都是可用的!

🌊 原生响应流

Nitro 2.6 包括 h3 1.8,支持原生 Web StreamsResponse。它还包括运行时和类型安全的请求验证工具、基于对象格式的事件处理程序以及其他功能!

Read more:

H3 v1.8 - 走向网络边缘

新版 H3 发布,支持 Web 和 Plain 适配器,Web 流支持,对象语法事件处理器,类型化事件处理器请求等更多功能!

Web Streams 现在支持 Node.jsBunDenoCloudflare WorkersVercel。对于不兼容的平台,Nitro 自动读取完整的流(#1624),并将其转换为兼容的格式。我们正在紧密合作,以扩展所有层上的流支持。

📦 运行时密钥兼容的导出条件

Nitro 2.6 现在自动根据 Runtime Keys Proposal (#1401) 添加导出条件。

使用平台导出条件,Nitro 可以智能地使用您项目库的适当构建,为每个部署目标。Unjs 包引入了与运行时键兼容的条件,例如 unjs/node-fetch-nativeunjs/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 现在自动捆绑自己的依赖项,如 h3defuhookableofetch 等。虽然许多这些都很小且紧凑,但捆绑它们导致显著的性能提升!

度量/模式外部依赖(2.5)捆绑依赖(2.6)
文件数量609
磁盘大小508K292K
磁盘大小(gzip)100Kb72Kb
启动34.7ms18ms
获取17.2 ms14.6ms
启动到获取53.2ms34.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)
  })
})

此外,还引入了三个全局钩子:requestbeforeResponseafterResponse (#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/untununjs/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:configprerender:initprerender:done 钩子。(#1519)
  • 支持缓存具有变量 host 和标头的事件处理程序。(#1184)
  • 支持预渲染查询链接探索。(#1474)
  • 支持通过 NITRO_UNIX_SOCKET 监听 UNIX 套接字。(#1201)
  • Cookie 标头自动分割。(#1452)

还有很多其他改进和修复。您可以在变更日志中找到详细的项目更改列表。