赞
踩
导语
本方案不仅适用于运营活动,模板工程等,实际应用非常广泛,可以应用到任何一个项目中。任何一个独立的模块都可作为子工程分出去,来减少工程源码量、大工程的模块分离、同类项目统一管理等。本篇文章只提供一些思路,细节方面可以根据自己项目情况进行配置及架构设计。
背景
在开发过程中,通常会遇到这样类似的问题,比如各种各样的模板项目,各种运营活动。这些项目很小,又会随着业务的发展越来越多,项目结构相类似,功能类似,略有些差异。虽然我们能够用脚手架,组件化等方式来统一和规范性开发,但在源码管理方面,依然无法解决我们的痛点。
举个例子:比方说运营活动,项目基本每周两个这样的频率,半年就要50个,这类项目,如果每个项目都是独立的git库,那这些项目将无法统一管理,更新资源及组件必须到某个项目下进行操作,发布时也只能一个个单独部署。如果将这些项目放到一个git库中,虽然可以进行公共资源统一更新,及配置多项目发布,但随着业务增长,源码库代码量会越来越大,高达几个G,项目拉取,开发压力较大,并且容易手误导致代码污染及公共资源误修改,影响了其他关联项目的情况。
那么,如何来解决这类增量项目源码的管理问题呢?
本篇文章主要是这类问题的一些解决思路,分析了常规方案的一些不足之处,设想了理想状态的源码管理方式。并按照预想,逐步实践,配合脚本工具,简化操作及管理流程,降低操作成本。因为我们是基于umi框架之下的项目,文章也会涉及一些改造umi工程时的问题点与处理方式。当然,我们的架构设计不仅仅局限与umi,任何技术栈都可以,这里只是提供一些思路,供大家参考。
常见源码管理方案
对于此类项目。在源码管理中,通常会有如下几种方案
(1)多git管理 :各个项目都是独立的一个git项目。新项目通常通过老项目copy而来,改改配置,删删文件。 (2)单git管理 :在一个git项目中维护,以项目名来区分不同的项目。项目作为此git工程的一个模块,所有项目共用一套配置和资源。 (3)其他工程化代码原理方案:例如脚手架工具,lerna, monorepo等存在问题
对比这几种方案,各自都有各自的问题,都不完美,并且,我们这里强调的是项目源码,并且是业务项目源码的统一管理及独立开发问题。
说明:对于项目的公共模块,可以自主开发,也可以通过npm方式引用,不做限制,我们讨论的重点的项目工程源码的管理。
目标方案
我们的理想状态是项目即能采取单git 代码共享及统一管理的优势,又拥有多git开发,项目间独立与隔离,还能具备脚手架一样的自动化应用。项目管理员来维护基础环境、公共资源,及管理子项目。开发者在基础环境中,开发自己的子项目就好了。对于每一个开发人员,只能看到自己负责的项目或正在开发中的项目。通过传入项目名参数,来进行单项目打包构建。
看到子项目这几个字,很多人会想到用git submodule来进行管理,我们的核心思路也是git submodule,但跟常规的使用方式不同,在主工程,子工程划分及最终应用上采取了逆向思维。
问题:谁是主工程,谁是子工程,如何使用?
通常的思路是,将公共模块分到子工程,新项目开发,将公共模块作为submodule映射引入,达到公共代码的复用,如果这样,疑问就比较多了,submodule相比npm,脚手架方式并无优势,并且,新项目依然是一个独立的git工程,无法进行多项目统一管理,也解决不了我们最初的问题。
逆向思维:如果我们把项目功能模块分出去,作为子工程,主工程中是一些基础配置和公共模块呢?
子项目作为submodule映射引入到主工程,在主工程中便可以进行全量项目统一管理。但子工程如何使用?子工程独立,没有运营环境怎么办?
当然,确实存在这样的问题,项目只能在主工程中跑起来,对与任何人来说,都只能在主工程中开发。但git 的强大也就在这里,我们可以通过权限,来控制不同使用者可否更新子项目,可否提交代码的能力。管理员可以初始化及更新公共项目及所有子项目权限,而开发者选择行初始化及更新子项目,只可提交子项目。这样想想,似乎可以实现最初的预想。
按照这样的思路,我们进行了任务拆解,并进行实践
任务拆解
* 划分工程,隔离出基础工程与子模块工程,支持子模块独立开发,独立构建功能。
* 分离子模块工程,并组合主工程,组合子模块工程
* 搭配脚本工具,简化操作流程
* 实践及应用
1. 划分工程,隔离出基础工程与子模块工程,支持子模块独立开发,独立构建功能。
因为我们的项目工程是基于umi架构下的项目工程。Umi是一个开源可插拔企业级react框架,通过cli工具,可生成标准工程,基础配置,打包部署流程等均已提供。基于此框架,我们只需要做一些调整,来匹配我们的目标目录。
umi 以约定大于配置著称,但正是这样,暴露的配置项越少,对我们拆分工程的难度越大,如mock ,router,及单独构建的等,都需要进行处理。
我们进行了umi基础项目的改造,重新组织了项目结构,划分清楚哪些是主项目配置及模块,哪些是子项目配置。
项目结构如下:
在改造项目的过程中,发现umi 的mock 约定目录不能更改,于是采用读取子项目中mock配置的方式进行动态配置。支持同时运行多个项目。
获取子项目配置,通过命令参数获取项目名,拼出资源路径,MOCK,ROUTER, OUTPUTPATH配置均如此,参考代码如下:
1. const projectName = process.argv[3]; 2. const url = '../src/pages/'+projectName+'/mock/index'; 3. var mockData = require(url); 4. export default mockData.mock;
umi只能构建router中配置的页面,但不能分项目名打包。多项目构建是一个刚需需求,好在OUTPUTPATH可以配置顶层目录。多项目构建,变成了遍历项目名进行多次执行,全量构建就是遍历pages文件下所有的项目名,再进行构建。
1. #!/bin/bash 2. buildAll(){ 3. path="$PWD"'/src/pages' 4. dir=$(ls $path) 5. for i in $dir 6. do 7. npm run buildpro $i 8. done 9. } 10. 11. if [ "$@" = "all" ];then 12. echo 'start build all project ......'; 13. buildAll 14. else 15. for arg in $@ 16. do 17. npm run buildpro $arg 18. done 19. fi
2. 分离子模块工程,并组合主工程,组合子工程模块
如前所述,开发者只能在主工程下进行开发及运行,通过权限控制代码是否可提交,来保证公共代码保护。并通过需求,选择性初始化及更新子工程代码,来保证开发者见隔离性。管理员全量更新子工程,来达到对项目代码的统一管理。
这种思路类似于组合模式。
管理员 :主工程基础环境 + 子工程1 + 子工程2 + …… 开发者 :主工程基础环境 + 子工程X3. 搭配脚本工具,简化操作流程
为了方便整个流程的操作,提升效率,我们写了一些shell脚本,以自动化方式来简化整个操作流程。并屏蔽gitsubmodule的使用上的差异。我们在项目中建立了子工程模板,通过命令,快速生成统一结构的子项目。并按照terminal交互提示,快速提交到远程仓库及关联为submodule。如下是一些自动化脚本,仅供参考:
CREATE 创建子工程脚本,用于创建git工程,并询问是否提交到远程,是否关联为子工程,流程如下:
后续可根据需要手动进行远程提交和关联子项目。
初始化子项目脚本,屏蔽SUBMODULE使用差异
1. …… 2. initProject(){ 3. path="$PWD" 4. cd $path'/src/pages' 5. rm -rf * 6. 7. echo '初始化项目......' 8. 9. git submodule init $pname 10. git submodule update $pname 11. 12. echo '开始安装依赖......' 13. 14. cd $path 15. npm install 16. } 17. ……
最终,使用者可以通过上述简单的命令来方便的进行工程操作,屏蔽使用上的差异
实践应用
在此架构下,使用者可以通过简单的几条命令,就可以开始进行开发:
1. npm run create <项目名> 2. npm run build all 3. npm run initProject <项目名1> <项目名2> 4. npm run dev <项目名1> 5. npm run build <项目名1> <项目名2> 6. ......
我们对公司中的项目需求进行了整理和分析,陆续将一些项目迁移到此架构中,来对多项目进行统一管理,提升项目的可维护性。
应用场景:
本方案不仅仅适用于运营活动,模板工程等,实际应用非常广泛,可以应用到任何一个项目中,任何一个独立的模块都可作为子工程分出去,来减少工程源码量,大工程的模块分离,同类项目统一管理等,本篇文章只提供一些思路,细节方面可以根据自己项目情况进行配置及架构设计。
总结展望与规划
如我们所愿,实现了多项目的管理方案,并配合自动化脚本,简化操作流程,提升开发效率。此架构方案也可以作为微服务架构的基础。
好的工具可以帮助我们更好的处理某些场景应用。探索与实践的过程中会遇到很多意向不到的问题,复杂的问题可以进行拆解,逐步攻克,目标很重要,只要目标准确,就会想到解决的办法。
参考文献
1. https://umijs.org/
2. https://git-scm.com/docs/git-submodule
作者简介
高莹 / 58集团信息安全部算法工程组前端负责人,主要负责项目架构设计,基础工具及工程开发,前端前沿技术调研及应用等。
live
沙龙活动直播
2020年58技术沙龙活动在线直播第一弹——《大数据平台建设实践与探讨》系列第二期已准备就绪,欢迎你强势围观!
详情?请戳?图片查看,3月1日本周日19:00,我们不见不散。
END
阅读推荐
1.标签会说话?揭秘58本地服务标签挖掘实践
2.埋点治理:如何把App埋点做到极致?
3.独家|React Native 无限列表的优化与实践
4.小程序时代:如何跨多小程序开发协作?
5.如何避免重复造轮子,打造一个属于自己的组件库?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。