Next.js编译器

Next.js 编译器(使用 SWC 用 Rust 编写)使 Next.js 能够在生产环境中转换和压缩 JavaScript 代码。这取代了 Babel 处理单个文件和 Terser 处理输出包的功能。

使用 Next.js 编译器的编译速度比 Babel 快 17 倍,自 Next.js 版本 12 起默认启用。如果您有现有的 Babel 配置或使用了 不支持的特性,您的应用将自动退出 Next.js 编译器并继续使用 Babel。

为什么选择 SWC?

SWC 是一个基于 Rust 的可扩展平台,旨在支持下一代快速开发工具。

SWC 可用于编译、压缩、打包等功能,并且设计上可进行扩展。您可以调用它来执行代码转换(无论是内置的还是自定义的)。这些转换的运行通过更高层次的工具(如 Next.js)来实现。

我们选择基于 SWC 的原因有几个:

  • 扩展性: SWC 可以作为 Crate 内部使用,无需对库进行分叉或解决设计限制。
  • 性能: 通过切换到 SWC,我们在 Next.js 中实现了约 3 倍的 Fast Refresh 提升和约 5 倍的构建速度提升,且仍有进一步优化的空间。
  • WebAssembly: Rust 对 WASM 的支持对于支持所有可能的平台和将 Next.js 开发带到任何地方至关重要。
  • 社区: Rust 社区和生态系统非常出色,并且仍在不断发展。

支持的特性

Styled Components

我们正在将 babel-plugin-styled-components 移植到 Next.js 编译器中。

首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新您的 next.config.js 文件:

// next.config.js module.exports = { compiler: { styledComponents: true, }, }

对于高级用例,您可以为 styled-components 编译配置单独的属性。

注意:ssrdisplayName 转换是使用 styled-components 在 Next.js 中的主要要求。

// next.config.js module.exports = { compiler: { // 有关选项的更多信息,请参见 example.com styledComponents: { // 默认在开发环境中启用,生产环境中禁用以减少文件大小, // 设置此项将覆盖所有环境的默认值。 displayName?: boolean, // 默认启用。 ssr?: boolean, // 默认启用。 fileName?: boolean, // 默认启用。 topLevelImportPaths?: string[], // 默认值为 ["index"]。 meaninglessFileNames?: string[], // 默认启用。 minify?: boolean, // 默认启用。 transpileTemplateLiterals?: boolean, // 默认启用。 namespace?: string, // 默认禁用。 pure?: boolean, // 默认启用。 cssProp?: boolean, }, }, }

Jest

Next.js 编译器会转译您的测试,并简化 Jest 与 Next.js 的配置,包括:

  • 自动模拟 .css.module.css(及其 .scss 变体)和图像导入
  • 自动设置使用 SWC 的 transform
  • .env(及所有变体)加载到 process.env
  • 忽略测试解析和转换中的 node_modules
  • 忽略测试解析中的 .next
  • 加载 next.config.js 以启用实验性的 SWC 转换标志

首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新您的 jest.config.js 文件:

// jest.config.js const nextJest = require('next/jest'); // 提供 Next.js 应用的路径,这将启用加载 next.config.js 和 .env 文件 const createJestConfig = nextJest({ dir: './' }); // 任何自定义配置 const customJestConfig = { setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], }; // createJestConfig 以这种方式导出,以确保 next/jest 可以加载 Next.js 配置,这是异步的 module.exports = createJestConfig(customJestConfig);

Relay

要启用 Relay 支持:

// next.config.js module.exports = { compiler: { relay: { // 这应与 relay.config.js 匹配 src: './', artifactDirectory: './__generated__', language: 'typescript', eagerEsModules: false, }, }, }

值得注意 : 在 Next.js 中,pages 目录中的所有 JavaScript 文件都被视为路由。因此,对于 relay-compiler,您需要将 artifactDirectory 配置设置在 pages 外部,否则 relay-compiler 将在 __generated__ 目录中生成文件,这些文件会被视为路由,可能会破坏生产构建。

移除 React 属性

允许移除 JSX 属性。这通常用于测试。类似于 babel-plugin-react-remove-properties

要移除匹配默认正则表达式 ^data-test 的属性:

// next.config.js module.exports = { compiler: { reactRemoveProperties: true, }, }

要移除自定义属性:

// next.config.js module.exports = { compiler: { // 这里定义的正则表达式在 Rust 中处理,因此语法与 JavaScript `RegExp` 不同。请参见 example.com。 reactRemoveProperties: { properties: ['^data-custom$'] }, }, }

移除 Console

此转换允许移除应用代码中的所有 console.* 调用(不包括 node_modules)。类似于 babel-plugin-transform-remove-console

移除所有 console.* 调用:

// next.config.js module.exports = { compiler: { removeConsole: true, }, }

移除 console.* 输出,但保留 console.error

// next.config.js module.exports = { compiler: { removeConsole: { exclude: ['error'], }, }, }

遗留装饰器

Next.js 将自动检测 jsconfig.jsontsconfig.json 中的 experimentalDecorators。遗留装饰器通常与旧版本的库(如 mobx)一起使用。

此标志仅用于与现有应用程序的兼容性。我们不推荐在新应用程序中使用遗留装饰器。

首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新您的 jsconfig.jsontsconfig.json 文件:

{ "compilerOptions": { "experimentalDecorators": true } }

importSource

Next.js 将自动检测 jsconfig.jsontsconfig.json 中的 jsxImportSource 并应用它。这通常用于像 Theme UI 这样的库。

首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新您的 jsconfig.jsontsconfig.json 文件:

{ "compilerOptions": { "jsxImportSource": "theme-ui" } }

Emotion

我们正在将 @emotion/babel-plugin 移植到 Next.js 编译器中。

首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新您的 next.config.js 文件:

// next.config.js module.exports = { compiler: { emotion: boolean | { // 默认值为 true。生产环境构建时将禁用。 sourceMap?: boolean, // 默认值为 'dev-only'。 autoLabel?: 'never' | 'dev-only' | 'always', // 默认值为 '[local]'。 labelFormat?: string, // 默认值为 undefined。 importMap?: { [packageName: string]: { [exportName: string]: { canonicalImport?: [string, string], styledBaseImport?: [string, string], } } }, }, }, }

压缩

自 v13 起,Next.js 的 swc 编译器默认用于压缩,比 Terser 快 7 倍。

如果由于某些原因仍需要使用 Terser,可以进行如下配置。

// next.config.js module.exports = { swcMinify: false, }

模块转译

Next.js 可以自动转译和打包本地包(如 monorepos)或来自外部依赖(node_modules)的依赖。这取代了 next-transpile-modules 包。

// next.config.js module.exports = { transpilePackages: ['@acme/ui', 'lodash-es'], }

模块化导入

此选项已被 optimizePackageImports 取代,我们建议升级到使用新选项,不再需要手动配置导入路径。

实验性功能

SWC 跟踪分析

您可以生成 SWC 内部转换的跟踪数据,格式为 Chromium 的 跟踪事件格式。

// next.config.js module.exports = { experimental: { swcTraceProfiling: true, }, }

启用后,swc 将在 .next/ 目录下生成名为 swc-trace-profile-${timestamp}.json 的跟踪文件。Chromium 的跟踪查看器(chrome://tracing/,example.com)或兼容的火焰图查看器(example.com)可以加载并可视化生成的跟踪数据。

SWC 插件(实验性)

您可以配置 SWC 的转换使用 SWC 的实验性插件支持(使用 wasm 编写)来自定义转换行为。

// next.config.js module.exports = { experimental: { swcPlugins: [ ['plugin', {...pluginOptions}], ], }, }

swcPlugins 接受一个包含插件配置的元组数组。插件的元组包含插件的路径和一个用于插件配置的对象。插件的路径可以是 npm 模块包名或 .wasm 二进制文件的绝对路径。

不支持的特性

当您的应用具有 .babelrc 文件时,Next.js 会自动回退使用 Babel 进行单个文件的转换。这确保了与现有应用程序的向后兼容性,这些应用程序利用了自定义 Babel 插件。

如果您使用自定义 Babel 设置,请分享您的配置。我们正在努力将尽可能多的常用 Babel 转换移植过来,并支持插件。

版本历史

版本变化
v13.1.0模块转译 和 模块化导入 稳定。
v13.0.0默认启用 SWC 压缩器。
v12.3.0SWC 压缩器 稳定。
v12.2.0添加了对 SWC 插件 的实验性支持。
v12.1.0添加了对 Styled Components、Jest、Relay、移除 React 属性、遗留装饰器、移除 Console 和 jsxImportSource 的支持。
v12.0.0引入了 Next.js 编译器 首次发布。

如果有任何其他翻译需求或问题,随时告诉我!