Next.js Compiler
Next.js Compiler 使用 SWC 用 Rust 编写,允许 Next.js 转换和压缩你的 JavaScript 代码以用于生产。这取代了用于单个文件的 Babel 和用于压缩输出包的 Terser。
使用 Next.js Compiler 的编译比 Babel 快 17 倍,并且自 Next.js 版本 12 以来默认启用。如果你有现有的 Babel 配置或使用不支持的功能,你的应用程序将选择退出 Next.js Compiler 并继续使用 Babel。
为什么选择 SWC?
SWC 是一个可扩展的基于 Rust 的平台,用于下一代快速开发工具。
SWC 可用于编译、压缩、打包等,并且设计为可扩展。你可以调用它来执行代码转换(内置或自定义)。这些转换通过像 Next.js 这样的高级工具进行。
我们选择在 SWC 上构建有几个原因:
- 可扩展性: SWC 可以在 Next.js 内部作为 Crate 使用,无需分叉库或绕过设计约束。
- 性能: 通过切换到 SWC,我们能够在 Next.js 中实现约 3 倍更快的 Fast Refresh 和约 5 倍更快的构建,还有更多优化空间仍在进行中。
- WebAssembly: Rust 对 WASM 的支持对于支持所有可能的平台和将 Next.js 开发带到任何地方至关重要。
- 社区: Rust 社区和生态系统令人惊叹且仍在增长。
支持的功能
Styled Components
我们正在努力将 babel-plugin-styled-components
移植到 Next.js Compiler。
首先,更新到最新版本的 Next.js:npm install next@latest
。然后,更新你的 next.config.js
文件:
module.exports = {
compiler: {
styledComponents: true,
},
}
对于高级用例,你可以为 styled-components 编译配置各个属性。
注意:
ssr
和displayName
转换是在 Next.js 中使用styled-components
的主要要求。
module.exports = {
compiler: {
// 有关选项的更多信息,请参阅 https://styled-components.com/docs/tooling#babel-plugin
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 Compiler 转译你的测试并简化与 Next.js 一起配置 Jest,包括:
- 自动模拟
.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
文件:
const nextJest = require('next/jest')
// 提供 Next.js 应用程序的路径,这将启用加载 next.config.js 和 .env 文件
const createJestConfig = nextJest({ dir: './' })
// 你想要传递给 Jest 的任何自定义配置
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}
// createJestConfig 以这种方式导出,以确保 next/jest 可以加载 Next.js 配置,这是异步的
module.exports = createJestConfig(customJestConfig)
Relay
要启用 Relay 支持:
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
的属性:
module.exports = {
compiler: {
reactRemoveProperties: true,
},
}
要移除自定义属性:
module.exports = {
compiler: {
// 这里定义的正则表达式在 Rust 中处理,所以语法与
// JavaScript `RegExp` 不同。请参阅 https://docs.rs/regex。
reactRemoveProperties: { properties: ['^data-custom$'] },
},
}
移除 Console
此转换允许移除应用程序代码中的所有 console.*
调用(不是 node_modules
)。类似于 babel-plugin-transform-remove-console
。
移除所有 console.*
调用:
module.exports = {
compiler: {
removeConsole: true,
},
}
移除 console.*
输出,除了 console.error
:
module.exports = {
compiler: {
removeConsole: {
exclude: ['error'],
},
},
}
遗留装饰器(Legacy Decorators)
Next.js 将自动检测 jsconfig.json
或 tsconfig.json
中的 experimentalDecorators
。遗留装饰器通常与较旧版本的库(如 mobx
)一起使用。
此标志仅支持与现有应用程序的兼容性。我们不建议在新应用程序中使用遗留装饰器。
首先,更新到最新版本的 Next.js:npm install next@latest
。然后,更新你的 jsconfig.json
或 tsconfig.json
文件:
{
"compilerOptions": {
"experimentalDecorators": true
}
}
importSource
Next.js 将自动检测 jsconfig.json
或 tsconfig.json
中的 jsxImportSource
并应用它。这通常与 Theme UI 等库一起使用。
首先,更新到最新版本的 Next.js:npm install next@latest
。然后,更新你的 jsconfig.json
或 tsconfig.json
文件:
{
"compilerOptions": {
"jsxImportSource": "theme-ui"
}
}
Emotion
我们正在努力将 @emotion/babel-plugin
移植到 Next.js Compiler。
首先,更新到最新版本的 Next.js:npm install next@latest
。然后,更新你的 next.config.js
文件:
module.exports = {
compiler: {
emotion: boolean | {
// 默认为 true。当构建类型为生产时,它将被禁用。
sourceMap?: boolean,
// 默认为 'dev-only'。
autoLabel?: 'never' | 'dev-only' | 'always',
// 默认为 '[local]'。
// 允许的值:`[local]` `[filename]` 和 `[dirname]`
// 此选项仅在 autoLabel 设置为 'dev-only' 或 'always' 时有效。
// 它允许你定义结果标签的格式。
// 格式通过字符串定义,其中变量部分用方括号 [] 括起来。
// 例如 labelFormat: "my-classname--[local]",其中 [local] 将被替换为结果分配给的变量名。
labelFormat?: string,
// 默认为 undefined。
// 此选项允许你告诉编译器它应该查看哪些导入
// 来确定它应该转换什么,所以如果你重新导出
// Emotion 的导出,你仍然可以使用转换。
importMap?: {
[packageName: string]: {
[exportName: string]: {
canonicalImport?: [string, string],
styledBaseImport?: [string, string],
}
}
},
},
},
}
压缩
Next.js 的 swc 编译器自 v13 以来默认用于压缩。这比 Terser 快 7 倍。
提示:从 v15 开始,无法使用
next.config.js
自定义压缩。对swcMinify
标志的支持已被移除。
模块转译
Next.js 可以自动转译和打包来自本地包(如 monorepos)或外部依赖项(node_modules
)的依赖项。这取代了 next-transpile-modules
包。
module.exports = {
transpilePackages: ['@acme/ui', 'lodash-es'],
}
模块化导入
此选项已被 Next.js 13.5 中的 optimizePackageImports
取代。我们建议升级使用不需要手动配置导入路径的新选项。
Define(在构建期间替换变量)
define
选项允许你在构建时静态替换代码中的变量。
该选项接受一个对象作为键值对,其中键是应该用相应值替换的变量。
在 next.config.js
中使用 compiler.define
字段为所有环境(服务器、边缘和客户端)定义变量。或者,使用 compiler.defineServer
仅为服务器端(服务器和边缘)代码定义变量:
module.exports = {
compiler: {
define: {
MY_VARIABLE: 'my-string',
'process.env.MY_ENV_VAR': 'my-env-var',
},
defineServer: {
MY_SERVER_VARIABLE: 'my-server-var',
},
},
}
构建生命周期钩子
Next.js Compiler 支持生命周期钩子,允许你在构建过程的特定点运行自定义代码。目前支持以下钩子:
runAfterProductionCompile
一个钩子函数,在生产构建编译完成后但在运行编译后任务(如类型检查和静态页面生成)之前执行。此钩子提供对项目元数据的访问,包括项目目录和构建输出目录,使第三方工具可以收集构建输出(如源映射)很有用。
module.exports = {
compiler: {
runAfterProductionCompile: async ({ distDir, projectDir }) => {
// 你的自定义代码在这里
},
},
}
钩子接收一个具有以下属性的对象:
distDir
:构建输出目录(默认为.next
)projectDir
:项目的根目录
实验性功能
SWC 跟踪分析
你可以生成 SWC 的内部转换跟踪作为 chromium 的跟踪事件格式。
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 的转换以使用 SWC 的用 wasm 编写的实验性插件支持来自定义转换行为。
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.0 | SWC 压缩器稳定。 |
v12.2.0 | 添加了SWC 插件实验性支持。 |
v12.1.0 | 添加了对 Styled Components、Jest、Relay、移除 React 属性、遗留装饰器、移除 Console 和 jsxImportSource 的支持。 |
v12.0.0 | Next.js Compiler 引入。 |