在現代軟體開發中,Monorepo 已成為團隊協作與代碼管理的重要策略。本文將探討 Monorepo 的優缺點,並分享團隊如何運用 Monorepo(特別是 Turborepo)來解決實際開發中的痛點。
Monorepo 的優缺點
優點
Turborepo 如何解決痛點
為了解決上述問題,我們採用了 Turborepo,並取得了顯著的效果:
抽離共用功能:將一些通用能力(如流程編排、動態表單)抽離成獨立項目,其他項目可直接引入使用,減少重複開發。
建立 UI 庫:構建統一的 UI 庫項目,應用項目可直接引入使用,並提供完整的文檔,提升開發效率。
共享工具類:將網路請求、工具類、加密等抽離成獨立項目,供其他項目重複使用,保持代碼一致性。
為何選擇 Turborepo
快取機制:Turborepo 具有強大的快取功能,能夠快取任務的結果和日誌,提升構建速度。
任務並行執行:優化了任務的並行執行,充分利用 CPU 資源,加快構建流程。
官方推薦:由於專案使用了 umijs 作為腳手架,其官方推薦使用 Turbo 的快取機制。
Turborepo 基本介紹
Turbo 的特性
快取任務
評估任務輸入:將工作區資料夾中所有非 Git 忽略的檔案轉換成哈希值。
檢查快取:查看本機快取中是否存在相同哈希值的快取資料夾。
執行或復用任務:若無快取,則執行任務並快取結果;若有快取,直接復用結果,省略執行時間。
平行任務
Turbo 在執行指令時,會利用所有可用 CPU,平行執行多個任務。
工作區與任務關係
工作區:每個應用程式和軟體包都在自己的工作區中,擁有自己的 package.json。
根工作區:根資料夾下的 package.json 用於指定整個 Monorepo 的依賴項,並新增運行在整個 Monorepo 上的任務。
Turborepo 的使用
宣告 Pipeline
在 turbo.json 中,最重要的是 pipeline 配置,用於聲明工作區的任務及任務之間的依賴關係,並可配置任務的快取。例如:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**"]
},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
},
"lint": {},
"deploy": {
"dependsOn": ["build", "test", "lint"]
}
}
}
配置任務之間的依賴關係
在同一工作區
若工作區的任務依賴目前工作區的其他任務,可使用:
{
"dependsOn": ["build"]
}
例如,執行 test 任務之前需要先執行當前工作區的 build 任務。
在不同工作區
使用 ^ 符號來聲明任務依賴其所依賴的工作區中的任務:
{
"dependsOn": ["^build"]
}
表示 build 任務需要先完成其所依賴工作區的 build 任務。
依賴特定工作區的任務
語法為 #,例如:
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"frontend#deploy": {
"dependsOn": ["ui#test", "backend#deploy"]
}
}
}
表示 frontend 工作區的 deploy 任務需要在 ui 的 test 和 backend 的 deploy 任務完成後執行。
運行根節點任務
執行 Monorepo 根目錄 package.json 中的任務,語法為 "//#"。
注意事項
如果 pipeline 中聲明的任務在所有工作區的 package.json 中不存在,Turbo 會優雅地忽略這些任務,不會報錯。
pipeline 是唯一聲明 Turbo 任務的地方,未在 pipeline 中聲明的任務,執行會報錯。