构建

打包器选择和构建输出调优。

Note

本页所有示例都假设已在 nitro.config.ts 中导入以下内容:

import { defineConfig } from "nitro";

#builder

  • 类型:"rollup" | "rolldown" | "rspack" | "vite" | "bun" | false
  • 默认值:undefined(自动检测)

指定用于构建的打包器。

export default defineConfig({
  builder: "vite",
});

未设置时,如果你的 vite.config 使用了 nitro() 插件,Nitro 会使用 vite,否则使用 rolldown。构建器包会从项目中解析(rolldown 也可以通过 vite 解析),并在构建时按需安装(CI 除外,参见 deps.install)。开发模式下,如果未安装 rolldown 且未设置 rollupConfig 或 rolldownConfig,nitro dev 会在不使用构建器的情况下运行(builder: false),而 nitro build 会提示安装构建器。Nitro 在 Bun 上运行时(例如 bun --bun nitro build),如果项目中既未安装 rolldown 也未安装 vite,则会改用实验性的 bun 构建器,包括开发模式。

将 builder 设为 false(实验性功能)可在不打包的情况下运行服务器源文件。此时 nitro dev 会在 env-runner worker 中直接运行文件,Nitro 虚拟模块由内存提供,并在每次文件变更时启动新的 worker。nitro start(或 nitro serve)也会以生产模式直接运行源文件,不执行构建步骤,与配置的构建器无关。nitro preview 只提供构建产物。预渲染也会以相同方式运行源文件;未安装 rolldown 时,vite 构建器也会使用此方式。目前尚不支持 nitro build。

模块会像打包构建中一样按需转换:包括 TypeScript 和 JSX、import.meta.* 和 replace 值、alias、无扩展名导入、raw:/text/bytes 导入以及 WebAssembly。

Note

  • 在 Bun 上,尚不能解析不带文件扩展名的别名(例如 ~/utils)和 WebAssembly 导入。
  • 项目、其扫描目录和 Nitro 以外的文件(例如链接的工作区包)会按原样加载,不执行上述转换。
  • 打包器选项(rollupConfig、rolldownConfig)以及模块通过 build:config 钩子添加的插件均不适用。插件请使用 buildPlugins。

将 builder 设为 "rspack"(实验性功能),可使用 Rspack(@rspack/core v2.3 及更高版本,按需安装)打包服务器。Nitro 自带的构建插件和 buildPlugins 会在 Rspack 中运行,TypeScript 和 JSX 则由其内置的 SWC 加载器编译。其他选项请使用 rspackConfig。

Note

使用 rspack 时,会应用 rollupConfig 和 rolldownConfig(由预设使用)中的这些选项:plugins、external(在解析导入前调用)、output.entryFileNames 和 output.chunkFileNames(包含 [name] 和 [hash] 的字符串)、output.banner、output.footer、output.intro 和 output.outro(字符串或同步函数)、output.inlineDynamicImports: true、output.sourcemapExcludeSources 以及 output.sourcemapPathTransform。其他选项会被忽略,Nitro 会对此发出警告。

将 builder 设为 "bun"(实验性功能),可使用 Bun 打包器(Bun.build)打包服务器。必须在 Bun 上运行 Nitro(例如 bun --bun nitro build),否则 Nitro 会抛出错误。该构建器支持所有预设,而不仅限于 bun,并支持 nitro dev。

Note

  • Nitro 构建插件、buildPlugins 以及 rollupConfig 和 rolldownConfig 中的插件会在同一个 Bun 插件中运行。支持 buildStart、resolveId、load、transform、buildEnd、renderChunk、resolveFileUrl、generateBundle 和 writeBundle 钩子。JavaScript 和 TypeScript 以外的文件只有在 load 钩子加载它们,或钩子的 filter 通过 id 指定它们时,才会传给 transform 钩子。Bun 不提供输入 source map,因此 transform 和 renderChunk 钩子不会更新 source map。
  • rollupConfig 和 rolldownConfig 中只有 plugins、external、platform: "node" 以及 output 的 entryFileNames、chunkFileNames、format、inlineDynamicImports、banner 和 footer(字符串形式)会生效。其他选项请使用 bunConfig。
  • 分块由 Bun 命名(_chunks/[name]-[hash].mjs),库分块不会归组。
  • Bun 没有 neutral 目标:不兼容 Node.js 的预设会使用 browser 目标,该目标会优先解析包的 browser 导出条件和 browser 字段。
  • 打包后的 CommonJS 模块会将 __dirname 和 __filename 设为构建机器上的绝对路径。

#buildPlugins

  • 类型:NitroBuildPluginOption[]
  • 默认值:[]

应用于所有构建器(rollup、rolldown、rspack、vite、bun 和 false)的构建插件。会解析嵌套数组和 Promise,并跳过假值条目。

插件使用 Rollup 插件接口。建议为 resolveId、load 和 transform 钩子设置 filter:这些钩子受所有构建器支持。

enforce: "pre" 插件会排在 Nitro 自身插件之前,其他插件排在其后(enforce: "post" 最后)。钩子自身的 order 优先级更高:Nitro 的一些钩子(例如虚拟模块解析)会使用 order: "pre",需要在它们之前运行的钩子也应设置该值。

Note

  • 不同构建器在插件运行前后的处理有所不同。使用 rolldown 和 bun 时,transform 钩子接收尚未转换的 TypeScript 和 JSX(插件运行后才会编译);使用 rollup 时,仅 enforce: "pre" 插件会收到未转换的内容。使用 vite 时,Vite 会先执行自己的解析和转换。
  • 使用 vite 时,插件仅作为打包器插件应用于 nitro 环境;不支持 Vite 专属选项和钩子(例如 apply 或 configureServer)。Vite 插件请添加到 Vite 的 plugins 中。
  • 使用 rspack 时,插件会在 Rspack 内运行。Rspack 支持 resolveId、load 和 transform(接收尚未转换的 TypeScript 和 JSX)、buildStart、buildEnd、renderChunk、generateBundle、writeBundle 和 closeBundle,并会对其他钩子发出警告。插件上下文功能有限:this.emitFile 只能输出资源(带有 source);this.load 解析为 { id, code };this.getModuleInfo 只包含模块导入方和导入项的 id;buildStart 不接收输入选项;输出分块不包含导入、导出或 source map(map)信息。开发模式下,每次重新构建都会运行 buildStart 和 closeBundle。load 和 transform 仅处理 JavaScript、TypeScript 模块及虚拟模块。
  • builder: false 时,插件会在 env-runner 中运行。它只支持 resolveId、load 和 transform(插件上下文功能有限),并会对其他钩子发出警告。钩子只会接收 JavaScript 和 TypeScript 模块,除非其 filter 通过 id 或 moduleType 指定了其他文件;只有 filter 指定 node_modules 时,才会接收其中的文件。
export default defineConfig({
  buildPlugins: [
    {
      name: "my-virtual-module",
      resolveId: {
        filter: { id: /^virtual:my-module$/ },
        handler: (id) => `\0${id}`,
      },
      load: {
        filter: { id: /^\0virtual:my-module$/ },
        handler: () => `export default "Hello!"`,
      },
    },
  ],
});

Nitro 模块可以通过 nitro.options.buildPlugins.push(plugin) 添加插件。

#rollupConfig

额外的 Rollup 配置。

export default defineConfig({
  rollupConfig: {
    output: { manualChunks: { vendor: ["lodash-es"] } },
  },
});

#rolldownConfig

额外的 Rolldown 配置。

export default defineConfig({
  rolldownConfig: {
    output: { banner: "/* built with nitro */" },
  },
});

#rspackConfig

额外的 Rspack 配置(适用于实验性的 rspack 构建器),会与 Nitro 生成的配置合并。

export default defineConfig({
  builder: "rspack",
  rspackConfig: {
    optimization: { concatenateModules: false },
  },
});

#bunConfig

bun构建器的额外 Bun.build 选项。

export default defineConfig({
  builder: "bun",
  bunConfig: {
    naming: { chunk: "chunks/[name]-[hash].mjs" },
  },
});

#vite

vite 构建器和 nitro/vite 插件的选项。

  • path:要使用的 vite 包,可以是指向其目录或入口的路径或 file:// URL(与 deps.paths.vite 相同)。默认情况下,nitro/vite 插件会使用当前运行的 vite,vite 构建器则从项目根目录解析它。
  • assetsImport:启用 ?assets 导入,以收集入口中的 CSS 和 JS 资源(默认值:true)。
  • serverReload:仅服务器模块发生变化时重新加载开发服务器(以及浏览器,默认值:true)。
export default defineConfig({
  vite: {
    path: import.meta.resolve("vite"),
  },
});

#services

  • 类型:Record<string, { entry: string }>
  • 默认值:{}

导出 fetch 处理器的服务器入口。它们由 nitro/vite 或 nitro/rsbuild 插件在各自的环境中构建,并通过 nitro/services 中的 fetchService(name, input, init?) 调用。

项目目录或服务器目录中的 app/、src/ 或根目录如果存在 entry-server 文件,Nitro 会据此检测 ssr 服务;带有入口的服务器环境也会自动注册。未设置渲染器时,未匹配的路由会由 ssr 服务渲染。

export default defineConfig({
  services: { api: { entry: "./src/api-entry.ts" } },
});

#deps

Nitro 按需安装的可选依赖项(例如 vite、rolldown、rollup、unstorage、db0 或 unenv)的选项。

  • paths:按包名显式指定要使用的包。每个值可以是指向包目录或入口的路径或 file:// URL。相对路径以 rootDir 为基准解析。
  • install:是否允许安装缺失的包(默认值:true,CI 中为 false)。禁用后,构建会失败并提示添加缺失包的命令,因此只会使用已提交到项目中的依赖。在 CI 中也要按需安装时,请设为 true。加载配置文件本身所需的包(jiti、giget,以及不支持原生加载的运行时所需的 dotenv)只会在 CI 以外安装,与此选项无关。

默认情况下,这些包会从项目中解析,缺失时按需安装(CI 除外)。基于 Nitro 构建的框架可以在 deps.paths 中传入自己的包副本,以确保运行所依赖的版本。服务器包也会使用其中的 unstorage、db0 和 unenv。显式指定的包不会被安装;版本超出支持范围时,Nitro 会发出警告。如果 rootDir 位于 node_modules 中(例如框架使用自己的包目录),也不会安装任何包:框架必须在自身依赖中声明所用包,或通过 deps.paths 传入这些包。

export default defineConfig({
  deps: {
    paths: {
      unstorage: import.meta.resolve("unstorage"),
      db0: import.meta.resolve("db0"),
    },
  },
});

若要完全禁止安装这些包(包括本地环境),请禁用 install:

export default defineConfig({
  deps: { install: false },
});

deps.paths.vite 是 vite.path 的别名。

#entry

打包器入口。

export default defineConfig({
  entry: "./server/entry.ts", // custom entry file
});

#alias

模块解析的路径别名。

export default defineConfig({
  alias: {
    "~utils": "./src/utils",
    "#shared": "./shared",
  },
});

使用 Vite 构建器时,这些别名会应用于每个 Vite 环境。如果 Vite 的 resolve.alias(来自 Vite 配置或其他插件,且 find 为字符串)将同一个键映射到其他目标,Nitro 目标只应用于 nitro 环境,其他环境(例如 client 和 ssr)则使用 Vite 目标。

#inject

在包中引用全局变量时,将其替换为对应导入。值可以是模块 id(默认导出),也可以是 [id, exportName] 元组。

将全局变量设为 false 可移除默认注入(例如为 node: false 构建添加的注入)。

export default defineConfig({
  inject: {
    Buffer: ["node:buffer", "Buffer"],
    performance: false,
  },
});

#polyfills

在服务器入口之前为执行副作用而导入的模块。在条目前加上 ! 可移除默认 polyfill。

node: false 构建默认会添加 #nitro/runtime/polyfills/global、#nitro/runtime/polyfills/process、#nitro/runtime/polyfills/buffer 和 #nitro/runtime/polyfills/timers(例如 "!#nitro/runtime/polyfills/timers" 会移除 setImmediate polyfill)。

export default defineConfig({
  polyfills: ["./polyfills/intl.ts"],
});

#builtinModules

由目标运行时提供的模块,例如 cloudflare:workers 或 Deno 上的 node:fs。这些 id 的导入会在输出中保持原样。

内置模块不会被打包、追踪或复制到输出中,因此这里只应列出运行时本身提供的模块。若要让 npm 包不进入构建包,请改用 traceDeps。node 为 true 时,Node.js 内置模块会自动处理。

在条目前加上 ! 可移除默认项(例如由预设添加的项目)。

export default defineConfig({
  builtinModules: ["cloudflare:workers"],
});

Note

预设也会添加默认的 alias、inject、polyfills 和 builtinModules 条目(例如,Cloudflare 和 Deno 会映射其原生支持的 Node.js 内置模块)。这些选项中你自行设置的值始终优先。

unenv 选项已弃用。通过它传入的预设仍会生效,顺序在预设默认值之后、你自己的选项之前。

#minify

  • 默认值:false

压缩构建包。

部分预设(尤其是 Worker 运行时)默认启用压缩。调试生产、Worker 或边缘构建时,请设置 minify: false,以便堆栈跟踪保持可读。

export default defineConfig({
  minify: true, // minify production bundle
});
export default defineConfig({
  minify: false, // easier to debug workers / edge bundles
});

#inlineDynamicImports

  • 默认值:false

将所有代码打包到单个文件中,而不是为每个路由创建单独的分块。

设为 false 时,每个路由处理器会成为单独的分块并按需加载;设为 true 时,所有内容会打包在一起。部分预设默认启用此选项。

export default defineConfig({
  inlineDynamicImports: true, // single output file
});

#sourcemap

  • 默认值:false

启用 source map 生成。参见选项说明。

export default defineConfig({
  sourcemap: true, // generate .map files
});

#node

  • 默认值:true

指定构建是否用于 Node.js。设为 false 时,Nitro 会添加默认的 alias、inject 和 polyfills 条目,以 polyfill Node.js 全局变量和内置模块(使用 unenv),并相应调整自身行为。

目标运行时未提供的 Node.js 内置模块(例如 Cloudflare 上的 node:inspector)会使用 unenv 进行 polyfill。只有构建导入了此类模块时,才会从项目中解析 unenv,并在需要时按需安装(CI 除外,参见 deps.install)。

export default defineConfig({
  node: false, // target non-Node.js runtimes
});

#replace

构建时字符串替换。

export default defineConfig({
  replace: {
    "process.env.APP_VERSION": JSON.stringify("1.0.0"),
  },
});

#commonJS

指定 Rollup CommonJS 插件的其他配置。

export default defineConfig({
  commonJS: {
    requireReturnsDefault: "auto",
  },
});

#exportConditions

模块解析的自定义导出条件。

export default defineConfig({
  exportConditions: ["worker", "production"],
});

#noExternals

  • 默认值:false

阻止将包标记为外部依赖。外部依赖会在运行时导入,而不是打包进产物,因此无法使用你的 alias 配置。

生产构建中,Nitro 已经会打包几乎所有内容:只有原生包、其他无法打包的包,以及列在 traceDeps 中的包会保留为外部依赖。开发模式下,为了提高速度,node_modules 中的依赖会保持为外部依赖,此时该选项最有用。

设为 true 可打包所有内容,包括通常会保留为外部依赖的包:

export default defineConfig({
  noExternals: true, // bundle all dependencies
});

#内联特定包

传入数组可仅内联部分模块。RegExp 条目按原样使用;字符串条目会经过转义,并作为路径子字符串进行匹配。

每个模式都会与导入说明符(例如 @scope/my-lib)以及解析后的绝对文件路径(例如 /…/node_modules/@scope/my-lib/dist/index.mjs)进行匹配。任意一项匹配时,模块都会保留在构建包中,因此通常只需填写包名:

export default defineConfig({
  alias: {
    "@shared": "./shared",
  },
  noExternals: ["@scope/my-lib"],
});

需要更精确的匹配时,请使用路径模式。例如,在 monorepo 中内联一个包而不匹配名称相似的包:

export default defineConfig({
  noExternals: [/packages[\\/]my-lib/],
});

此类模式中请使用 [\\/] 代替 /,以便同时匹配 Windows 路径。

Note

在 Nitro 2 中,此选项名为 externals.inline。

#traceDeps

  • 默认值:[]

要追踪并包含在构建输出中的额外依赖项。

支持以下特殊前缀:

  • !pkg:从追踪中排除内置包。
  • pkg*:完整追踪,复制包中的所有文件,而不只是已追踪的文件。
export default defineConfig({
  traceDeps: [
    "sharp",
    "better-sqlite3",
    "my-pkg*", // full trace (copy all package files)
    "!unwanted-pkg", // exclude from tracing
  ],
});

#traceOpts

传递给 nf3 以进行依赖追踪的高级选项。

export default defineConfig({
  traceOpts: {
    // Options passed to @vercel/nft for file tracing
    nft: { /* ... */ },
    // Alias for module paths when tracing
    traceAlias: { "old-pkg": "new-pkg" },
    // Preserve or set file permissions when copying (true or octal like 0o755)
    chmod: true,
    // Transform traced files before copying
    transform: [
      { filter: (id) => id.endsWith(".js"), handler: (code) => code },
    ],
    // Hook into tracing lifecycle
    hooks: {
      tracedPackages(pkgs) {
        console.log("Traced packages:", Object.keys(pkgs));
      },
    },
  },
});

#oxc

rollup 构建器的 OXC 选项,包括 minify 和 transform 子选项。

minify 使用 rolldown 的压缩器。如果未安装 rolldown,则会发出警告并跳过压缩。

export default defineConfig({
  oxc: {
    minify: { compress: true, mangle: true },
  },
});