背景
公司有一个历史悠久、体积庞大的老项目,除了传统老旧项目存在的特点,该项目强依赖后端模板,且每一个页面都对应一个模板,启动依托于docker,随着项目不断更新迭代,项目结构越来越复杂,维护成本越来越高,进而引发一系列的问题...
巨石应用存在的问题
项目体积过大,clone时间长
结构混乱,高度耦合,难以维护
需要解决构建时间长的问题,需要维护复杂的webpack配置
多人开发同一个项目,发布部署容易混乱
技术栈迭代成本高昂
如何拆分?
既然是巨石应用,很容易想到的改造方案就是拆分成多个子应用,分而治之,通常来说有以下几种拆分方案:
按技术拆分
按照业务或者页面拆分
按照权限拆分
按照变更的频率拆分
我们的项目不存在权限限制以及技术栈不统一的问题,显然这两种拆分方式都不合适,在我们的业务场景中,一个项目是由多个页面组成的,每个页面之前的状态相互独立,显而易见的直接按照业务拆分即可,这里推荐madge工具,它可根据你指定的入口自动为你找到入口的依赖,并将其从主项目中剥离出来,拆分完成之后,又该采用哪种架构方式呢?
传统解决方案
muti repo
也就是直接将其拆分成多个仓库,简单粗暴但存在不少问题:
管理、调试困难
多个 git 仓库管理起来天然是麻烦的。对于功能类似的模块,如果拆成了多个仓库,无论对于多人协作还是独立开发,都需要打开多个仓库。
虽然 vscode 通过 Workspaces 解决多仓库管理的问题,但在多人协作的场景下,无法保证每个人的环境配置一致。
对于共用的包通过 Npm 安装,如果不能接受调试编译后的代码,或每次 npm link 一下,就没有办法调试依赖的子包。
分支管理混乱
假如一个仓库提供给 A、B 两个项目用,而 B 项目优先开发了功能 b,无法与 A 项目兼容,此时就要在这个仓库开一个 feature/b 的分支支持这个功能,并且在未来合并到主干同步到项目 A。
一旦需要开分支的组件变多了,且之间出来依赖关联,分支管理复杂度就会呈指数上升。
依赖关系复杂
独立仓库间组件版本号的维护需要手动操作,因为源代码不在一起,所以没有办法整体分析依赖,自动化管理版本号的依赖。三方依赖版本可能不一致:一个独立的包拥有一套独立的开发环境,难以保证子模块的版本和主项目完全一直,就存在运行结果不一致的风险。
占用总空间大
正常情况下,一个公司的业务项目只有一个主干,多 git repo 的方式浪费了大量存储空间重复安装比如 React 等大型模块,时间久了可能会占用几十 GB 的额外空间,对于没有外接硬盘的同学来说,定期清理不用的项目下 node_modules 也是一件麻烦事。
不利于团队协作
一个大项目可能会用到数百个二方包,不同二方包的维护频率不同,权限不同,仓库位置也不同,主仓库对它们的依赖方式也不同。一旦其中一个包进行了非正常改动,就会影响到整个项目,而我们精力有限,只盯着主仓库,往往会栽在不起眼的二方包发布上。