如果你維護過三個以上的前端專案,一定遇過這種場景:公共工具函式改了一行,得同時到三個倉庫各改一次、各發一次版;A 專案升了 TypeScript 5.4,B 專案還卡在 4.9,型別對不上;想抽共用元件,只能複製貼上,貼著貼著兩邊就分家了。這些痛點的標準解法,就是今天的主角——Monorepo。
一、什麼是 Monorepo?先分清三個名詞
Monorepo 就是把多個專案或套件,放進同一個 Git 倉庫統一管理。它和兩個容易混淆的概念要區分:
- Monorepo ≠ 巨石應用(Monolith):Monolith 是「一個應用包辦所有功能」;Monorepo 是「一個倉庫管理多個套件」,套件之間依然邊界清晰
- Polyrepo(一倉庫一專案)的痛點:跨倉庫改代碼要發版多次、依賴版本各自漂移、共用代碼只能靠複製
- 大廠都在用:Google、Meta 內部都是巨型 Monorepo;前端圈熟悉的 Vben Admin 本身就是 pnpm Monorepo 架構
重點:Monorepo 解決的是「代碼共享與一致性」問題,不是效能問題。把八竿子打不著的專案硬塞一個倉庫,只會拖慢 clone 和 CI。
二、步驟 1:用 pnpm Workspace 搭骨架
先安裝 pnpm(建議用 corepack),然後在專案根目錄建立 pnpm-workspace.yaml:
packages:
- "apps/*"
- "packages/*"
接著建立這樣的目錄結構:
my-monorepo/
├─ apps/
│ └─ web/ # 主應用(Vite + Vue3)
├─ packages/
│ ├─ utils/ # 共用工具庫
│ └─ ui/ # 共用元件庫
├─ package.json
└─ pnpm-workspace.yaml
關鍵一步:在 apps/web/package.json 裡用 workspace:* 協議引用本地套件:
{
"dependencies": {
"@my/utils": "workspace:*"
}
}
執行 pnpm install 後,node_modules 裡的 @my/utils 會是一個指向本地目錄的 symlink。改了 utils 的代碼,web 這邊立刻生效,完全不用發版——這就是 workspace 協議的精髓:依賴的是「本地工作區的這個套件」,不是 npm 上的版本號。
三、步驟 2:用 Turborepo 加速任務調度
套件多了之後,build/lint 一個個跑太慢。Turborepo 會分析套件依賴圖,只重跑「真的變了」的部分。在根目錄初始化後配置 turbo.json:
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
dependsOn: ["^build"] 表示「先把我依賴的套件 build 完再輪到我」——執行 pnpm turbo run build 時會自動先 build utils、再 build web。沒變化的套件直接命中快取,秒出結果;還可以用 filter 精準圈定範圍:
# 只對 web 及其依賴鏈跑建置
pnpm turbo run build --filter=web
重點:outputs 一定要寫對(如 dist/**),快取命中時 Turborepo 靠它還原產物;漏寫會出現「快取命中但檔案不存在」的靈異事件。
四、步驟 3:實戰抽共用元件與發版
把 formatDate、useDebounce 這類高頻工具放進 packages/utils 導出,apps 裡直接 import { useDebounce } from '@my/utils',配合 TypeScript 專案引用,型別即時可見。等元件庫要對外發佈時,再引入 Changesets 管版本號與 changelog——內部依賴用 workspace:*,對外發佈時自動替換成真實版本號。
五、三個邊界與避坑指南
- 倉庫範圍:Monorepo 適合「強相關」專案——同一團隊、同一技術棧、高頻共享代碼;不同業務線的專案別硬湊
- 依賴提升:pnpm 預設嚴格隔離 node_modules,子套件用了未宣告的依賴會直接報錯——這是好事,逼你把 dependency 寫乾淨
- CI 範圍:用 Turborepo 的快取加
--filter,只建置受本次提交影響的套件,別每次全量跑,否則 CI 會越來越慢
總結:Monorepo 的本質是用「倉庫邊界」換「同步成本」——共享代碼即時可見、版本天然對齊,代價是工程化基建要自己搭好。pnpm Workspace 負責依賴拓撲,Turborepo 負責任務調度,兩者搭配就是目前前端圈的主流方案。
互動話題:你的團隊現在是 Polyrepo 還是 Monorepo?踩過哪些「共用代碼同步地獄」的坑?歡迎留言聊聊!