Menu

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 无需任何配置:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

使用 Webpack

如果你需要使用 Webpack 而不是 Turbopack,可以使用 --webpack 标志选择加入:

package.json
{
  "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.jsonpathsbaseUrl,与 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,这些模块没有其他排序方式。例如:

components/BlogPost.jsx
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 不支持此语法。

从:

styles/globals.scss
@import '~bootstrap/dist/css/bootstrap.min.css';

改为:

styles/globals.scss
@import 'bootstrap/dist/css/bootstrap.min.css';

如果你无法更新导入,可以添加 turbopack.resolveAlias 配置来将 ~ 语法映射到实际路径:

next.config.js
module.exports = {
  turbopack: {
    resolveAlias: {
      '~*': '*',
    },
  },
}

包大小

根据我们在生产应用程序上的测试,我们观察到 Turbopack 通常生成的包大小与 Webpack 相似。然而,比较可能很困难,因为 turbopack 倾向于生成更少但更大的块。我们的建议是关注更高级别的指标,如 Core Web Vitals 或你自己的应用程序级别指标来比较两个打包器的性能。然而,我们意识到有一个差距可能偶尔会导致较大的退化。

Turbopack 尚不具备 webpack 中默认启用的 Inner Graph Optimization 的等效功能。此优化对于树摇大型模块很有用。例如:

large.module.js
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:export ICSS 规则。
    • .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.nextScriptWorkers
    • experimental.sri.algorithm
    • experimental.fallbackNodePolyfills 我们计划在未来实现这些。

有关每个功能标志及其状态的完整详细分类,请参阅 Turbopack API Reference

配置

Turbopack 可以通过 next.config.js(或 next.config.ts)中的 turbopack 键进行配置。配置选项包括:

  • rules 为文件转换定义额外的 webpack loaders
  • resolveAlias 创建手动别名(类似于 webpack 中的 resolve.alias)。
  • resolveExtensions 更改或扩展模块解析的文件扩展名。
next.config.js
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.0Turbopack 成为 Next.js 的默认打包器。在找到配置文件时自动支持 Babel。
v15.5.0Turbopack 对 build 的 beta 支持
v15.3.0build 的实验性支持
v15.0.0Turbopack 用于 dev 的稳定版