Turborepo 成熟了。在我們的 15 個包的 monorepo 中使用了大半年,分享一下實踐經驗。
為什麼選 Turborepo
Monorepo 工具選型:
- Nx:功能最全,但學習曲線陡峭,對非 JS 項目有偏好
- Lerna:版本管理為主,任務編排能力弱
- Turborepo:專注任務編排和緩存,上手簡單,和 pnpm 配合好
我們的需求很簡單:任務編排 + 緩存 + 並行執行。不需要 Nx 的全套功能。
基礎配置
jsonc
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.ts", "src/**/*.tsx", "test/**/*.ts"]
},
"lint": {
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
}
}
}
dependsOn: ["^build"]:先構建所有依賴包(^表示依賴)outputs:定義緩存的產出文件inputs:定義影響緩存的輸入文件(精確控制緩存失效)cache: false:dev 模式不緩存
工作原理
turbo build
1. 解析所有包的 package.json,構建依賴圖
2. 按拓撲排序確定構建順序
3. 並行執行沒有依賴關係的任務
4. 每個任務的輸入(源碼 + 依賴 hash + 環境變量)生成 hash
5. 如果 hash 命中遠程緩存,跳過執行,直接恢復 outputs
6. 執行結果上傳到遠程緩存
實際效果
# 首次構建(無緩存)
turbo build: 45s
# 只改了一個包的代碼
turbo build: 3s (其餘 14 個包命中緩存)
# CI 中 PR 重複構建
turbo build: <1s (全部命中遠程緩存)
遠程緩存
bash
# 使用 Vercel Remote Cache(免費額度夠用)
npx turbo login
npx turbo link
# 或者自建遠程緩存
# 使用 turbo-server 或第三方方案
遠程緩存讓 CI 和本地共享構建緩存。同事已經構建過的代碼,你拉下來直接用緩存。
與 pnpm workspace 配合
jsonc
// pnpm-workspace.yaml
packages:
- "packages/*"
- "apps/*"
// package.json
{
"scripts": {
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint",
"dev": "turbo run dev --parallel"
}
}
pnpm 管依賴解析和安裝,Turbo 管任務執行和緩存。職責清晰。
過濾和選擇性執行
bash
# 只構建某個包及其依賴
turbo run build --filter=@company/ui
# 只構建有變更的包
turbo run build --filter=[HEAD^1]
# 排除某些包
turbo run build --filter='!@company/docs'
# 只構建 apps 目錄下的包
turbo run build --filter='./apps/*'
全局依賴和緩存失效
jsonc
// turbo.json
{
"globalDependencies": [
// 這些文件變化會導致所有任務緩存失效
".env",
"tsconfig.base.json"
],
"pipeline": {
"build": {
"dependsOn": ["^build"],
// 精確到每個任務的輸入文件
"inputs": ["src/**", "tsconfig.json", "package.json"]
}
}
}
globalDependencies 很重要。如果忘記配置 tsconfig.base.json,改了基礎配置但緩存不過期,會出詭異的構建問題。
小結
- Turborepo 專注做一件事:任務編排 + 緩存,做得很好
- 與 pnpm workspace 天然配合,各司其職
- 遠程緩存是殺手級功能,CI 構建時間可以降到秒級
- 配置簡單,
turbo.json一個文件搞定 - 不需要 Nx 那樣的學習成本,適合大多數前端 monorepo