前言
隨着功能和業務量級的飆升,前端代碼量級也越來越大,管理運維的成本也進一步增加。
代碼倉庫的運營管理挑戰也浮出水面。
主流方案有兩種:一是multirepo式的分散式的獨立倉庫,二是monorepo式的集中管理,各有千秋,下面就結合實際場景一起深入了解下。
分散式管理:multirepo
即按照功能或者其他維度,將項目拆分為不同模塊單獨維護於各自倉庫中。
使用場景
對於敏捷迭代快速開發的新需求,常規做法就是每個模塊對應一個倉庫,新的需求進行歸類,可歸入已有倉庫則進行迭代,不滿足則新建倉庫。
優勢
1.靈活
不同模塊獨立維護,與其他模塊天然隔離。各個模塊可以選擇適合自己的風格、工具等。
2.安全
得益於模塊的拆分,權限控制較為自然。
開發時只關注相關部分,不會誤操作其他內容。
發布上線,對其他模塊無感知。
問題
作為傳統的管理組織方式,發展演進這么久,必然會存在一些限制。突出體現在協作和管理成本上。
1. 管理成本
常見的項目交接時,每個人都負責了一堆項目、賬號等,只能手動梳理,還存在漏掉的可能。我當初經歷過幾次大的調整,交接的真是一臉懵逼和心痛。來個需求才發現還有個倉庫一直處於遺忘的角落。
2. 協作成本
涉及多個項目開發時,本地開發需要打開多個IDE在其中切換。
對於本地調試等也是個繁瑣的過程,雖然存在npm link等方式。
3. 依賴升級
這種場景一般出現在依賴的核心模塊上,特別是自行開發的基礎依賴,不得不升級時簡直一言難盡,數目直逼上百的項目,每個都要修改發布一次。
上面說的是業務模塊,對於開源或者公司內部基礎性工具,升級這里的問題更顯著一些。對於程序員倆說,出現問題解決問題就是,因此集中式的管理模式就出現了。
集中式管理:monorepo
monorepo 的核心觀點是所有的項目在一個代碼倉庫中。嚴格的統一和收歸,以利於統一的升級和管理。
不過這並不是說代碼沒有組織的隨意存放。相反,在文件目錄上體現出管理結構的要求更高,否則可維護性更低。
例如Babel,每個模塊都在指定的packages目錄下。
優勢
既然是基於問題的演進,其實優勢比較明顯,就是multirepo的局限的解決。
例如協作、運營管理等成本降低。
不過monorepo也不全是益處,相反其局限也比較明顯。
問題
1. 項目體積增加
隨着項目的發展,體積會逐漸增大,甚至成為巨無霸項目體積幾個G。
自然帶來一些問題:
-
獲取時間變長
拿babel舉個例子,雖然只有130M,但時間已經增加不少,更遑論上G的存在。
http://xxdy.tech/img/mono.gif[動圖太大,始終上傳不成功,只能放個鏈接了。。。] -
編譯耗時增加
很自然,如果每次還是全部編譯的話,開發、部署時的等待時間會相當的長
2. 安全性
全部功能就這樣暴露在所有開發者面前,安全性是個大問題。
誤操作的可能性,如果僅僅寄希望於開發者素質和codereview時的人工復檢是不可靠的。
解決方案
當然對於比較成熟的模式,解決方案也是形成了沉淀的。
1. 多模塊管理工具
針對復雜的項目模塊,自然需要有貼合實際的管理工具。
例如lerna,自我定位就是:
A tool for managing JavaScript projects with multiple packages
至於詳細用法,大家可以通過官網查看。
2. git稀疏檢出
針對開發者只關注相應內容的解決方案可以依托git來實現的。
Git在1.7版本后,已經支持只Checkout部分內容,即稀疏檢出(sparse checkout)
稀疏檢出就是本地版本庫檢出時不檢出全部,只將指定的文件從本地版本庫檢出到工作區,而其他未指定的文件則不予檢出(即使這些文件存在於工作區,其修改也會被忽略)。
也就是我們可以在工作區只關注相關的模塊,雖然文件全部pull了下來,但展示和管理式會忽略其他文件,即使展示了其他文件並進行了修改,修改依然會被忽略。
例如babel中我們只展示 babel-cli 內容部分,操作如下:
// 創建文件夾
mkdir demo && cd demo
// 初始化git
git init
git remote add origin https://github.com/babel/babel.git
// 打開 開關
git config core.sparsecheckout true
// 指定目錄
echo "packages/babel-cli/" >> .git/info/sparse-checkout
// 獲取代碼
git pull origin master
這樣,我們ls可以查看到文件內容只有:
packages/babel-cli
如果需要修改展示目錄,直接修改.git/info/sparse-checkout,即可,然后重新進行checkout
echo "packages/babel-cli/" >> .git/info/sparse-checkout
git checkout master
這樣增加了安全性。
擴展:淺克隆
稀疏檢出只是展示上的部分,本身仍然包含所有的文件和歷史。如果只關注最近的提交,可以通過淺克隆實現。
使用:
git clone --depth 2 https://github.com/babel/babel.git
不過淺克隆限制較多,一般用於對遠程版本庫的查看和研究。
- 不能從淺克隆版本庫克隆出新的版本庫。
- 其他版本庫不能從淺克隆獲取提交。
- 其他版本庫不能推送提交到淺克隆版本庫。
- 不要從淺克隆版本庫推送提交至其他版本庫,除非確認推送的目標版本庫包含淺克隆版本庫中缺失的全部歷史提交,否則會造成目標版本庫包含不完整的提交歷史導致版本庫無法操作。
- 在淺克隆版本庫中執行合並操作時,如果所合並的提交出現在淺克隆歷史中,則可以順利合並,否則會出現大量的沖突,就好像和無關的歷史進行合並一樣。
結束語
本文簡單介紹了不同的倉庫管理模式理念和一些實踐方式,個人理解有限,拋磚引玉,歡迎一起討論。更多內容請轉雨打梨夢三村邊。