微前端工具箱:用subtree解决多模块复用问题
在日常开发工作中,可能会面临这样一种需求:项目 A 中,存在一个或多个有价值的功能模块,这里的所谓模块指有一个或几个页面组成的功能模组;其他项目,如项目 B,也想借助这些模块给自己赋能,且基本要求如:
要使用项目 B 自己的导航菜单 要重新定义路由并将各个模块分散到不同页面下 接口请求要统一加特殊标识参数 项目 B 要根据额外的环境变量对各模块中的功能做限制 项目 B 希望以自己的上线节奏更新模块
为了理解方便,约定文档中可能通用的几个称呼:
主项目
- 项目 A新项目
- 项目 B 等子模块
- 从项目 A 里划分出的几个模块
【方案对比】
经过调研,常用且纯前端的项目模块化改造方案如下:
成本 \ 方案 | iframe | 微前端 | npm包 | Git子模块 |
---|---|---|---|---|
首次改造主项目 | 3 | 3 | 5 | 5 |
首次改造新项目 | 1 | 3 | 2 | 2 |
维护子模块 | 2 | 3 | 3 | 2 |
更新子模块 | 1 | 5 | 3 | 1 |
同步子模块 | 1 | 1 | 2 | 1 |
总开发成本 | 8 | 16 | 15 | 11 |
综合到考虑各业务项目体量、具体产品需求,和由改造带来的长期用户体验等,我们可能会在工具箱中选择Git子模块
方案进行。
【git subtree 介绍】
subtree 是 git submodule 技术的主要替代技术,避免了后者的一些麻烦。
具体介绍这里不做赘述,可以直接参考文末的资料,如 《submodule vs. subtree 对比》[1]
简而言之:
为每个子模块创建一个独立的 git 仓库 子模块的 git 仓库中的文件可以被当成一个普通的子目录添加到主项目/新项目中 过程中只拉取文件,不会产生额外的 git 隐藏文件等 子模块中的改变会被正常提交到所在项目的历史中 在主项目/新项目层面也可完成子模块的 git 推送/拉取操作,这也是推荐的做法
分别在主项目/新项目中执行的 git 命令:
添加 remote 以简化后续命令:
git remote add -f <子模块别名> git@coding.foo.com:<子模块的...`.git`>
后面以 子模块别名
为 report
为例
添加 subtree:
git subtree add --prefix=<相对路径> report <分支> --squash
拉取 subtree:
git subtree pull --prefix=<相对路径> report <分支> --squash
推送 subtree:
git subtree push --prefix=<相对路径> report <分支>
查看 subtree 的 id:
git ls-remote report
或
git ls-remote report | grep
【选择一种分支策略】
和 git 本身各种流派的 workflow 一样,subtree 并没有规定特定的工作流程;这里尝试总结两种:
⇲ 单向模式:被动小分支
涉及子模块中功能升级、优化、改进的内容,都在主项目中 日常的以上改动都 push 到子模块的 master 子模块仓库中维护某个独立分支,如用于项目 B 的 feature-projB 子模块 master 有更新时手动 merge 到 feature-projB 新项目只 pull 最新的 feature-projB
优点:
新项目可以随意修改特定的子模块分支 合并冲突可以在子模块中按普通方式解决 子模块代码中无需判断所在项目的环境
缺点:
如果改动需要反向同步到 master,可能需要额外的重复修改或 cherry-pick
♺ 双向模式:共建master
主项目和新项目各自维护涉及子模块的相关功能 新项目中的改动也可以 push 到子模块的 master 新项目涉及子模块的改动应保证不污染主项目等其他项目
优点:
涉及子模块中功能升级、优化、改进的内容,可以由各个业务项目共同贡献 如果改动不复杂可以跳过再去子模块仓库下进行的各种操作
缺点:
可能需要改动 webpack 配置等以区分项目环境 代码中需要区分环境的片段需要重点关注
【注意问题】
新项目和主项目结构、基础能力难免不一致,如 src/store
和src/common/store
,以及http
等模块中方法的不同要竭尽所能地使子模块低耦合,保证多项目适配的基本可行性 要在文档中(如子模块根目录的README)标明所有依赖点 merge 代码冲突 双向模式下,如果本方没有更新,可以直接 rm -rf 掉子模块目录并重新 add
【参考文档】
《submodule vs. subtree 对比》: https://einverne.github.io/post/2020/04/git-subtree-usage.html#sub-module-vs-sub-tree-%E5%AF%B9%E6%AF%94
https://betterprogramming.pub/git-subtree-usage-6aaba8b5d947 https://medium.com/@v/git-subtrees-a-tutorial-6ff568381844 https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec https://medium.com/codex/github-subtrees-fb93d229cdc0 https://segmentfault.com/a/1190000012002151 https://tech.youzan.com/git-subtree/ http://www.fwolf.com/blog/post/246 https://liuyufang.com/version-control/git/git-subtree https://www.worldhello.net/gotgit/04-git-model/050-subtree-model.html
评论