从 Nx 迁移
本指南将帮助你将现有的 Nx 仓库迁移到 Turborepo。
- 通过从 Nx starter 迁移到 Turborepo 探索关键概念
- 考虑更复杂的迁移场景
为什么要切换?
你可能有许多理由选择从 Nx 迁移到 Turborepo。下面,我们列出了开发者在迁移时最常提及的动机。
使用生态系统标准
Turborepo 的目标是轻量级,以你的仓库作为真理的来源。Turborepo 的一个例子是 基于 JavaScript 包管理器工作区构建,以支持 JavaScript/TypeScript。
相比之下,Nx 使用插件、依赖项和其他 Nx 特定的代码层来推断有关你的仓库的信息。虽然这些插件可以提供一层功能并且是可选的,但希望迁移的 Nx 用户通常将从其代码库中删除 Nx 特定的代码作为他们更改的关键动机。
更好地控制源代码
Nx 的理念包括使用插件、依赖项和 Nx 特定的代码层包装你的代码。虽然这些代码层是可选的,但它们提供了 Nx 的大部分价值,并且是 Nx 推荐的,因此大多数 Nx 仓库都拥有它们。在迁移到 Turborepo 时,许多开发者解释说,这些层往往会创建一个混淆层,将他们的仓库从他们的控制中抽象出来,从而导致问题。
Turborepo 选择让你按照自己的方式处理你的工具,随意配置(或不配置)你的任何工具。
更少的仓库管理器配置
迁移到 Turborepo 可能需要删除你之前为 Nx 所做的配置,并将其替换为更少的 Turborepo 配置,因为 Turborepo 将自动推断你仓库的需求。例如,以下是你在 Turborepo 和 Nx 的等效 starter 中找到的工具特定配置在下面使用。


免费远程缓存
Turborepo 的 远程缓存 将你的任务结果存储在云服务器上。这通过防止整个组织内重复工作来节省大量时间。 Vercel 远程缓存 到目前为止已为团队节省了超过 500 年的计算时间。
自 Nx 19.7 以来,类似的功能是一项付费功能,即使是自托管也是如此。当自托管或使用 Vercel 远程缓存时,Turborepo 的远程缓存是免费的。
迁移步骤
我们此次迁移的目标是尽快获得可用的 Turborepo 任务,以便你可以逐步采用 Turborepo 功能。我们将首先使用 Nx scaffolder 创建一个带有 Next.js 应用程序的仓库。
步骤 1:更新 .gitignore
Turborepo 使用 .turbo 目录来保存本地缓存和你仓库的其他信息。因此,应将其添加到你的 .gitignore
中。
步骤 2:添加工作区定义
Turborepo 构建于包管理器工作区(JavaScript 生态系统标准)之上。将目录路径添加到将包含包的工作区。
步骤 3:向应用程序添加 package.json
Turborepo 使用标准的 package.json
文件,而不是添加额外的配置文件(如 project.json
)。
向 starter
应用程序添加 package.json
。在 ./apps/starter/package.json
创建一个 package.json
,其中包含 dev
和 build
脚本。
步骤 4:删除 Nx 插件
从 ./apps/starter/next.config.js 中删除 Nx 插件。下面的示例文件没有配置,但你现有的 Next.js 应用程序可能需要一些配置。
步骤 5:添加 packageManager
字段
根 package.json 需要包含 packageManager
字段。这确保了仓库中的开发者使用正确的包管理器,并且 Turborepo 可以根据你的 lockfile 优化你的包图。
步骤 6:运行你的包管理器的安装命令
通过运行你的安装命令来更新你的 lockfile。
完成此操作后,你应该会看到 lockfile 差异,表明该包已添加到包管理器的工作区。
步骤 7:安装 Turborepo
将 Turborepo 添加到工作区的根 package.json
中。
你也可以选择全局安装 turbo
,以便在使用 Turborepo 时更加方便。
步骤 8:添加 turbo.json
在根目录创建一个 turbo.json
,以注册你的任务并描述其任务依赖项。


步骤 9:运行 turbo build
使用 Turborepo 构建应用程序。使用全局 turbo
,这将是 turbo build
。你也可以通过你的包管理器运行该命令
步骤 10:启用远程缓存(可选)
默认情况下,当你运行时,Turborepo 将连接到免费使用的 Vercel 远程缓存
你还可以配置自托管的远程缓存,这不需要许可证或任何其他费用。
高级迁移注意事项
虽然上面的迁移指南是一个好的起点,但 monorepo 的可能性和功能范围意味着很难为所有情况创建通用的说明。下面,我们列出了一些你可能正在考虑的常见后续步骤。
逐步迁移复杂的 monorepo
我们鼓励增量迁移,这意味着你的仓库将同时拥有 Nx 和 Turborepo。确保花时间了解你的 Nx 任务图是如何构建的。拆分任务图可能包括以下策略:
- 一次迁移一个任务:将
nx run lint
更改为turbo run lint
- 一次迁移一个包/项目:将
nx run-many lint test --projects=web
更改为turbo run lint test --filter=web
- 双重运行你的某些任务:为了确保稳定性,你可能会选择在迁移的早期阶段,当你仍然感到舒适并在建立确定性时,运行
turbo run lint
和nx run lint
。
在使用的位置安装依赖项
Turborepo 建议在使用的位置安装包,以提高缓存命中率、帮助依赖项修剪能力,并向开发者明确哪些依赖项用于哪些包。这与 Nx 策略不同,Nx 策略将所有依赖项安装在仓库的根目录中,使所有依赖项对工作区中的所有包都可用。
从历史上看,Nx 建议将所有依赖项安装在仓库的根目录中,使所有依赖项对工作区中的所有包都可用。如果你遵循了此指南,我们强烈建议你将依赖项移动到需要它们的包和应用程序的 package.json
中。 访问我们的依赖项管理文档 以了解更多信息。
创建共享包
你将大致按照与上面相同的步骤集来向包管理器的工作区添加包。
- 确保包的目录包含在工作区定义中(如
./packages/*
)。 - 向包添加一个
package.json
,其中包含它需要运行的脚本。 - 检查
turbo.json
中的任务依赖项,以确保你的依赖关系图满足你的要求。
多语言 monorepo
Turborepo 原生支持 JavaScript 和 TypeScript,并为你想使用的任何其他语言提供辅助支持。 访问多语言支持文档 以了解更多信息。
配置等效项
在 nx.json
中找到的配置可以使用下表映射到 turbo.json
。
用于捕获文件的大多数 glob 在 Nx 和 Turborepo 之间是相同的。有关详细信息和边缘情况,请参阅我们的文件 glob 规范。
全局配置
Nx | Turborepo |
---|---|
sharedGlobals | globalDependencies |
sharedGlobals.env | globalEnv |
sharedGlobals.namedInput | globalDependencies |
cacheDirectory | cacheDir |
任务配置
Nx | Turborepo |
---|---|
inputs 文件 | tasks[task].inputs |
inputs.env | tasks[task].env |
outputs 文件 | tasks[task].outputs |
cache | tasks[task].cache |
CLI 等效项
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 |