為什麼前端工程越來越愛使用 Monorepo 架構
Using single git repository to manage multiple apps and libraris

Monorepository (簡稱 Monorepo) 概念雖然有一段歷史了,但這個名詞卻是近幾年才變得如此熱門。自己公司也是這半年才導入這個架構,再嚐到許多甜頭後想寫一篇來介紹它,希望多一點人認識此架構。這篇並不會有程式碼,而是從現有架構痛點開始 (Single Repo Monolith、Multi-repo)、為什麼要用 Monorepo 等,若想要實際導入可以參考 nx.dev
現有架構遇到了什麼問題 ?
20 年前的前端相當單純,但在這 6 ~7 年卻產生巨變,現在應該沒幾個人只用純 html/css/js 做出網站了,大部分都是以前端框架出發搭配一大堆的 dependencies (SCSS preprocessors、task managers、npm、typescript…) 。當團隊發展到一定規模又會分出好幾個不同產品,每一個產品使用的 dependencies 都不大相同使得維護變得困難,到底要怎麼做到避免重覆程式碼以及分好責任歸屬 呢?直接用實際例子會清楚許多
若 shop.com 公司今天有數個專案,每一個專案都有不同負責的團隊
購物網站 shop.com (React)
結帳 shop.com/cart購物網站手機版 m.shop.com (不是 RWD,是獨立網站)
後台 admin.shop.com (Vue)
分析使用者網站 analytics.shop.com (Angular)Note. 雖然不同專案你可以選擇用不同前端框架,但若都用同一種會看到 monorepo 的更大好處。

shop.com 跟 shop.com/cart 雖然是在一個 domain 底下,但負責的卻是完全不同的團隊

在這種複雜的架構下,我們比較熟悉的方法為 Monolith 跟 Multi repo [延伸閱讀: 初探 Micro Frontends 程式架構]
Single-repo Monolith 😰

最開始大家都是使用這種架構開發的,但隨著前端工程日益複雜,前端需要做的事越來越多、更多 dependencies 被引入,在 Single-repo Monolith 架構下整包會變超級肥大,部署時也必需要整包一起,想當然爾 deploy 時間都爆久,這樣的架構缺點很明顯,也無法達到高擴充性與高效率的組織開發。
Single-repo Monolith
apps
├ node_modules
├ libs // 放 share 的東西
├ design-systems
| ├ node_modules
| ├ xx...
├ shop
| ├ node_modules
| ├ cart
| | ├ xx...
| ├ xx...
├ shop-mobile
| ├ node_modules
| ├ xx...
├ admin
| ├ node_modules
| ├ xx...
├ analytics
| ├ node_modules
| ├ xx...
├ e2e
| ├ xx...Multi repo 😢

現在大部分的前端會採用 Multi repo,每一個獨立案子都會有相對應 repo,團隊各自維護自己 product,釐清責任也很容易
Design-systems Repository
design-systems
├ node_modules
├ e2e
├ xxxx
Shop Repository
shop
| ├ node_modules
| ├ e2e
| ├ xx...
Shop Cart Repository: Cart 因為隸屬另一個團隊所以會拆分成兩個 Repository
shop-cart
| ├ node_modules
| ├ e2e
| ├ xx...
Mobile Version Repository
shop-mobile
| ├ node_modules
| ├ e2e
| ├ xx...
Admin Repository
admin
| ├ node_modules
| ├ e2e
| ├ xx...
Analytics Repository
analytics
| ├ node_modules
| ├ e2e
| ├ xx...看似不錯,但問題又來了
重覆配置 Multi repo 因為每一個 repo 都是獨立的,所以必須建自己的 webpack、開發環境、如何 deploy 等等,若十個 repo 就要維護這 10 個配置,若 repo 之間都不一致,那管理很麻煩
共用程式碼維護成本變很高 projects 間許多邏輯是重覆的,但因為不同 repo,所以在 debug 時就要一次修五份,維護耗時耗力成本相當高。你可能會想那把會重覆用到的東西另外拉出來單獨創一個 libs Repository,直接改 libs 得東西即可,那流程就會變成改
- libs Repository,version 從 1.0 到 1.1 2.
- shop、shop-mobile、admin、analytic 安裝最新的 libs 1.1
commit變動,再push更新個自 repo,等待 deploy
這也是 Multi repo 最常被抱怨的事,因為 Repo 被切得太清楚,導致只是 share code 小改動流程也超複雜,所花時間也相對變很高
dependencies 的版本管理變異常複雜 每個 team 用的 dependencies 有些相同有些不同,例如 design-system 用了 react 17.0.2 而 shop 還在 15.6,若新版本捨棄某些支援,就會產生 bug。或是因為沒有及時 pull 最新的 libs Repo 所以更新不及時而產生 bug。
Mono repo 😊

Mono repo 可以解決上面 Multi repo 的痛點,由於只有一個 Repo 所以管理起來很方便,一個 webpack 、一個 test suite runner 、共用 dependency 若有變動,那有用到此 dependency 的 project 都會知道,並且因為只有個 repo 所以大家都是使用最新的 code 不會用更新不及時的狀況




