跳至内容
简介架构Next.js 编译器

Next.js 编译器

Next.js 编译器使用 SWC(用 Rust 编写的)来转换和压缩您的 JavaScript 代码以用于生产环境。这取代了 Babel 对单个文件的使用,以及 Terser 对输出包的压缩。

使用 Next.js 编译器的编译速度比 Babel 快 17 倍,并且从 Next.js 版本 12 开始默认启用。如果您有现有的 Babel 配置或正在使用不受支持的功能,您的应用程序将选择退出 Next.js 编译器,并继续使用 Babel。

为什么选择 SWC?

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

SWC 可用于编译、压缩、捆绑等,并且设计为可扩展的。您可以调用它来执行代码转换(内置或自定义)。这些转换的执行是通过 Next.js 等更高级别的工具进行的。

我们选择基于 SWC 构建的原因有以下几点

  • **可扩展性:**SWC 可以作为 Next.js 中的 Crate 使用,无需分叉库或变通设计约束。
  • **性能:**通过切换到 SWC,我们能够在 Next.js 中实现约 3 倍的快速刷新速度和约 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 转换是 Next.js 中使用 styled-components 的主要要求。

next.config.js
module.exports = {
  compiler: {
    // see https://styled-components.npmjs.net.cn/docs/tooling#babel-plugin for more info on the options.
    styledComponents: {
      // Enabled by default in development, disabled in production to reduce file size,
      // setting this will override the default for all environments.
      displayName?: boolean,
      // Enabled by default.
      ssr?: boolean,
      // Enabled by default.
      fileName?: boolean,
      // Empty by default.
      topLevelImportPaths?: string[],
      // Defaults to ["index"].
      meaninglessFileNames?: string[],
      // Enabled by default.
      minify?: boolean,
      // Enabled by default.
      transpileTemplateLiterals?: boolean,
      // Empty by default.
      namespace?: string,
      // Disabled by default.
      pure?: boolean,
      // Enabled by default.
      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')
 
// Providing the path to your Next.js app which will enable loading next.config.js and .env files
const createJestConfig = nextJest({ dir: './' })
 
// Any custom config you want to pass to Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
 
// createJestConfig is exported in this way to ensure that next/jest can load the Next.js configuration, which is async
module.exports = createJestConfig(customJestConfig)

Relay

启用 Relay 支持

next.config.js
module.exports = {
  compiler: {
    relay: {
      // This should match relay.config.js
      src: './',
      artifactDirectory: './__generated__',
      language: 'typescript',
      eagerEsModules: false,
    },
  },
}

注意:在 Next.js 中,pages 目录下的所有 JavaScript 文件都被视为路由。因此,对于 relay-compiler,您需要在 pages 目录之外指定 artifactDirectory 配置设置,否则 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: {
    // The regexes defined here are processed in Rust so the syntax is different from
    // JavaScript `RegExp`s. See https://docs.rs/regex.
    reactRemoveProperties: { properties: ['^data-custom$'] },
  },
}

移除控制台

此转换允许移除应用程序代码中的所有 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 | {
      // default is true. It will be disabled when build type is production.
      sourceMap?: boolean,
      // default is 'dev-only'.
      autoLabel?: 'never' | 'dev-only' | 'always',
      // default is '[local]'.
      // Allowed values: `[local]` `[filename]` and `[dirname]`
      // This option only works when autoLabel is set to 'dev-only' or 'always'.
      // It allows you to define the format of the resulting label.
      // The format is defined via string where variable parts are enclosed in square brackets [].
      // For example labelFormat: "my-classname--[local]", where [local] will be replaced with the name of the variable the result is assigned to.
      labelFormat?: string,
      // default is undefined.
      // This option allows you to tell the compiler what imports it should
      // look at to determine what it should transform so if you re-export
      // Emotion's exports, you can still use transforms.
      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'],
}

模块化导入

此选项已被 Next.js 13.5 中的 optimizePackageImports 取代。我们建议升级以使用不需要手动配置导入路径的新选项。

实验性功能

SWC 跟踪分析

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

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

启用后,swc 将在 .next/ 下生成名为 swc-trace-profile-${timestamp}.json 的跟踪文件。Chromium 的跟踪查看器(chrome://tracing/,https://ui.perfetto.dev/) 或兼容的火焰图查看器(https://www.speedscope.app/) 可以加载并可视化生成的跟踪。

SWC 插件(实验性)

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

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 Minifier。
v12.3.0SWC Minifier 稳定
v12.2.0SWC 插件 添加了实验性支持。
v12.1.0添加了对 Styled Components、Jest、Relay、Remove React Properties、Legacy Decorators、Remove Console 和 jsxImportSource 的支持。
v12.0.0Next.js 编译器 引入