最近工做中遇到了一個問題:隨着項目愈來愈多,不少項目依賴同一個模板或是配置文件想同一管理,又不想分開維護,因此只能互相引用,或是各自維護,致使了後續的不少麻煩。前端
場景一: 不少公司手機端和pc同時開發,引用同一套模板,或者通用的組件庫。node
場景二: 用gulp、webpack來打包,或是用node來開發會有一些通用的配置文件須要統一管理。webpack
這個是咱們最初使用的方法,好比有兩個項目projectA和projectB,B項目依賴A項目中的一套模板,會遇到幾個問題:git
開發中咱們引用模塊的時候,B項目要通過很長的路徑引用才能引到A項目中的模板,這要求全部開發者本地文件路徑保持高度一致。web
使用webpack打包壓縮靜態文件的時候,A、B兩個項目必須在同一個git分支,很容易搞亂。json
修改完文件不能及時看到效果,還要手動同步一次。這點是開發中最致命的問題,作前端的都會有體會若是改了一個樣式或是一個模板要經過一個很長的操做路徑才能看到效果,是很是影響開發效率的。gulp
在用了幾個月以後,各類問題暴露出來,咱們必須找新的辦法。segmentfault
網上調研了不少方法,例如git submodule,第二階段最終選擇了subtree,一是官網已經再也不推薦使用submodule了,二是subtree實在是太方便易用了。(後來和同事商量了下發現submodule仍是有使用價值的,在第三階段中咱們再分析。)工具
說到subtree易用,只須要2步就能夠初始化好一個子項目:post
語法:git remote add -f <子倉庫名> <子倉庫地址>
實例:git remote add -f component git@xxx.git
驗證:git remote -v
能夠看到已經你添加成功了一個新的遠程倉庫叫 component
語法:git subtree add --prefix=<子目錄名> <子倉庫名> <分支> --squash
實例:git subtree add --prefix=component component master --squash
這時候會在本地新建一個叫component的文件夾,--squash
會把subtree上的改動合併成一次commit
pull:git subtree pull --prefix=component component master --squash
push:git subtree push --prefix=component component master --squash
注意:必須在component的父級目錄執行,使用起來還不是很方便。
能夠在package.json裏面加script語句來執行,這樣在每一個文件夾下均可以pull & push,強制統一,避免出錯。
若是是引用多個子項目,會形成當前項目過於臃腫。其實有的時候相似組件庫是不須要上線的,只在開發環境引用就行了。
添加:git submodule add
添加後會在當前目錄下生成一個.gitmodules的新文件,裏面會記錄submodule的引用信息,在當前項目的位置以及倉庫的url。
git submodule foreach git pull
這樣能夠更新全部子模塊。
這裏只介紹了最基本的submodule用法,實際在多個項目中更新和修改submodule仍是不少坑的,能夠參考這篇文章 Git Submodule的坑。 因此咱們規定在項目中只能pull子模塊,修改的話只能到子模塊中去push。 這樣避免了多人修改形成的衝突。
在新員工加入團隊時:一次性clone項目,submodule能夠一塊兒clone出來,只需添加--recursive遞歸參數就能夠了,而subtree並不行,只能手動添加,不過能夠藉助神器Yeoman(一個自動生成項目腳手架的工具)來實現。
subtree適合像配置文件這種須要跟着項目走的狀況。
submodule適合在開發階段時引用,到了生產環境會被打包到指定文件內,而自己並不用跟着版本走的狀況。