Monorepo 和 Polyrepo 從把妹角度理解前後端如何和平相處

me
林彥成
2022-10-03 | 4 min.
文章目錄
  1. 1. Polyrepo
    1. 1.1. Polyrepo 專案架構與問題
  2. 2. Monorepo
    1. 2.1. Monorepo 專案架構與問題
    2. 2.2. Nx

在版本控制系統中 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 前後端各自開工,當需要整合測試的時候就會需要

  1. 確認前後端目前是在哪個分支
  2. 確認前、後端各自跑起來的方法
  3. 確認如何把不同的分支整合對接

共用元件的開發與測試流程較多手工且繁雜的部分

UI 共用元件通常會把元件封裝成 package 或透過 git 的 URL 來 npm install

開發階段測試流程,維護共同相關 dependencies 成本較高

  1. npm run build 將元件建置
  2. 將目標專案 node_module 的 lib 改成新建置版本
  3. 在目標專案中實際測試
  4. 回到 UI 元件專案進行版號更動及 Change Log 撰寫
  5. 發布新版本
  6. 在目標專案中重新 npm install 新版

Polyrepo CI/CD 每次進版或退版較複雜

Polyrepo CI/CD 在做用戶端 APP 會很常區分 dev、uat、production 環境並以三或多個 branch 做區分。

舉小編前公司的案例來說,除了公版的功能外,剩下每個客戶因為有相對應的客製化,若無法用 config 解決就會另外開新分支維護,這樣的情況下如果需要更新 UAT 的版本,就要在各個 Repository 做重複 N 次的操作,如果今天 CI/CD 流程因應公司政策有修改也需要在 N 個地方配合修正。

  1. 將 Dev 的程式碼發 PR 到 UAT
  2. 確認 UAT 的 CI 測試有過且包版成功
  3. 請 PM 跟維運協助上到公司內部 UAT 環境
  4. 請 QC 協助測試
  5. 請 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 架構,並內建支援

  1. React、Vue、Angular 三大框架專案設定
  2. Express、Nest、Next 後端專案設定
  3. cypress、jest 測試相關設定

Nx 在不使用任何外掛的情況下也可以方便地去使用,雖然主要以 JavaScript 生態系為主但因為可以使用外掛擴充,其實可以發現社群對於其他語言也有相關的支援,像是常見的 nx-spring-boot

Nx 的專案架構如下

  • apps: 存放各專案
  • libs: 共用的部分
  • tools: 腳本
  • workspace.json: 專案列表
  • nx.json: 專案該如何執行
1
2
3
4
5
6
7
8
NxProject/
├── apps/
├── libs/
├── tools/
├── workspace.json
├── nx.json
├── package.json
└── tsconfig.base.json

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: 透過互動式介面了解專案相依性

喜歡這篇文章,請幫忙拍拍手喔 🤣


share