- Published on
將公司專案轉換成 Monorepo 遇到的那些事 - 第九篇 如何管理 Monorepo 中的多個團隊協作
- Authors
- Name
- Alex Yu

如何管理 Monorepo 中的多個團隊協作
在現代軟體開發中,隨著專案規模的擴大,多個團隊協作開發已經成為常態。當我們採用 monorepo 架構時,雖然帶來了許多優勢,但也同時為多團隊協作帶來了新的挑戰。本文將深入探討在 monorepo 環境中,如何有效管理多個團隊的協作流程,包含團隊間的程式碼共享和衝突解決方案。
多團隊協作的挑戰
在傳統的多儲存庫架構中,團隊分工相對清晰,每個團隊負責自己的儲存庫,協作模式相對簡單。但在 monorepo 中,所有團隊共享同一個程式碼庫,這會帶來一系列挑戰:
1. 程式碼所有權與責任模糊
當所有團隊的程式碼都在同一個儲存庫中時,很容易出現「誰是這段程式碼的擁有者」的問題。有時候一個功能或模組可能涉及多個團隊的領域,導致責任邊界模糊不清。這種情況下,當出現問題時,可能沒有特定團隊願意承擔修復責任,或者多個團隊可能同時修改相同的程式碼區域。
2. 程式碼審查壓力大
在大型 monorepo 中,每天可能有數十甚至上百個 Pull Request 需要審查。這不僅增加了團隊負擔,也可能導致程式碼審查品質下降。特別是當一個 PR 涉及多個團隊的專業領域時,找到合適的審查者變得更加困難。
3. 分支管理與合併衝突
多個團隊同時開發時,分支管理變得複雜,合併衝突的頻率也會增加,尤其是當多個團隊修改共享元件或核心程式碼時。這些衝突不僅耗費開發時間去解決,還可能導致整合問題和更嚴重的技術債。
4. 建置和測試的效能問題
當專案規模越來越大,完整的建置和測試時間會越來越長,這會影響團隊的開發效率。如果沒有良好的增量建置和測試策略,每次小改動都可能觸發整個系統的重新建置和測試,大大延長了回饋循環。
團隊協作的最佳實踐
基於多年在大型 monorepo 專案中的經驗,以下是一些經過實戰檢驗的最佳實踐:
程式碼審查流程
CODEOWNERS 機制

在 GitHub 和 GitLab 等平台上,我們可以利用 CODEOWNERS 檔案清晰地定義程式碼的所有權。這是一個非常實用的功能,它不僅可以明確每段程式碼的擁有權,還能自動將 PR 分配給相應的擁有者,有效減少了手動指派審查者的時間。
以下是一個實際的 CODEOWNERS 範例:
# 全域預設擁有者
* @org/core-team
# 前端團隊負責的區域
/apps/web/ @org/frontend-team
/libs/ui/ @org/ui-team
/libs/shared/ @org/shared-team
# 後端團隊負責的區域
/apps/api/ @org/backend-team
/libs/data-access/ @org/data-team
# 特殊檔案的擁有者
package.json @org/devops-team
nx.json @org/devops-team
.github/ @org/infra-team
這種方式可以:
- 明確每段程式碼的擁有權
- 自動通知相關團隊進行程式碼審查
- 防止未經授權的修改
- 提高程式碼品質,確保專業團隊審查相應區域
- 減少手動分配審查者的管理負擔
程式碼所有權與團隊結構
團隊結構與 Nx Workspace 結構對應
在我們的實務中,我們根據領域驅動設計 (DDD) 的概念將團隊和程式碼結構對齊。每個團隊負責一個或多個業務領域,例如:
- 產品團隊:負責使用者面對的產品功能
- 平台團隊:負責底層平台和共享基礎設施
- 體驗團隊:負責 UI 元件和使用者體驗
- 資料團隊:負責資料處理和分析
我們的 Nx workspace 結構也相應地組織:
my-workspace/
├── apps/
│ ├── product-a/
│ ├── product-b/
│ └── admin/
├── libs/
│ ├── product/
│ │ ├── feature-a/
│ │ └── feature-b/
│ ├── platform/
│ │ ├── core/
│ │ └── utils/
│ ├── experience/
│ │ ├── ui/
│ │ └── design-system/
│ └── data/
│ ├── models/
│ └── services/
這種結構使每個團隊都能在自己的領域內自主工作,同時透過共享 libs 實現程式碼重用。
複雜 PR 的審查者選擇
除了利用 CODEOWNERS 自動分配外,對於複雜的 PR,我們也會依循以下原則手動選擇額外的審查者:
- 選擇熟悉相關程式碼的人員
- 確保至少有一位具有該領域專業知識的成員
- 考慮團隊成員的工作負載,避免同一人同時審查太多 PR
程式碼審查分級制度
我們實施了一個基於變更範圍和風險的分級審查制度:
- 小型變更(如文案修改、簡單 bug 修復):只需一位團隊成員審查
- 中型變更(如新功能、重構):需要相關模組的擁有者審查
- 高風險變更(如核心架構修改、跨多個團隊的變更):需要資深工程師和架構師審查,並可能需要進行系統設計評審
這種分級制度確保了程式碼審查的效率和品質,讓重要的變更得到足夠的重視,同時避免小改動被拖延。
定時程式碼審查會議
每個團隊每週安排固定的程式碼審查會議,處理積壓的或複雜的 PR。這不僅加速了審查流程,還提供了知識分享的機會。會議遵循以下形式:
- 開發者簡要介紹 PR 的目的和實現方式(5分鐘)
- 團隊集體審查關鍵部分(10-15分鐘)
- 解決任何疑問和討論潛在問題(10分鐘)
- 制定清晰的後續步驟
這種做法特別適合處理跨團隊的複雜 PR,能加快審查過程並避免來回溝通的延遲。
分支策略與衝突管理
基於 trunk-based 開發的適應性策略
在我們的經驗中,嚴格的 trunk-based 開發模式在大型 monorepo 中效果最好,但需要一些調整:
- 主分支保護:main 分支必須受到保護,所有程式碼必須透過 PR 合併
- 短生命週期的功能分支:鼓勵小型、頻繁的提交,功能分支存活時間不超過 2-3 天
- 頻繁同步主分支:每天至少一次從主分支同步到功能分支,減少合併衝突
以下是我們實際使用的 git workflow:
# 建立功能分支
git checkout -b feature/user-profile
# 進行開發,頻繁提交
git add .
git commit -m "feat: add user profile avatar component"
# 每天同步主分支
git fetch origin main
git rebase origin/main
# 推送到遠端
git push origin feature/user-profile -f # 因為 rebase 後需要強制推送
# 建立 PR 後,可能需要再次同步主分支
git checkout main
git pull
git checkout feature/user-profile
git rebase main
git push origin feature/user-profile -f
這種方法可以:
- 減少長期分支造成的合併困難
- 鼓勵更小、更容易審查的修改
- 保持主分支的穩定性
- 降低整合問題的風險
建置和測試優化
使用 Nx 的分散式快取
Nx 提供了強大的分散式快取功能,可以大幅提升建置和測試速度。在我們的專案中,使用 Nx Cloud 後,CI 時間減少了 70%。
// nx.json
{
"tasksRunnerOptions": {
"default": {
"runner": "@nrwl/nx-cloud",
"options": {
"cacheableOperations": ["build", "test", "lint", "e2e"],
"accessToken": "your-nx-cloud-token"
}
}
}
}
如我們在第八篇文章中討論的,也可以使用 S3 作為快取後端來替代 Nx Cloud:
// nx.json
{
"tasksRunnerOptions": {
"default": {
"runner": "@pellegrims/nx-remotecache-s3",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"],
"s3Options": {
"region": "ap-northeast-1",
"bucketName": "your-nx-cache-bucket"
}
}
}
}
}
這種快取機制對多團隊協作特別有價值:
- 團隊不會重複執行已經由其他團隊完成的任務
- 從一個 PR 獲得的快取結果可以用於其他 PR
- 大大減少了等待時間,提高開發效率
影響分析與智能測試
Nx 的影響分析功能可以幫助我們只運行受影響的測試,這在大型團隊中尤為重要:
# 只運行受當前變更影響的測試
nx affected:test
# 只建置受影響的應用程式
nx affected:build
# 自動化 CI 腳本
echo "Running tests for affected projects"
nx affected:test --configuration=ci
在我們的實務中,這使得平均 CI 運行時間從 45 分鐘減少到 8 分鐘,極大提高了開發效率。具體是透過:
- 只測試受影響的程式碼,而不是整個程式碼庫
- 利用 Nx 的相依圖來精確確定哪些測試需要運行
- 平行執行測試以進一步節省時間
協作工具與流程
共享元件庫管理
在多團隊協作中,共享元件的管理尤為重要。我們建立了一套完整的流程:
共享元件開發流程
- 提案階段:任何新的共享元件首先需要提交提案,包含用例、API 設計和技術細節
- 審查階段:由架構委員會審查提案,確保與現有系統的一致性
- 開發階段:由提案團隊或平台團隊開發,必須包含完整文件和測試
- 試用階段:在有限範圍內試用,收集回饋
- 正式發布:完成試用後,正式發布並通知所有團隊
這個流程確保了我們的共享元件高品質且適合實際需求,同時避免了重複開發。
使用 Storybook 作為元件展示平台
我們使用 Storybook 作為所有共享元件的展示平台,這不僅方便了開發者了解可用元件,也成為了溝通的橋樑:
// libs/ui/buttons/src/lib/primary-button.stories.tsx
import { Meta, Story } from '@storybook/react';
import { PrimaryButton, PrimaryButtonProps } from './primary-button';
export default {
title: 'UI/Buttons/PrimaryButton',
component: PrimaryButton,
argTypes: {
onClick: { action: 'clicked' },
variant: {
control: {
type: 'select',
options: ['default', 'success', 'warning', 'danger'],
},
},
},
} as Meta;
const Template: Story<PrimaryButtonProps> = (args) => <PrimaryButton {...args} />;
export const Default = Template.bind({});
Default.args = {
children: '按鈕',
variant: 'default',
};
export const Success = Template.bind({});
Success.args = {
children: '成功按鈕',
variant: 'success',
};
這個 Storybook 成為了團隊設計參考的權威來源。它提供了:
- 每個元件的即時展示
- 互動式文件,顯示 API 和用法
- 不同變體和狀態的視覺呈現
- 程式碼範例和最佳實務
衝突解決機制
即使有了良好的流程和工具,衝突仍然不可避免。以下是我們處理衝突的方式:
架構審查委員會
對於跨團隊的架構決策或衝突,我們建立了一個架構審查委員會,由各團隊的資深工程師組成。委員會負責:
- 評估重大架構變更
- 仲裁團隊間的技術分歧
- 制定共享標準和最佳實務
委員會定期開會討論提案和問題,並且對於重大決策有最終裁決權。這種集中治理模式確保了整個系統的架構一致性和技術方向的統一。
定期同步會議
每個團隊選派代表參加每週的跨團隊同步會議,會議內容包括:
- 分享各團隊當前的工作重點
- 討論可能影響其他團隊的變更
- 協調需要多團隊參與的專案
- 分享學習心得和最佳實務
這些會議通常控制在 30 分鐘以內,重點是交流資訊而不是詳細討論。會議紀錄會共享給所有團隊成員,以保持透明度。
實際案例分析
以下是一個在 monorepo 環境中多團隊協作的實際案例:
案例:跨團隊共享元件庫升級
背景
我們需要對共享 UI 元件庫進行一次重大升級,涉及到設計變更和 API 重構,影響到所有使用這些元件的產品團隊。
挑戰
- 不同產品團隊有不同的發布週期和優先級
- 某些元件在不同產品中有不同的客製化需求
- 需要確保向後相容或提供平滑遷移路徑
解決方案
協作開發新版本:
- UI 團隊負責核心元件的開發
- 各產品團隊派代表參與設計審查和API定義
- 使用 feature flags 控制新功能的啟用
漸進式發布策略:
- 首先發布 alpha 版本供早期使用者試用
- 基於回饋改進,發布 beta 版本
- 在非關鍵產品中先行應用
- 所有產品完成遷移後,發布穩定版
詳細文件和遷移指南:
- 為每個變更撰寫詳細說明
- 提供遷移步驟和範例程式碼
- 針對常見問題製作 FAQ
結果
升級過程持續了 6 個月,但最終所有團隊都順利完成了遷移。關鍵成功因素:
- 各團隊的早期參與
- 自動化工具減少了手動遷移工作
- 漸進式發布降低了風險
結論與建議
經過多年在大型 monorepo 中管理多團隊協作的經驗,我總結出以下關鍵建議:
1. 明確的治理結構
建立明確的程式碼所有權和決策流程,避免責任模糊導致的延遲和衝突。CODEOWNERS 檔案和 RFC 流程是非常實用的工具。在我們的實務中,清晰的治理結構幫助我們減少了 30% 的程式碼審查時間,並且讓團隊間的合作更加順暢。
2. 重視自動化
在多團隊協作中,自動化不僅是提高效率的工具,更是確保一致性和減少錯誤的關鍵。投資於自動化測試、CI/CD、程式碼生成和重構工具,會帶來長期收益。我們發現,自動化流程幫助我們將發布頻率提高了 2 倍,同時保持了高品質標準。
3. 溝通與透明
頻繁而有效的溝通是多團隊協作的基石。確保團隊之間的資訊流通暢,包括定期同步會議、技術分享、文件更新等。透明的決策過程和清晰的溝通管道能有效減少誤解和衝突。
4. 漸進式變更
避免大規模、一次性的變更,而是採用漸進式的方法,分階段實施,這樣可以降低風險並及早發現問題。在我們的經驗中,將大型變更分解為多個小步驟,成功率提高了 80%。
5. 建立共享知識庫
在 monorepo 中,知識共享尤為重要。建立完善的文件系統、設計決策紀錄、技術部落格等,幫助團隊成員了解整個系統。我們使用了 Storybook 和內部技術分享會等多種方式,讓知識在團隊間流通。
在多團隊協作的 monorepo 中,管理複雜度是一場持久戰。透過清晰的結構、良好的流程、有效的工具和持續的改進,我們可以將這種複雜度轉化為團隊的競爭優勢,讓多個團隊能夠在同一個程式碼庫中和諧高效地協作。
正如我們在系列前幾篇文章中所討論的,良好的 monorepo 結構設計(第三篇)、有效的循環依賴管理(第五篇)、合理的版本控制(第六篇)、優化的測試流程(第七篇)和高效的效能解決方案(第八篇)都是多團隊協作的基礎。本文作為系列的第九篇,聚焦於人與組織的協作層面,與前面的技術討論相輔相成,共同構成了 monorepo 成功的關鍵要素。
希望這篇文章能對你在 monorepo 中管理多團隊協作有所幫助。如果有任何問題或經驗想要分享,歡迎在評論區留言交流。