跳到内容

Turbopack

Turbopack 是一个为 JavaScript 和 TypeScript 优化的增量打包器,用 Rust 编写,并内置于 Next.js 中。您可以将 Turbopack 与 Pages 和 App Router 配合使用,以获得更快的本地开发体验。

为什么选择 Turbopack?

我们构建 Turbopack 是为了提升 Next.js 的性能,包括:

  • 统一图: Next.js 支持多种输出环境(例如,客户端和服务器)。管理多个编译器并将打包结果拼接在一起可能会很麻烦。Turbopack 为所有环境使用单个统一图
  • 打包与原生 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 编译。
快速刷新支持无需配置。
React 服务器组件 (RSC)支持适用于 Next.js App Router。Turbopack 确保正确的服务器/客户端打包。
根布局创建不支持App Router 中根布局的自动创建不受支持。Turbopack 将指导您手动创建。

CSS 和样式

功能状态备注
全局 CSS支持直接在应用程序中导入 .css 文件。
CSS 模块支持.module.css 文件原生支持(Lightning CSS)。
CSS 嵌套支持Lightning CSS 支持现代 CSS 嵌套
@import 语法支持组合多个 CSS 文件。
PostCSS支持在 Node.js worker 池中自动处理 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)尚未支持。有关详细信息,请参见下文。

资产

功能状态备注
静态资产(图片、字体)支持导入 import img from './img.png' 开箱即用。在 Next.js 中,为 <Image /> 组件返回一个对象。
JSON 导入支持支持从 .json 文件命名导入或默认导入。

模块解析

功能状态备注
路径别名支持读取 tsconfig.jsonpathsbaseUrl,与 Next.js 行为匹配。
手动别名支持next.config.js 中配置 resolveAlias(类似于 webpack.resolve.alias)。
自定义扩展支持next.config.js 中配置 resolveExtensions.
AMD部分支持基本转换有效;高级 AMD 用法有限。

性能和快速刷新

功能状态备注
快速刷新支持更新 JavaScript、TypeScript 和 CSS,无需完全刷新。
增量打包支持Turbopack 惰性地只构建开发服务器请求的内容,从而加快大型应用程序的速度。

与 webpack 的已知差距

在迁移应用程序时,webpack 和 Turbopack 之间存在一些重要的非平凡行为差异,需要注意。通常,对于新应用程序来说,这些问题较少。

CSS 模块排序

Turbopack 将遵循 JS 导入顺序来排序CSS 模块,否则这些模块将不会被排序。例如

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 倾向于生成更少但更大的块。我们的建议是关注更高层次的指标,例如核心 Web 生命体征或您自己的应用程序级别指标来比较两种打包器的性能。但是,我们确实知道一个可能偶尔导致重大退步的差距。

Turbopack 尚未拥有与 webpack 中的内部图优化等效的功能,该优化是默认启用的。此优化有助于摇树大型模块。例如

import heavy from 'some-heavy-dependency.js'
 
export function usesHeavy() {
  return heavy.run()
}
 
export const CONSTANT_VALUE = 3

如果应用程序只使用 CONSTANT_VALUE,Turbopack 将检测到并删除 usesHeavy 导出,但不会删除相应的 import。然而,通过内部图优化,webpack 也可以删除 import,从而也可以删除依赖项。

我们计划在 Turbopack 中提供与内部图优化等效的功能,但它仍在开发中。如果您受到此差距的影响,请考虑手动拆分模块。

构建缓存

Webpack 支持磁盘构建缓存以提高构建性能。Turbopack 提供了一个类似的自选功能,目前处于 Beta 阶段。从 Next 16 开始,您可以通过设置以下实验性标志来启用 Turbopack 的文件系统缓存:

须知: 因此,在比较 webpack 和 Turbopack 的性能时,请确保在构建之间删除 .next 文件夹以进行公平比较,或者启用 turbopack 文件系统缓存功能。

Webpack 插件

Turbopack 不支持 webpack 插件。这会影响依赖 webpack 插件系统进行集成的第三方工具。我们支持webpack 加载器。如果您依赖 webpack 插件,您需要寻找 Turbopack 兼容的替代方案,或者继续使用 webpack,直到提供等效功能为止。

不支持和未计划的特性

有些功能尚未实现或未计划:

  • 遗留 CSS Modules 功能
    • 独立的 :local:global 伪类(仅支持函数变体 :global(...))。
    • @value 规则(已被 CSS 变量取代)。
    • :import:export ICSS 规则。
    • .module.css 中组合 .css 文件的 composes。在 webpack 中,这将把 .css 文件视为 CSS Module,而 Turbopack 将始终将 .css 文件视为全局文件。这意味着如果要在 CSS Module 中使用 composes,需要将 .css 文件更改为 .module.css 文件。
    • CSS Modules 中将 .css 作为 CSS Module 导入的 @import。在 webpack 中,这会将 .css 文件视为 CSS Module,而 Turbopack 将始终将 .css 文件视为全局文件。这意味着如果要在 CSS Module 中使用 @import,需要将 .css 文件更改为 .module.css 文件。
  • sassOptions.functions 不支持在 sassOptions.functions 中定义的自定义 Sass 函数。此功能允许定义可在编译期间从 Sass 代码调用的 JavaScript 函数。Turbopack 基于 Rust 的架构无法直接执行通过 sassOptions.functions 传递的 JavaScript 函数,这与完全在 JavaScript 中运行的 webpack 基于 Node.js 的 sass-loader 不同。如果您正在使用自定义 Sass 函数,则需要使用 webpack 而不是 Turbopack。
  • webpack() 配置next.config.js 中 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 参考

配置

Turbopack 可以通过 next.config.js(或 next.config.ts)在 turbopack 键下配置。配置选项包括:

  • rules 定义用于文件转换的额外webpack 加载器
  • resolveAlias 创建手动别名(类似于 webpack 中的 resolve.alias)。
  • resolveExtensions 更改或扩展模块解析的文件扩展名。
next.config.js
module.exports = {
  turbopack: {
    // Example: adding an alias and custom file extension
    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 for dev 稳定版