本文首發於公眾號:符合預期的CoyPan
寫在前面
2019年9月21號,我參加了第五屆FEDAY。在會上,聽了王澤老師的分享,我第一次接觸到了monorepo這個概念。本文是結合王澤老師的分享,自己進行一定實踐後的總結。
本文中的圖片,均來自我在團隊內部分享時的PPT截圖
Monorepo
一種項目管理方式:一個git倉庫下管理多個項目,適用於大型團隊,框架開發,庫開發等。
線上項目現狀
一看到這個概念,我立馬想起了自己所在團隊的一個repo,目錄大概長成下面這樣:
這種把所有的項目都放到一個repo下面的好處是:
-
統一技術棧
- 降低團隊成員之間的backup成本
-
提升效率
- 每一個人都可以改動任意部分的代碼,改動效果實時呈現,調試方便
- 可以在業務開發中,靈活地將代碼抽出作為公共模塊
- 省去了在多個repo情況下,給團隊新成員開通repo權限的時間
大概的repo組織結構是下面這樣的:
上圖這種repo組織方式對團隊現在的業務開發來説,完全足夠了,因為每一個頁面都還算簡單。但是如果要開發一個大型複雜項目,會有問題嘛?
大型複雜項目怎麼辦
上圖的情況在平時的開發中很常見,B項目或許根本就沒有時間、人力來回歸測試,但是A項目很着急上線,也顧不上這麼多。如果業務複雜度小,那這種情況一般不是問題。如果是大型複雜的項目,怎麼辦呢?項目A重新複製一個基礎庫a來修改嗎?
解決辦法就是:版本管理。對組件進行版本管理,託管在公司內部的組件庫裏面。
到底什麼是monorepo
微軟的定義如下:
再來看看著名的babel和React:
我自己的總結如下:
rush.js
微軟出品的,一個專門為monorepo打造的項目管理工具。https://rushjs.io。
rush.js解決了兩個重要的問題:phantom dependencies 和 doppelgangers。我們先來看看這兩個問題。
phantom dependencies
沒有在package.json裏指定安裝,卻可以在項目中被引用的依賴。
在npm3.0以後,是可以的。這是因為:npm原有的樹形結構,造成了依賴冗餘和路徑過深。npm3後開始扁平化,把原來不同級的依賴變成了同級依賴。這樣我們在項目中就能直接引用到了。
phantom dependencies的問題:
- 依賴版本混亂
- 依賴丟失
常規解決思路:制定代碼規範;使用代碼檢查工具來避免這種情況發生。但是......
doppelgangers
同一個依賴被多次安裝,導致項目臃腫,打包變慢。
rush.js的Symlink機制
Rush會將項目依賴全部都安裝在repo根目錄的common/temp下,然後提供symlink到各個項目中去引用。原本的項目中,依然會保持原有的node_modules結構。
看一個例子:
Rush保證只會在項目的node_modules中保留package.json中聲明過的依賴的Symlink。這樣,自然解決了phantom dependencies
rush會將所有的依賴都安裝在一個地方,對於不同版本的同一個依賴,rush會同時安裝所有的依賴版本,並且提供symlink供項目使用,這樣,自然就解決了doppelgangers。
另外,rush會對依賴的版本(SemVer)進行智能判斷,防止重複安裝依賴包。例如,兩個項目同時依賴了一個第三方庫,第一個項目依賴的是:^1.2.0,另一個依賴的版本號是:1.5.0。rush安裝依賴時,只會安裝1.5.0。
rush.js的簡單使用介紹
下面簡單介紹一下rush.js的使用。
- rush.json
- rush build
- rush update
- rush change
- rush publish
寫在後面
本文介紹了monorepo,同時對rush.js進行了簡單的探索。monorepo已經有很多的案例了,比如上面提到的babel,react。monorepo的管理也有很成熟的工具了,如著名的lerna。經過一些小小的研究,我對rush.js的印象是:很規範,但是對於團隊來説,上手成本真的不小。
目前我所在團隊負責的業務,並沒有適合monorepo的場景,所有也沒有對rush.js,lerna等工具進行更深入的瞭解與對比。希望有經驗的大佬能夠深入分享一下自己的體會。
參考資料:
https://rushjs.io/
https://www.zhihu.com/questio...