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 在 Next.js 内部使用,而无需分叉库或规避设计限制。
- 性能: 通过切换到 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 文件
module.exports = {
compiler: {
styledComponents: true,
},
}对于高级用例,你可以为 styled-components 编译配置单独的属性。
注意:
ssr和displayName转换是 Next.js 中使用styled-components的主要要求。
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 文件
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 支持
module.exports = {
compiler: {
relay: {
// This should match 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: {
// 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)中的所有 console.* 调用。类似于 babel-plugin-transform-remove-console。
移除所有 console.* 调用
module.exports = {
compiler: {
removeConsole: true,
},
}移除 console.* 输出,但保留 console.error
module.exports = {
compiler: {
removeConsole: {
exclude: ['error'],
},
},
}传统装饰器
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 编译器。
首先,更新到最新版本的 Next.js:npm install next@latest。然后,更新你的 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 倍。
温馨提示: 从 v15 开始,不能使用
next.config.js自定义代码压缩。已移除对swcMinify标志的支持。
模块转译
Next.js 可以自动转译和打包本地包(如 Monorepo)或外部依赖项(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 编译器支持生命周期钩子,允许你在构建过程中的特定点运行自定义代码。目前,支持以下钩子
runAfterProductionCompile
一个钩子函数,在生产构建编译完成后但在运行类型检查和静态页面生成等编译后任务之前执行。此钩子提供对项目元数据(包括项目目录和构建输出目录)的访问,使其适用于第三方工具收集构建输出(如源映射)。
module.exports = {
compiler: {
runAfterProductionCompile: async ({ distDir, projectDir }) => {
// Your custom code here
},
},
}此钩子接收一个具有以下属性的对象
distDir:构建输出目录(默认为.next)projectDir:项目的根目录
实验性功能
SWC 跟踪分析
你可以将 SWC 的内部转换跟踪生成为 Chromium 的 trace 事件格式。
module.exports = {
experimental: {
swcTraceProfiling: true,
},
}启用后,swc 将在 .next/ 下生成名为 swc-trace-profile-${timestamp}.json 的跟踪文件。Chromium 的 trace viewer (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 转换,并在未来支持插件。
版本历史
这有帮助吗?