基于Git子模块的微前端项目管理和公用组件库方案
基于Git子模块的微前端项目管理方案
1. 媒体项目从单一项目到多项目的转变及问题
随着前端媒体业务的急剧扩大,传统的单体应用已经变得难以维护,由此,这几年我们一直在探索对大型复杂项目的拆分工作。
一开始拆分出去的是策划中心,老的媒体项目主体是AngularJS编写的,而拆分出去的策划中心模块则采用 VueJS 编写,限于框架之间的巨大差异,难以优雅地集成在一起,就使用了 Iframe 嵌入式方案。
后来,随着配置管理模块、网络资源模逐渐使用 VueJS 重写为独立项目的工作完成,对采编模块的重写工作终于开始,未来版权资源和运营中心模块都会各自独立为一个项目。
各项目的集成工作提上了日程,经过一段时间的试验和摸索,最终使用了micro-app
库提供的微前端作为解决方案,基本实现了以采编中心为基座应用,其它模块作为子应用无缝集成的应用架构。
此时,就产生了新的问题:
- 随着所有模块都转而使用 VueJS 开发,而各个模块都属于典型的中后台项目,所以就会在各个模块产生很多相同UI、相同功能的组件,各个模块都要维护相同的组件,就会造成代码冗余以及重复的组件维护和功能升级工作。
- 每一个子应用都有自己独立的仓库,比较分散,不便于统一管理
- 每个子应用的依赖项都是单独管理,子应用间会产生大量重复依赖,浪费存储空间。
经过对目前可用的各种项目管理方案进行详细研究和对比,结合我们自己的项目特点,最终决定使用基于Git 子模块的项目管理方案。
2. 常见的项目管理方案研究
2.1 NPM
当提到跨项目组件复用时,我们第一时间想到的就是NPM仓库,即将公共组件都传到NPM里,各个项目直接通过NPM安装使用就可以。
NPM 方案的优点是:
- 非常成熟的依赖管理机制
- 具有成熟的规范
- 易于使用
它的问题在于:
- 我们的很多组件是跟业务相关的,不便于上传到NPM公共仓库中,所以就必须建立自己公司的私有NPM仓库,这会带来一些运维成本
- 当公共组件功能进行修复、升级时,项目要与其进行联调测试,而NPM包的发布流程又很繁琐,所以会拖慢调试速度,浪费大量时间在公共组件的发布流程上。
- 该方案只能解决跨项目组件复用问题,解决不了子应用项目集中管理和子项目重复依赖的问题
2.2 monorepo
monorepo
是单体式仓库,它的方案思路是在一个项目仓库中管理多个模块或包。即一个模块一个目录,全部装进一个仓库,统一拉取,统一发布。
这种方案的优点是:
- 一个地方管理主应用和所有子应用
- 所有子应用的Git活动日志和问题跟踪都在同一个仓库中管理
- 由于在同一仓库中,子应用间共享代码将变得简单
- 所有子应用和主应用保持一致的规范并一同进化,即统一的工作流
- 可以实现依赖共享
它的缺点是:
- 虽然各个模块子应用在代码上还是独立的,但是由于所有子应用代码都放在同一个仓库内,那仓库就会变得无比巨大
- 对于那些和主应用关联较弱,甚至可以独立部署的子应用,这种方式会增加其复杂度
- 实际应用中,业务仓库很难保持清晰的模块边界与依赖关系。
- 会产生依赖爆炸问题,并且依赖爆炸的解决与统一的工作流不可兼得。
2.3 Git 子模块
Git 子模块时 Git 原生提供的功能,它的依赖管理机制类似于NPM,但又有明显区别:
- NPM包管理的是子模块构建后的产物
- Git 子模块管理的依赖是子模块的源码
Git 子模块在目录结构上则与 monorepo 很相似,它其实相当于monorepo的各个模块抽离了独立的仓库,它与 monorepo的不同在于:
monorepo
在单个仓库里存放所有子模块源码- git子模块只在主仓库里存放所有子模块的索引
它的缺点是:
- 子模块与主项目是两个不同仓库,意味着需要为每个仓库创建一套脚手架(包含代码规范、发布脚本等)
- 主项目只保存了子模块的链接,说明了当前版本的主项目依赖那个版本的子项目,那么需要正确对这些依赖关系进行管理,而这不太容易
- 发布时需要自己处理依赖关系,先发子项目,再发主项目
对于我们来说,monorepo
最大的问题有两个:
- 仓库体积巨大,并且需要将现有的若干个仓库整合为一个仓库,工作量巨大
- 如果要使用这种方案,需要使用
yarn
的workspaces
功能和lerna
,增加了对工具和相关配置的学习成本。
而针对 Git 子模块的三个缺点:
- 我们现在其实已经是每个子模块都有独立的仓库和代码规范、发布脚本等,对于我们来说不算缺点,而是优点
- 对于处理依赖关系和发布顺序,可以开发响应的命令行工具,以更友好的方式对开发人员进行约束和辅助(类似于使用
git cz / trs tag
等工具),学习成本也不高。
所以,最终我们选用 Git 子模块方案来解决我们的问题
3. 方案实施示范
这里为了方便演示,我将采编模块作为主仓库,用绩效考核模块来同时模拟子模块和公共模块,来示范整个方案的实施过程。
3.1 添加子模块
在添加子模块之前,要想确保子模块代码不被提交到主模块仓库中去,需要先将子模块目录添加到.gitignore
文件中;
// .gitignore/performance
首先,我们在采编模块根目录下,执行命令:
git submodule add https://git.trscd.com.cn/cdtrs/dev/03_super_star/tianMuYun/performance
执行成功后,我们使用 git status
查看当前目录状态,发现:
- 多了
performance
目录 - 多了一个
.gitmodules
文件
performance
目录下就是我们的绩效考核的代码,而.gitmodules
文件内容为:
[submodule "performance"]path = performanceurl = https://git.trscd.com.cn/cdtrs/dev/03_super_star/tianMuYun/performance
这里存放了对子模块的引用信息。
3.2 在子模块中新建用来共享的测试组件
我们在performance/src/coomponent/normal
目录下新建一个用来测试共享的组件SubCom.vue
:
<template><div><span>这是来自子模块的组件,作者为 {{ name }}</span></div></template><script>export default {name: 'SubCom',data() {return {name: 'lll',};},};</script>
3.3 使用子模块内的组件
我们在采编头条号模块的基座应用(src/views/editingCenter/components/newMediaNewsList/Index.vue
)中引入子模块的组件:
<template>...<SubCom></SubCom>...
</template><script>import SubCom from '../../../../../src/components/normal/SubCom.vue';//...export default {components: {//... SubCom,},}</script>
现在来看看效果:
3.4 子模块别名设置
你一定注意到了上面代码中 import SubCom from '../../../../../src/components/normal/SubCom.vue'
的这一长串代码,我们采用了相对路径去引用子模块组件,非常难受。
我们可以通过在主模块webpack配置中为子模块路径设置别名来解决:
// 主模块vue.config.jsconfigureWebpack: {//...resolve: {alias: {Performance: path.resolve(__dirname, 'performance'),},},},
然后这样引用:
import SubCom from 'Performance/src/components/normal/SubCom.vue';
3.5 子模块改动提交
切换到performance
目录,进行提交:
$ git add .$ git commit -m "添加Git子模块测试组件"[submoduleTest 07384a1] 添加Git子模块测试组件1 file changed, 16 insertions(+)create mode 100644 src/components/normal/SubCom.vue
3.6 主模块改动提交
切换到根目录,查询状态:
$ git statusOn branch subModelChanges to be committed:(use "git restore --staged <file>..." to unstage)new file: .gitmodulesnew file: performanceChanges not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: performance (new commits)modified: src/views/editingCenter/components/newMediaNewsList/Index.vuemodified: vue.config.js
我们注意到两点情况:
- 一般情况下,当我们在Git仓库目录中新增一个目录时,它显示的是一个目录形式的路径,就像下面:
$ git statusOn branch subModelUntracked files:(use "git add <file>..." to include in what will be committed)test/
而这里,我们的performance
目录 被识别为一个文件new file: performance
;
- 在已修改文件列表里,我们也看到了
performance (new commits)
这条记录
这就是Git 子模块的机制,它实际上只是存储了我们子模块仓库的一个索引,所以它表现为一个文件,而子模块目录里的文件不会被提交到主模块仓库中,它会将子模块当前分支最新提交作为一个提交记录,提交到主模块去。
我们验证一下:
$ git add .$ git commit -m "增加绩效考核子模块"[subModel 4113e12] 增加绩效考核子模块4 files changed, 14 insertions(+), 12 deletions(-)create mode 100644 .gitmodulescreate mode 160000 performance$ git push origin subModel
看一下线上的Git仓库:
当点击这个文件时,就会跳转到子模块所在仓库。
而这个文件后面跟的 @54d73859
就是主模块所引用的子模块的那个提交的HASH值,我们切换到子模块目录验证:
$ git logcommit 54d73859763e2b4c87f623631ac29b9821ef075d (HEAD -> subModel)Author: hjb2722404 <hjb2722404@163.com>Date: Tue Jan 11 09:49:46 2022 +0800添加Git子模块测试组件
4. 总结
通过这样的方式,我们就可以同时实现子应用与主应用统一管理但又能分开管理,并且各个模块之间还可以共享组件和依赖的需求。总的结构如下:
当然,这里为了方便,将公共模块与各个子模块并列放在了一起,实际上,公共模块同样可以作为各个子模块的子模块还使用,也就是说,子模块时可以嵌套的。具体以实际需求和应用场景为准。
基于Git子模块的微前端项目管理和公用组件库方案相关推荐
- 基于qiankun搭建ng-alain15微前端项目示例实践
基础环境 实践日期:2023-03-04 ng versionAngular CLI: 15.2.1 Node: 18.14.2 Package Manager: npm 9.5.0 OS: win3 ...
- 基于 iframe 的全新微前端方案
作者:damyxu,腾讯 PCG 前端开发工程师 iframe是一个天然的微前端方案,但受限于跨域的严格限制而无法很好的应用,本文介绍一种基于 iframe 的全新微前端方案,继承iframe的优点, ...
- 基于qiankun搭建ng-alain15微前端项目入门实践
基础环境 实践日期:2023-02-22 ng versionAngular CLI: 15.1.6 Node: 18.14.2 Package Manager: npm 9.5.0 OS: win3 ...
- 基于微前端的大型中台项目融合方案
点击上方"程序员成长指北"关注 关于微前端是什么,以及微前端落地方案,社区遍地都是,本篇文章不会再赘述这些基础知识.当然如果你没了解过上述知识,也可以直接读下这篇文章,足够浅显易懂 ...
- 016基于pinia完成Vue3的前端数据持久化储存storage的方案落地
016基于pinia完成Vue3的前端数据持久化储存storage的方案落地 支持自定义前缀 支持localStorage和sessionStorage 支持自定义某一些key进入缓存模式 采用中间件 ...
- Henry前端笔记之 UI组件库中table与slot相关理解
Henry前端笔记之 UI组件库中table与slot相关理解 作用域插槽: 解构赋值基础:https://developer.mozilla.org/zh-CN/docs/Web/JavaScrip ...
- Muse-UI(基于 Vue 2.0 和 Material Desigin 的 UI 组件库)
基于 Vue 2.0 和 Material Desigin 的 UI 组件库,Muse UI 拥有40多个UI 组件,用于适应不同业务环境.Muse UI 自定义主题方式极为优雅,仅需少量代码即可完成 ...
- Angular前端项目(使用ng-zorro组件库)
分享一个最近在做的一个前端项目,前端选型Angular,组件库选择的是ng-zorro(官网:http://ng.ant.design/docs/introduce/zh).项目结构以及项目里面用到的 ...
- 基于qiankun.js的微前端应用实战
背景:在项目开发中,有这样的需求,多个项目要通过统一的门户网站加载出来,该统一门户网站只显示相应按钮进行菜单导航切换 qiankun.js介绍: qiankun 是一个基于 single-spa 的微 ...
最新文章
- 如何使用Leangoo看板统计中的任务周期?
- idea工程本地依赖_IDEA最新版2020.1的maven工程本地依赖仓库无法使用问题(已解决)...
- 优秀产品经理(CEO)必须get的财税知识
- wxWidgets:命令行参数
- MySQL中replace主键_Mysql中replace与replace into的用法讲解
- 一些人一旦离开原来的单位,就不爱再去了,是为什么?
- 归并排序(数组指针详细讲解,图例分析)
- ms17-010 php版本,MS17-010补丁360版
- AI模型的大一统!浅析微软的BEIT3:多模态领域乱杀的十二边形战士
- 技术负责人如何带领好团队
- linux篇-图解cacti监控安装
- 服务器系统浏览器打不开,电脑浏览器打不开解决方法
- java 图像梯度检测_opencv学习笔记(六)---图像梯度
- 第 4-4 课:Spring Boot 中使⽤ Cache 缓存的使⽤
- 用SQLite进行全文检索
- 蓝牙款血氧仪单片机开发
- 今天没有收到农行的笔试通知
- 外设驱动库开发笔记40:AT25xxx外部存储器驱动
- 开源服务器日志实时查看系统,开源日志管理系统
- 高精度倾角传感器测量原理