最近工做中遇到了一个问题:随着项目愈来愈多,不少项目依赖同一个模板或是配置文件想同一管理,又不想分开维护,因此只能互相引用,或是各自维护,致使了后续的不少麻烦。前端
场景一: 不少公司手机端和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适合在开发阶段时引用,到了生产环境会被打包到指定文件内,而自己并不用跟着版本走的状况。