一、概述:它们是什么?
Turborepo 和 Nx 都是现代前端工程中用于管理 Monorepo(多包存储库) 的任务编排与缓存系统。
Monorepo 的核心挑战在于:一个仓库包含数十甚至上百个项目,每个项目都有自己的构建、测试流程。如果没有工具辅助,顺序执行所有任务会极其耗时。Turborepo 和 Nx 正是为了解决这个问题而生,它们通过依赖图分析、智能任务调度和缓存三大机制来加速工作流。
在工具生态中,它们的定位各有侧重:
| 工具 | 核心回答的问题 |
|---|---|
| pnpm / Yarn / npm | 包如何安装和链接? |
| Turborepo / Nx | 任务如何快速、按正确顺序运行? |
| Lerna / Rush | 多包版本管理和发布流程如何管理? |
| Bazel | 大型多语言代码库如何构建和测试? |
二、核心概念
两者共享以下核心概念:
1. 依赖图(Dependency Graph)
工具自动分析项目之间的依赖关系(如 app 依赖 ui-library),形成一张图。有了这张图,才能知道哪些任务可以并行,哪些必须串行。
2. 任务图(Task Graph)
基于依赖图,进一步构建出任务之间的执行顺序关系。例如,必须先构建 ui-library,才能构建依赖它的 app。
3. 缓存(Caching)
这是加速的核心。工具会对每个任务的输入(源代码、环境变量、依赖等)计算哈希值。如果输入没有变化,就直接从缓存中恢复之前的输出结果,跳过实际执行。
4. 远程缓存(Remote Caching)
将缓存存储在云端(Turborepo 由 Vercel 提供,Nx 由 Nx Cloud 提供),团队成员和 CI 环境可以共享缓存,进一步加速。
三、Turborepo 详解
核心理念
速度优先、极简主义 。Turborepo 被设计为运行在你已有的 package.json 脚本之上,不做多余假设。它是"工作区原生、脚本优先、JavaScript 生态原生"的。
配置方式:turbo.json
所有任务编排逻辑在根目录的 turbo.json 中声明:
json
{
"tasks": {
"build": {
"dependsOn": ["^build"], // 先构建所有依赖包
"outputs": ["dist/**"] // 缓存这些输出
},
"dev": {
"cache": false, // 开发服务器不缓存
"persistent": true, // 标记为常驻进程
"dependsOn": ["//#setup"] // 依赖根任务
},
"lint": {
"dependsOn": [] // 可并行执行
}
}
}
关键语法:
dependsOn: ["^build"]--- 先执行所有依赖包的build任务dependsOn: ["build"](无^)--- 先执行当前项目自身的build任务--filter参数 --- 只对特定项目或项目子集执行任务
使用步骤
- 确保已有 package manager workspaces(pnpm/yarn/npm workspaces)
- 安装 turbo :
npm install turbo --save-dev - 创建
turbo.json,配置任务 - 运行任务 :
npx turbo build
Turborepo 可以增量式接入现有仓库,无需大规模重构。
四、Nx 详解
核心理念
全功能平台 。Nx 远不止是一个任务运行器,它试图成为 Monorepo 的"操作系统"。除了任务编排和缓存,Nx 还内置了代码生成、模块边界约束、依赖图可视化、版本发布工具等能力。
配置方式
Nx 的任务可以从三个来源自动合并:
package.json中的scripts- 工具配置文件自动推断(如
jest.config.js自动产生test任务) project.json或nx.json中的显式配置
任务管道配置 (nx.json 或 project.json):
json
{
"targetDefaults": {
"build": {
"dependsOn": ["^build", "prebuild"]
},
"test": {
"dependsOn": ["build"]
}
}
}
核心命令
- 单项目 :
npx nx test header - 多项目 :
npx nx run-many -t build lint test - 仅影响的项目 :
npx nx affected -t test--- 只运行 PR 改动所影响项目的测试
特色能力
Nx 的分布式任务执行 (Distributed Task Execution)可以将任务分发到多台机器并行执行。官方基准测试显示,在大型 Monorepo 中 Nx 比 Turborepo 快 7 倍以上。此外,Nx 还提供依赖图可视化 和IDE 插件支持。
五、对比总结
| 维度 | Turborepo | Nx |
|---|---|---|
| 定位 | 快速任务运行器 | 全功能 Monorepo 平台 |
| 上手难度 | 低,配置极简 | 中等,功能丰富需要学习 |
| 配置哲学 | 单一 turbo.json |
多种配置来源,灵活但复杂 |
| 缓存 | ✅ 本地 + 远程(Vercel) | ✅ 本地 + 远程(Nx Cloud) |
| 受影响项目检测 | ✅(--filter) |
✅(affected 命令) |
| 代码生成 | ❌ | ✅ |
| 模块边界约束 | ❌ | ✅ |
| 分布式执行 | ❌ | ✅ |
| 依赖图可视化 | 基础 | 强大 |
| 插件生态 | 有限 | 丰富(支持 Angular、React、Vue、NestJS 等) |
| 包结构要求 | 基于 package manager workspaces | 更灵活,可接入非 Monorepo 项目 |
| 维护方 | Vercel | Nrwl |
六、选型建议
选择 Turborepo 的场景
- 项目以 Next.js / React / Vue 等前端应用为主
- 团队规模较小,希望低成本快速引入 Monorepo
- 核心痛点是"构建和 CI 太慢",不需要额外的治理能力
- 已经重度使用 Vercel 部署生态,希望深度集成
- 典型的「
apps/+packages/」结构
选择 Nx 的场景
- 大中型团队,需要强大的任务缓存和调度能力
- 微前端架构,需要高效管理多个子应用
- 项目非常复杂,包含前端、后端(NestJS)、工具库等多种类型
- 需要代码生成来保证项目结构一致性
- 需要模块边界约束来强制执行架构规范
- 需要分布式执行来进一步加速 CI
关于 Lerna
值得一提的是,Lerna 在 6.x 版本后由 Nx 团队维护,其任务运行和缓存能力实际上由 Nx 驱动。如果你主要需要多包版本管理和 npm 发布自动化 ,Lerna 仍然是最佳选择;但纯粹的任务编排建议直接使用 Turborepo 或 Nx。
七、总结
Turborepo 和 Nx 都是优秀的 Monorepo 任务编排工具,但定位不同:
- Turborepo 是手术刀------轻量、聚焦、即插即用,适合希望快速解决构建速度问题的团队。
- Nx 是瑞士军刀------功能全面、平台化,适合需要长期治理和复杂工程能力的团队。
两者没有绝对的优劣,选择取决于团队规模、项目复杂度以及对"控制力"的需求。好消息是,两者都可以增量接入现有项目,你可以先从 Turborepo 开始,在需要更多能力时再考虑迁移到 Nx。