Turbopack
Turbopack 是一个增量打包器,针对 JavaScript 和 TypeScript 进行了优化,使用 Rust 编写,并内置于 Next.js 中。你可以在 Pages 和 App Router 中使用 Turbopack,以获得更快的本地开发体验。
为什么选择 Turbopack?
我们构建 Turbopack 是为了提升 Next.js 的性能,包括:
- 统一图谱: Next.js 支持多种输出环境(例如,客户端和服务器)。管理多个编译器并将包拼接在一起可能很繁琐。Turbopack 为所有环境使用单一的统一图谱。
- 打包 vs 原生 ESM: 一些工具在开发中跳过打包,依赖浏览器的原生 ESM。这对小型应用效果很好,但由于过多的网络请求,可能会拖慢大型应用。Turbopack 在开发中打包,但以优化的方式保持大型应用的速度。
- 增量计算: Turbopack 在多个核心上并行工作,并将结果缓存到函数级别。一旦完成一项工作,Turbopack 不会重复执行。
- 懒加载打包: Turbopack 只打包开发服务器实际请求的内容。这种懒加载方式可以减少初始编译时间和内存使用。
开始使用
Turbopack 现在是 Next.js 中的默认打包器。使用 Turbopack 无需任何配置:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}使用 Webpack
如果你需要使用 Webpack 而不是 Turbopack,可以使用 --webpack 标志选择加入:
{
"scripts": {
"dev": "next dev --webpack",
"build": "next build --webpack",
"start": "next start"
}
}支持的特性
Next.js 中的 Turbopack 对于常见用例具有零配置。以下是开箱即用支持的功能摘要,以及在需要时如何进一步配置 Turbopack 的一些参考。
语言特性
| 特性 | 状态 | 说明 |
|---|---|---|
| JavaScript & TypeScript | 支持 | 底层使用 SWC。Turbopack 不进行类型检查(运行 tsc --watch 或依赖你的 IDE 进行类型检查)。 |
| ECMAScript (ESNext) | 支持 | Turbopack 支持最新的 ECMAScript 特性,与 SWC 的覆盖范围一致。 |
| CommonJS | 支持 | 开箱即用地处理 require() 语法。 |
| ESM | 支持 | 完全支持静态和动态 import。 |
| Babel | 支持 | 从 Next.js 16 开始,如果检测到配置文件,Turbopack 会自动使用 Babel。与 webpack 不同,SWC 始终用于 Next.js 的内部转换和降级到较旧的 ECMAScript 版本。如果存在 Babel 配置文件,使用 webpack 的 Next.js 会禁用 SWC。node_modules 中的文件被排除在外,除非你手动配置 babel-loader。 |
框架和 React 特性
| 特性 | 状态 | 说明 |
|---|---|---|
| JSX / TSX | 支持 | SWC 处理 JSX/TSX 编译。 |
| Fast Refresh | 支持 | 无需配置。 |
| React Server Components (RSC) | 支持 | 用于 Next.js App Router。Turbopack 确保正确的服务器/客户端打包。 |
| Root layout creation | 不支持 | 不支持在 App Router 中自动创建根布局。Turbopack 会指示你手动创建它。 |
CSS 和样式
| 特性 | 状态 | 说明 |
|---|---|---|
| Global CSS | 支持 | 直接在应用程序中导入 .css 文件。 |
| CSS Modules | 支持 | .module.css 文件原生工作(Lightning CSS)。 |
| CSS Nesting | 支持 | Lightning CSS 支持现代 CSS 嵌套。 |
| @import syntax | 支持 | 组合多个 CSS 文件。 |
| PostCSS | 支持 | 在 Node.js 工作池中自动处理 postcss.config.js。对 Tailwind、Autoprefixer 等很有用。 |
| Sass / SCSS | 支持(Next.js) | 对于 Next.js,开箱即用地支持 Sass。不支持自定义 Sass 函数(sassOptions.functions),因为 Turbopack 基于 Rust 的架构无法直接执行 JavaScript 函数,这与 webpack 的 Node.js 环境不同。如果需要此功能,请使用 webpack。未来,Turbopack 独立使用可能需要加载器配置。 |
| Less | 通过插件计划 | 默认情况下尚不支持。一旦自定义加载器稳定,可能需要加载器配置。 |
| Lightning CSS | 使用中 | 处理 CSS 转换。一些低使用率的 CSS Modules 特性(如作为独立伪类的 :local/:global)尚不支持。详见下文。 |
资源
| 特性 | 状态 | 说明 |
|---|---|---|
| Static Assets(图片、字体) | 支持 | 导入 import img from './img.png' 开箱即用。在 Next.js 中,为 <Image /> 组件返回一个对象。 |
| JSON Imports | 支持 | 支持从 .json 进行命名或默认导入。 |
模块解析
| 特性 | 状态 | 说明 |
|---|---|---|
| Path Aliases | 支持 | 读取 tsconfig.json 的 paths 和 baseUrl,与 Next.js 行为一致。 |
| Manual Aliases | 支持 | 在 next.config.js 中配置 resolveAlias(类似于 webpack.resolve.alias)。 |
| Custom Extensions | 支持 | 在 next.config.js 中配置 resolveExtensions。 |
| AMD | 部分支持 | 基本转换有效;高级 AMD 使用受限。 |
性能和 Fast Refresh
| 特性 | 状态 | 说明 |
|---|---|---|
| Fast Refresh | 支持 | 无需完全刷新即可更新 JavaScript、TypeScript 和 CSS。 |
| Incremental Bundling | 支持 | Turbopack 懒加载地仅构建开发服务器请求的内容,加快大型应用的速度。 |
与 webpack 的已知差异
webpack 和 Turbopack 之间存在许多非平凡的行为差异,在迁移应用程序时了解这些差异很重要。通常,这些对新应用程序来说不太重要。
CSS Module 排序
Turbopack 将遵循 JS 导入顺序来排序CSS modules,这些模块没有其他排序方式。例如:
import utilStyles from './utils.module.css'
import buttonStyles from './button.module.css'
export default function BlogPost() {
return (
<div className={utilStyles.container}>
<button className={buttonStyles.primary}>Click me</button>
</div>
)
}在这个例子中,Turbopack 将确保 utils.module.css 在生成的 CSS 块中出现在 button.module.css 之前,遵循导入顺序。
Webpack 通常也这样做,但在某些情况下它会忽略 JS 推断的排序,例如,如果它推断 JS 文件没有副作用。
如果应用程序已经依赖于任意排序,这可能会在采用 Turbopack 时导致细微的渲染变化。通常,解决方案很简单,例如,让 button.module.css @import utils.module.css 来强制排序,或识别冲突的规则并更改它们以不针对相同的属性。
Sass node_modules 导入
Turbopack 开箱即用地支持导入 node_modules Sass 文件。Webpack 支持传统的波浪号 ~ 语法,Turbopack 不支持此语法。
从:
@import '~bootstrap/dist/css/bootstrap.min.css';改为:
@import 'bootstrap/dist/css/bootstrap.min.css';如果你无法更新导入,可以添加 turbopack.resolveAlias 配置来将 ~ 语法映射到实际路径:
module.exports = {
turbopack: {
resolveAlias: {
'~*': '*',
},
},
}包大小
根据我们在生产应用程序上的测试,我们观察到 Turbopack 通常生成的包大小与 Webpack 相似。然而,比较可能很困难,因为 turbopack 倾向于生成更少但更大的块。我们的建议是关注更高级别的指标,如 Core Web Vitals 或你自己的应用程序级别指标来比较两个打包器的性能。然而,我们意识到有一个差距可能偶尔会导致较大的退化。
Turbopack 尚不具备 webpack 中默认启用的 Inner Graph Optimization 的等效功能。此优化对于树摇大型模块很有用。例如:
import heavy from 'some-heavy-dependency.js'
export function usesHeavy() {
return heavy.run()
}
export const CONSTANT_VALUE = 3如果应用程序只使用 CONSTANT_VALUE,Turbopack 会检测到这一点并删除 usesHeavy 导出,但不会删除相应的 import。然而,使用 Inner Graph Optimization,webpack 也可以删除 import,这也可以删除依赖项。
我们计划在 Turbopack 中提供 Inner Graph Optimization 的等效功能,但它仍在开发中。如果你受到此差距的影响,请考虑手动拆分模块。
构建缓存
Webpack 支持磁盘构建缓存以提高构建性能。Turbopack 提供了类似的选择加入功能,目前处于 beta 阶段。从 Next 16 开始,你可以通过设置以下实验性标志来启用 Turbopack 的文件系统缓存:
值得注意的是: 因此,在比较 webpack 和 Turbopack 性能时,请确保在构建之间删除
.next文件夹以进行公平比较,或启用 turbopack 文件系统缓存功能。
Webpack 插件
Turbopack 不支持 webpack 插件。这会影响依赖 webpack 插件系统进行集成的第三方工具。我们支持 webpack loaders。如果你依赖 webpack 插件,你需要找到与 Turbopack 兼容的替代方案,或继续使用 webpack,直到等效功能可用。
不支持和未计划的特性
一些特性尚未实现或未计划:
- 传统 CSS Modules 特性
- 独立的
:local和:global伪类(仅支持函数变体:global(...))。 @value规则(已被 CSS 变量取代)。:import和:exportICSS 规则。.module.css中的composes组合一个.css文件。在 webpack 中,这会将.css文件视为 CSS Module,在 Turbopack 中,.css文件将始终是全局的。这意味着如果你想在 CSS Module 中使用composes,你需要将.css文件更改为.module.css文件。- CSS Modules 中的
@import导入.css作为 CSS Module。在 webpack 中,这会将.css文件视为 CSS Module,在 Turbopack 中,.css文件将始终是全局的。这意味着如果你想在 CSS Module 中使用@import,你需要将.css文件更改为.module.css文件。
- 独立的
sassOptions.functions不支持在sassOptions.functions中定义的自定义 Sass 函数。此功能允许定义可以在编译期间从 Sass 代码中调用的 JavaScript 函数。Turbopack 基于 Rust 的架构无法直接执行通过sassOptions.functions传递的 JavaScript 函数,这与 webpack 基于 Node.js 的 sass-loader 不同,后者完全在 JavaScript 中运行。如果你使用自定义 Sass 函数,你需要使用 webpack 而不是 Turbopack。next.config.js中的webpack()配置 Turbopack 取代了 webpack,因此不识别webpack()配置。请改用turbopack配置。- Yarn PnP Next.js 中不计划提供 Turbopack 支持。
experimental.urlImports不计划用于 Turbopack。experimental.esmExternals不计划。Turbopack 不支持 Next.js 中的传统esmExternals配置。- 一些 Next.js 实验性标志
experimental.nextScriptWorkersexperimental.sri.algorithmexperimental.fallbackNodePolyfills我们计划在未来实现这些。
有关每个功能标志及其状态的完整详细分类,请参阅 Turbopack API Reference。
配置
Turbopack 可以通过 next.config.js(或 next.config.ts)中的 turbopack 键进行配置。配置选项包括:
rules为文件转换定义额外的 webpack loaders。resolveAlias创建手动别名(类似于 webpack 中的resolve.alias)。resolveExtensions更改或扩展模块解析的文件扩展名。
module.exports = {
turbopack: {
// 示例:添加别名和自定义文件扩展名
resolveAlias: {
underscore: 'lodash',
},
resolveExtensions: ['.mdx', '.tsx', '.ts', '.jsx', '.js', '.json'],
},
}有关更深入的配置示例,请参阅 Turbopack 配置文档。
生成用于性能调试的跟踪文件
如果你遇到性能或内存问题并希望帮助 Next.js 团队诊断它们,可以通过在开发命令中附加 NEXT_TURBOPACK_TRACING=1 来生成跟踪文件:
NEXT_TURBOPACK_TRACING=1 next dev这将生成一个 .next/dev/trace-turbopack 文件。在 Next.js 仓库上创建 GitHub issue 时包含该文件,以帮助我们调查。
默认情况下,开发服务器输出到 .next/dev。阅读更多关于 isolatedDevBuild 的信息。
总结
Turbopack 是一个基于 Rust 的增量打包器,旨在使本地开发和构建快速——特别是对于大型应用程序。它集成到 Next.js 中,提供零配置的 CSS、React 和 TypeScript 支持。
版本变更
| 版本 | 变更 |
|---|---|
v16.0.0 | Turbopack 成为 Next.js 的默认打包器。在找到配置文件时自动支持 Babel。 |
v15.5.0 | Turbopack 对 build 的 beta 支持 |
v15.3.0 | 对 build 的实验性支持 |
v15.0.0 | Turbopack 用于 dev 的稳定版 |