发布 Nitro 2.6

发布于
-
分类
作者

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

🌊 原生响应流

Nitro 2.6 集成了 h3 1.8,以支持原生 Web StreamsResponse。它还包括运行时和类型安全的请求验证工具、对象格式的事件处理器等等!

阅读更多

H3 1.8 - 迈向 Web 边缘

H3 新版本带来了 Web 和普通适配器、Web 流支持、对象语法事件处理器、类型化事件处理器请求等等!

现在 Node.jsBunDenoCloudflare WorkersVercel 都支持 Web Streams。对于不兼容的平台,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 组合式 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 现在会自动捆绑其自身依赖项,例如 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 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:configprerender:initprerender:done 钩子(#1519)。
  • 支持带有可变 host 和头部信息的缓存事件处理器(#1184)。
  • 支持预渲染查询链接探索(#1474)。
  • 支持使用 NITRO_UNIX_SOCKET 监听 UNIX 套接字(#1201)。
  • Cookie 头信息自动拆分(#1452)。

还有许多其他改进和错误修复。您可以在更新日志 (changelog) 中找到详细的更改列表。