基于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最大的问题有两个:

  • 仓库体积巨大,并且需要将现有的若干个仓库整合为一个仓库,工作量巨大
  • 如果要使用这种方案,需要使用yarnworkspaces功能和lerna,增加了对工具和相关配置的学习成本。

而针对 Git 子模块的三个缺点:

  1. 我们现在其实已经是每个子模块都有独立的仓库和代码规范、发布脚本等,对于我们来说不算缺点,而是优点
  2. 对于处理依赖关系和发布顺序,可以开发响应的命令行工具,以更友好的方式对开发人员进行约束和辅助(类似于使用 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

我们注意到两点情况:

  1. 一般情况下,当我们在Git仓库目录中新增一个目录时,它显示的是一个目录形式的路径,就像下面:
    $ git statusOn branch subModelUntracked files:(use "git add <file>..." to include in what will be committed)test/

而这里,我们的performance 目录 被识别为一个文件new file: performance;

  1. 在已修改文件列表里,我们也看到了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子模块的微前端项目管理和公用组件库方案相关推荐

  1. 基于qiankun搭建ng-alain15微前端项目示例实践

    基础环境 实践日期:2023-03-04 ng versionAngular CLI: 15.2.1 Node: 18.14.2 Package Manager: npm 9.5.0 OS: win3 ...

  2. 基于 iframe 的全新微前端方案

    作者:damyxu,腾讯 PCG 前端开发工程师 iframe是一个天然的微前端方案,但受限于跨域的严格限制而无法很好的应用,本文介绍一种基于 iframe 的全新微前端方案,继承iframe的优点, ...

  3. 基于qiankun搭建ng-alain15微前端项目入门实践

    基础环境 实践日期:2023-02-22 ng versionAngular CLI: 15.1.6 Node: 18.14.2 Package Manager: npm 9.5.0 OS: win3 ...

  4. 基于微前端的大型中台项目融合方案

    点击上方"程序员成长指北"关注 关于微前端是什么,以及微前端落地方案,社区遍地都是,本篇文章不会再赘述这些基础知识.当然如果你没了解过上述知识,也可以直接读下这篇文章,足够浅显易懂 ...

  5. 016基于pinia完成Vue3的前端数据持久化储存storage的方案落地

    016基于pinia完成Vue3的前端数据持久化储存storage的方案落地 支持自定义前缀 支持localStorage和sessionStorage 支持自定义某一些key进入缓存模式 采用中间件 ...

  6. Henry前端笔记之 UI组件库中table与slot相关理解

    Henry前端笔记之 UI组件库中table与slot相关理解 作用域插槽: 解构赋值基础:https://developer.mozilla.org/zh-CN/docs/Web/JavaScrip ...

  7. Muse-UI(基于 Vue 2.0 和 Material Desigin 的 UI 组件库)

    基于 Vue 2.0 和 Material Desigin 的 UI 组件库,Muse UI 拥有40多个UI 组件,用于适应不同业务环境.Muse UI 自定义主题方式极为优雅,仅需少量代码即可完成 ...

  8. Angular前端项目(使用ng-zorro组件库)

    分享一个最近在做的一个前端项目,前端选型Angular,组件库选择的是ng-zorro(官网:http://ng.ant.design/docs/introduce/zh).项目结构以及项目里面用到的 ...

  9. 基于qiankun.js的微前端应用实战

    背景:在项目开发中,有这样的需求,多个项目要通过统一的门户网站加载出来,该统一门户网站只显示相应按钮进行菜单导航切换 qiankun.js介绍: qiankun 是一个基于 single-spa 的微 ...

最新文章

  1. 如何使用Leangoo看板统计中的任务周期?
  2. idea工程本地依赖_IDEA最新版2020.1的maven工程本地依赖仓库无法使用问题(已解决)...
  3. 优秀产品经理(CEO)必须get的财税知识
  4. wxWidgets:命令行参数
  5. MySQL中replace主键_Mysql中replace与replace into的用法讲解
  6. 一些人一旦离开原来的单位,就不爱再去了,是为什么?
  7. 归并排序(数组指针详细讲解,图例分析)
  8. ms17-010 php版本,MS17-010补丁360版
  9. AI模型的大一统!浅析微软的BEIT3:多模态领域乱杀的十二边形战士
  10. 技术负责人如何带领好团队
  11. linux篇-图解cacti监控安装
  12. 服务器系统浏览器打不开,电脑浏览器打不开解决方法
  13. java 图像梯度检测_opencv学习笔记(六)---图像梯度
  14. 第 4-4 课:Spring Boot 中使⽤ Cache 缓存的使⽤
  15. 用SQLite进行全文检索
  16. 蓝牙款血氧仪单片机开发
  17. 今天没有收到农行的笔试通知
  18. 外设驱动库开发笔记40:AT25xxx外部存储器驱动
  19. 开源服务器日志实时查看系统,开源日志管理系统
  20. 高精度倾角传感器测量原理

热门文章

  1. 【方法】Latex使用BibTeX生成参考文献列表
  2. IMPERVA-WAF 系统制作和安装-USB
  3. oscp——symfonos:3
  4. 学院来信371:建立“可复制”+“可迭代”的投资系统
  5. PC端和手机端平台的区别
  6. Beta阶段基于NABCD评论作品
  7. 单灯闪烁c语言程序,51单片机,C语言编程,控制指示灯闪烁的频率
  8. 【黏住用户的不是小红书,而是它背后的那些人】
  9. QNX系统挂载CF卡
  10. Python Tkinter——数字拼图游戏