从 Nx 迁移
本指南将帮助你将现有的 Nx 存储库迁移到 Turborepo。
¥This guide will help you migrate an existing Nx repository to Turborepo.
-
探索 从 Nx 启动器迁移到 Turborepo 的关键概念
¥Explore key concepts by migrating from an Nx starter to Turborepo
-
更复杂的迁移场景 注意事项
¥Considerations for more complex migration scenarios
为什么要切换?
¥Why switch?
你选择从 Nx 迁移到 Turborepo 的原因有很多。下面,我们列出了开发者在迁移过程中参考的一些最常见动机。
¥There are many reasons why you may be choosing to migrate from Nx to Turborepo. Below, we've listed the most common motivations that developers have referenced for their migrations.
使用生态系统标准
¥Using ecosystem standards
Turborepo 的目标是轻量级,依靠你的代码库作为数据源。Turborepo 因其 JavaScript/TypeScript 支持而成为 基于 JavaScript 包管理器工作区构建 就是一个例子。
¥Turborepo's goal is to be lightweight, leaning on your repository as the source of truth. An example of this is Turborepo being built on top of JavaScript package manager workspaces for it's JavaScript/TypeScript support.
相比之下,Nx 使用多层插件、依赖和其他 Nx 特定的代码来推断你的存储库信息。虽然这些插件可以提供一层功能并且是可选的,但希望迁移的 Nx 用户经常将从代码库中删除特定于 Nx 的代码作为他们进行迁移的主要动机。
¥By contrast, Nx uses layers of plugins, dependencies, and other Nx-specific code to infer information about your repository. While these plugins can provide a layer of functionality and are optional, Nx users looking to migrate often cite removing Nx-specific code from their codebase as a key motivation for their change.
更好地控制源代码
¥Greater control of source code
Nx 的理念在于用多层插件、依赖和 Nx 专用代码来封装你的代码。虽然这些代码层是可选的,但它们提供了 Nx 的大量价值,并且是 Nx 推荐的,因此大多数 Nx 仓库都包含它们。许多开发者在迁移到 Turborepo 时表示,这些层往往会创建一个混淆层,使其存储库脱离他们的控制,从而导致问题。
¥Nx’s philosophy involves wrapping your code with layers of plugins, dependencies, and Nx-specific code. While these layers of code are optional, they provide a great deal of Nx's value and are recommended by Nx, so most Nx repos have them. When migrating to Turborepo, many developers explain that these layers tend to create a layer of obfuscation that abstracts their repository away from their control, causing issues.
Turborepo 选择让你根据自己的意愿处理工具,你可以根据需要配置(或不配置)任何工具。
¥Turborepo chooses to let you handle your tooling on your own terms, configuring (or not configuring) any of your tooling as you please.
减少存储库管理器的配置
¥Less configuration for your repository manager
迁移到 Turborepo 可能需要删除你之前为 Nx 使用的配置,并用更少的 Turborepo 配置替换,因为 Turborepo 会自动推断你的代码库需求。例如,以下是 Turborepo 和 Nx 以下使用 的等效启动器中提供的工具特定配置。
¥Migrating to Turborepo will likely require deleting previous configuration that you had for Nx and replacing it with less configuration for Turborepo, since Turborepo will automatically infer your repository's needs. For example, here are the tool-specific configurations you'll find in the equivalent starters for Turborepo and Nx used below.


迁移步骤
¥Migration steps
我们此次迁移的目标是尽快获得一个可以运行的 Turborepo 任务,以便你可以逐步采用 Turborepo 的功能。我们将首先使用 Nx 脚手架创建一个包含 Next.js 应用的仓库。
¥Our goal for this migration is to get a working Turborepo task as quickly as possible, so that you can adopt Turborepo features incrementally. We’ll start by using the Nx scaffolder to create a repository with a Next.js app.
步骤 1:更新 .gitignore
¥Step 1: Update .gitignore
Turborepo 使用 .turbo 目录来保存本地缓存和有关你的仓库的其他信息。因此,应该将其添加到你的 .gitignore
中。
¥Turborepo uses the .turbo directory to hold local caches and other information about your repository. For this reason, it should be added to your .gitignore
.
步骤 2:添加工作区定义
¥Step 2: Add a workspace definition
Turborepo 构建于 JavaScript 生态系统标准包管理器工作区之上。将目录路径添加到将包含包的工作区中。
¥Turborepo is built on top of package manager workspaces, a JavaScript ecosystem standard. Add the directory paths to the workspace that will contain packages.
步骤 3:将 package.json 文件添加到应用
¥Step 3: Add a package.json to the application
Turborepo 使用标准的 package.json
文件,而不是像 project.json
那样添加额外的配置文件。
¥Rather than adding additional configuration files like project.json
, Turborepo uses the standard package.json
file.
将 package.json
添加到 starter
应用。在 ./apps/starter/package.json
中创建一个包含 dev
和 build
脚本的 package.json
。
¥Add a package.json
to the starter
application. Create a package.json
at ./apps/starter/package.json
that contains a dev
and build
script.
步骤 4:删除 Nx 插件
¥Step 4: Remove Nx plugin
从 ./apps/starter/next.config.js 中删除 Nx 插件。下面的示例文件没有配置,但你现有的 Next.js 应用可能需要一些配置。
¥Remove the Nx plugin from ./apps/starter/next.config.js. The example file below doesn’t have configuration, though your existing Next.js application may need some.
步骤 5:添加 packageManager
字段
¥Step 5: Add the packageManager
field
根 package.json 需要包含 packageManager
字段。这确保了存储库中的开发者使用正确的包管理器,并且 Turborepo 可以根据你的锁定文件优化你的包图。
¥The root package.json needs to have the packageManager
field. This ensures developers in the repository use the correct package manager, and that Turborepo can optimize your package graph based on your lockfile.
步骤 6:运行包管理器的安装命令
¥Step 6: Run you package manager's install command
通过运行安装命令来更新锁定文件。
¥Update your lockfile by running your installation command.
完成此操作后,你应该会看到一个 lockfile diff,表明该包已添加到包管理器的工作区中。
¥Once you've done this, you should see a lockfile diff, indicating that the package has been added to the package manager's workspace.
步骤 7:安装 Turborepo
¥Step 7: Install Turborepo
将 Turborepo 添加到工作区的根 package.json
。
¥Add Turborepo to the root package.json
of the workspace.
你还可以选择全局安装 turbo
,以便在使用 Turborepo 时更加方便。
¥You can also optionally install turbo
globally for added convenience when working with Turborepo.
步骤 8:添加 turbo.json
¥Step 8: Add a turbo.json
在根目录下创建一个 turbo.json
来注册你的任务并描述它们之间的任务依赖。
¥Create a turbo.json
at the root to register your tasks and describe their task dependencies.


步骤 9:运行 turbo build
¥Step 9: Run turbo build
使用 Turborepo 构建应用。使用全局 turbo
,这将是 turbo build
。你也可以通过包管理器运行以下命令:
¥Build the application with Turborepo. Using global turbo
, this would be turbo build
. You can also run the command through your package manager:
步骤 10:启用远程缓存(可选)
¥Step 10: Enable Remote Caching (optional)
默认情况下,Turborepo 会在你运行时连接到免费的 Vercel 远程缓存:
¥By default, Turborepo will connect to the free-to-use Vercel Remote Cache when you run:
你还可以配置自托管远程缓存。
¥You may also configure a self-hosted Remote Cache.
高级迁移注意事项
¥Advanced migration considerations
虽然上面的迁移指南是一个很好的起点,但单一仓库的可能性和功能范围之广意味着很难为所有情况创建通用的说明。下面,我们列出了一些你可能正在考虑的常见后续步骤。
¥While the migration guide above is a good starting point, the breadth of possibilities and capabilities of monorepos means that its difficult to create generalized instructions for all cases. Below, we’ve listed some common next steps that you may be thinking about.
逐步迁移复杂的单一存储库
¥Migrate complex monorepos incrementally
我们鼓励增量迁移,这意味着你的代码库中将同时包含 Nx 和 Turborepo。确保花时间了解 Nx 任务图的构建方式。拆分任务图可能包括以下策略:
¥We encourage incremental migration, meaning you will have both of Nx and Turborepo in your repository at the same time. Make sure to spend time understanding how your Nx task graph is constructed. Splitting up the task graph may include strategies like:
-
一次迁移一个任务:将
nx run lint
更改为turbo run lint
¥Migrating one task at a time: Changing
nx run lint
toturbo run lint
-
一次迁移一个包/项目:将
nx run-many lint test --projects=web
更改为turbo run lint test --filter=web
¥Migrating one package/project at a time: Changing
nx run-many lint test --projects=web
toturbo run lint test --filter=web
-
重复运行某些任务:为了确保稳定性,你可以选择在迁移的早期阶段仍在熟悉和建立确定性时运行
turbo run lint
和nx run lint
。¥Double-running some of your tasks: To ensure stability, you may choose to run
turbo run lint
andnx run lint
while you're still getting comfortable and building certainty in the early phases of your migration.
在使用依赖的位置安装它们
¥Installing dependencies where they're used
Turborepo 建议使用 在使用它们的地方安装包 来提高缓存命中率,增强依赖修剪能力,并向开发者明确哪些依赖对应哪些包。这与 Nx 策略不同,Nx 策略将所有依赖安装在仓库的根目录下,从而使所有依赖都可供工作区中的所有包使用。
¥Turborepo recommends installing packages where they're used to improve cache hit ratios, help dependency pruning capability, and clarify for developers which dependencies are meant for which packages. This is different from the Nx strategy, where all dependencies are installed at the root of the repository, making all dependencies available to all packages in the workspace.
过去,Nx 建议将所有依赖安装在仓库的根目录中,从而使所有依赖都可供工作区中的所有包使用。如果你遵循此指南,我们强烈建议你将需要依赖的包和应用移至 package.json
。访问我们关于管理依赖的文档 了解更多。
¥Historically, Nx has recommended installing all dependencies in the root of the repository, making all dependencies available to all packages in the Workspace. If you followed this guidance, we highly recommend that you move dependencies to the package.json
's for packages and applications that need them. Visit our documentation on managing dependencies to learn more.
创建共享包
¥Creating shared packages
你将按照与上述大致相同的步骤将包添加到包管理器的工作区。
¥You’ll follow roughly the same set of steps as above to add a package to your package manager’s workspace.
-
确保软件包的目录包含在工作区定义中(例如
./packages/*
)。¥Ensure the package’s directory is included in the workspace definition (like
./packages/*
). -
将
package.json
添加到包含其运行所需脚本的包中。¥Add a
package.json
to the package with the scripts it needs to run. -
检查
turbo.json
中的任务依赖,以确保你的依赖图符合你的要求。¥Check task dependencies in
turbo.json
to make sure your dependency graph meets your requirements.
多语言单一仓库
¥Multi-language monorepos
Turborepo 原生支持 JavaScript 和 TypeScript,并支持你想要使用的任何其他语言。访问多语言支持文档 了解更多。
¥Turborepo natively supports JavaScript and TypeScript, with secondary support for any other languages you’d like to use. Visit the Multi-Language support documentation to learn more.
配置等效项
¥Configuration equivalents
可以使用下表将 nx.json
中的配置映射到 turbo.json
。
¥Configuration found in nx.json
can be mapped to turbo.json
using the tables below.
Nx 和 Turborepo 中用于捕获文件的 glob 大部分是相同的。有关详细信息和特殊情况,请参阅 我们的文件全局规范。
¥The majorify of globs for capturing files are the same between Nx and Turborepo. See our file glob specification for details and edge cases.
全局配置
¥Global configuration
Nx | Turborepo |
---|---|
sharedGlobals | globalDependencies |
sharedGlobals.env | globalEnv |
sharedGlobals.namedInput | globalDependencies |
cacheDirectory | cacheDir |
任务配置
¥Task configuration
Nx | Turborepo |
---|---|
inputs 文件 | tasks[task].inputs |
inputs.env | tasks[task].env |
outputs 文件 | tasks[task].outputs |
cache | tasks[task].cache |
CLI 等效项
¥CLI equivalents
Nx | Turborepo |
---|---|
nx generate | turbo generate |
nx run | turbo run |
nx run-many | turbo run |
nx reset | --force |
--parallel | --concurrency |
--nxBail | --continue |
--projects | --filter |
--graph | --graph |
--output-style | --log-order |
--no-cloud | --cache |
--verbose | --verbosity |