在版本控制系統中 Monorepo 和 Polyrepo 分別是兩種用來管理模組化程式碼的軟體開發策略。
以男女之間來說,就像是金錢是要分開管理 (Poly) 或是一起管理 (Mono),即使一起管理是單純全部丟在一起 (Monolith) 還是有做簡單的分類 (Monorepo) 像是個人花費和公共花費等等。
👉 小編點評: 該分開就早點分開,這個道理在哪似乎都適用
接下來這篇文章以前後端分離的 Web 開發為例來分析 Monorepo 和 Polyrepo,另外 Monolith 可以看成缺少規劃的 Monorepo 原則上是將讓專案可運行的相關程式全部放一起,常在專案初期 POC 使用,這個名詞基本不用管。
圖片來源: https://codefresh.io/blog/using-codefresh-with-mono-repos/
Polyrepo
Polyrepo 則是把前端與後端分為兩個不同的 Repository,目前絕大多數專案的管理方式
把不同功能的專案分成不同的 Repository 管理
- 權限: 因為是不同 Repo 可以按照 Repo 設定權限
- 專案管理: 比較難看到系統全貌,但易於切割責任歸屬
- CI/CD: 方便擴展且 DevOps 相關工具較齊全
- Hotfix: 需要透過 PR 修改所有相關的程式
- 重構: 有相依性的專案之間重構需要切換,改動時不易確認影響範圍
- 套件版本管理: 多個專案需要分開管理
Polyrepo 專案架構與問題
功能開發階段,前後端溝通成本較難下降?!
Polyrepo 前後端各自開工,當需要整合測試的時候就會需要
- 確認前後端目前是在哪個分支
- 確認前、後端各自跑起來的方法
- 確認如何把不同的分支整合對接
共用元件的開發與測試流程較多手工且繁雜的部分
UI 共用元件通常會把元件封裝成 package 或透過 git 的 URL 來 npm install
開發階段測試流程,維護共同相關 dependencies 成本較高
- npm run build 將元件建置
- 將目標專案 node_module 的 lib 改成新建置版本
- 在目標專案中實際測試
- 回到 UI 元件專案進行版號更動及 Change Log 撰寫
- 發布新版本
- 在目標專案中重新 npm install 新版
Polyrepo CI/CD 每次進版或退版較複雜
Polyrepo CI/CD 在做用戶端 APP 會很常區分 dev、uat、production 環境並以三或多個 branch 做區分。
舉小編前公司的案例來說,除了公版的功能外,剩下每個客戶因為有相對應的客製化,若無法用 config 解決就會另外開新分支維護,這樣的情況下如果需要更新 UAT 的版本,就要在各個 Repository 做重複 N 次的操作,如果今天 CI/CD 流程因應公司政策有修改也需要在 N 個地方配合修正。
- 將 Dev 的程式碼發 PR 到 UAT
- 確認 UAT 的 CI 測試有過且包版成功
- 請 PM 跟維運協助上到公司內部 UAT 環境
- 請 QC 協助測試
- 請 PM 協助上到對方 UAT 環境進行測試
Monorepo
Monorepo 是把前端與後端的原始碼都放在同個 Repository,是軟體開發過程中,使用一個 Repository 開發多個模組或專案的方式。
Facebook 的 React 其實就是 Monorepo。
將相關程式碼依照特定的邏輯,包含前後端放在同個 Repository
- 權限: 權限只有一種
- 專案管理: 方便不懂架構的人發 Issue
- CI/CD: 流程或是架構配置統一管理,統一退版較容易
- Hotfix: 可透過原子化提交直接修改所有相關的程式
- 重構: 原始碼都很近方便大規模的重構,改動時易於確認影響範圍
- 套件版本管理: 集中管理,若遇到套件資安漏洞也能統一升級
以小編前公司的經驗來說,覺得 monorepo 的概念就蠻適合部門內整合各模組的專案架構。
因為只有一個 Repo 所以權限也只有一種,不過理論上同部門也不需要過於詳細的權限控制。
雖然當專案過大的時候 git 操作會變慢,可以指定 clone 深度來解決。
npm 沒辦法用 install github url 的方式安裝模組,有個招式是可以開個 Branch 專門放 build 過的結果,但繁雜程度可能跟 Polyrepo 差不多。
Monorepo 專案架構與問題
統一的設定及專案技術選型
- 初期需多點時間設定專案,Config、Library、Tech stack 會統一
- CI/CD 流程需要考慮更多情境
- 可以立即知道修改程式碼後,相關專案是否正常運作
- 開發一次元件,就能給各專案使用
- 在專案之間檢視程式碼時,可以省下切換時間
Nx
Nx 是使用 TypeScript 撰寫的 Monorepo 專案建置工具,官網介紹是
Smart, Fast, Extensible Build System
主要協助建構與整合 Monorepo 架構,並內建支援
- React、Vue、Angular 三大框架專案設定
- Express、Nest、Next 後端專案設定
- cypress、jest 測試相關設定
Nx 在不使用任何外掛的情況下也可以方便地去使用,雖然主要以 JavaScript 生態系為主但因為可以使用外掛擴充,其實可以發現社群對於其他語言也有相關的支援,像是常見的 nx-spring-boot。
Nx 的專案架構如下
- apps: 存放各專案
- libs: 共用的部分
- tools: 腳本
- workspace.json: 專案列表
- nx.json: 專案該如何執行
1 | NxProject/ |
Demo Repo:
https://github.com/LinYenCheng/monorepo-demo
另外因為 Nx 功能蠻多的若是使用 VS Code 開發,建議安裝 Nx 擴充套件,就不必將指令記起來,舉三個常用的例子
npx nx print-affected
: 找出這次改動被影響需要修改跟重新 build 跟 test 的專案npx nx run-many -target=serve --project=api, demo
: 一次執行多個專案像是同時把前後端跑起來npx nx graph
: 透過互動式介面了解專案相依性
喜歡這篇文章,請幫忙拍拍手喔 🤣