如何瓦解巨石单页应用

以前经过几篇文章像你们介绍了我是如何经过微前端的手段去治理一个有几十个子业务域系统的大型 B 端系统。今天我想经过这篇文章来像你们介绍下我是如何在这样一个大型 B 端系统中去治理一个“巨石”单页子业务系统的。前端

先聊聊背景

做为一个前端咱们大体都经历过早期的 MPA 应用演变为 SPA 应用的体验快感,也相信你们都经历过简单 SPA 演变为巨石 SPA 的痛苦。目前我在负责一个大型 B 端系统的一个子业务,这个子业务是一个大型的 SPA,3W+代码行数,子页面入口有 10+。而且由于业务属性的类似性,这个子业务系统还做为子系统服务于其余两个系统平台。从我平日的迭代开发来看,这样的应用已经“大到快不能维护了”,开发维护成本极高。npm

接下来我会像你们简单介绍,在拿到这样一个“巨石“单页应用,我是如何一步步作项目拆分优化治理的。数据结构

分析业务边界

首先我以为要作的就是理清楚业务边界,咱们的业务虽然做为大型 B 端系统的一个子业务,可是咱们的系统内部也能够根据业务边界拆分红多个细分的子系统,接下来我从一个例子提及。架构

假设咱们当前的业务大致以下所示,业务功能聚合在子 tab 下,每一个 tab 下都有着复杂的业务逻辑,而且咱们的系统也做为子业务服务于平台 A、B、C。
函数

这时候作系统拆分的时候,很直观的就会联想到根据平台 A、B、C 把咱们的系统拆分为三个业务子系统。若是说,咱们的业务平台差别性很大,那么按照平台属性去作系统拆分无可厚非。可是我相信业界的 FEer 们都更倾向于 “one code,any platform”,那么咱们的业务在这些平台都差别不大,甚至说只是主题色的差别,那么按照平台去作系统拆分就显得很不合理了。布局

接下来,咱们能够考虑从页面结构来作系统拆分,能够看出目前咱们应用的结构以 tab 的形式分别聚合。若是此时各个 tab 间没有复杂的事件通讯等,即可以考虑以此来拆分咱们的子模块。post

最后还差一步,就是咱们的业务属性的分析,能够更进一步的从当前的产品逻辑来入手,将更贴合或者说彼此耦合度较高的一些产品功能做为一个子模块放到一块儿,这样会更加利于将来代码的扩展和维护。优化

在咱们作业务拆分的时候常常会面临着取舍,有不少细碎的小业务不知道划分到哪一个子模块里,这里我说一个我常常用的方法:我会尽可能保持核心业务模块的独立性,把相对无关的子业务拆分到一块儿,想一想由于一个八竿子打不着的业务影响到核心业务你们都不想吧...spa

这里简单总结下:架构设计

  • 分析平台差别,平台差别大能够根据平台拆分;
  • 分析页面结构,若是结构清晰,能够根据结构拆分;
  • 分析产品业务,将产品逻辑耦合度高的功能合并到一块儿;

拆分公共依赖

在咱们理清了业务边界划分了业务模块以后,不要着急着去作模块拆分,这时候咱们能够从这些即将要拆分的子业务模块中去找到公共依赖。

接下来简单说下我在当前业务的一个依赖拆分思路:

  • 针对视图层,咱们落地了组内的业务组件库,在已有 UI 组件库以外抽离了一些具备业务特征的基础业务原子组件,而后是基于原子组件封装一些复杂的业务域特有的业务组件,这些业务组件不只服务与咱们自有的业务,在其余业务域与咱们业务的交集中也能够用到。
  • 针对逻辑层,咱们落地了业务函数库,里面包含了咱们业务域通用的函数功能,接口数据结构 to 组件数据结构的各类 adapter 函数等等。

那么此时咱们的系统就以下图所示:

拆分子业务模块

在梳理了业务边界和公共依赖的拆分以后,就是真正的子模块的拆分,这里我主要想说的就是怎么把拆开的各模块“聚合”起来。

不一样于以前聊过的 B 端系统的治理,咱们子系统中子业务模块的聚合没有太多的约束:

  • 业务体量大不过整个 B 端系统,不须要复杂的路由设计
  • 不须要考虑和其余业务域间的影响,宿主环境已经为咱们作好了沙箱隔离;
  • 能够设计本身的通讯方案,也能够适当复用宿主环境的通讯方案(由于作好了业务边界的划分,子业务模块间理论上不该该存在复杂的通讯场景了);

可是咱们也须要针对宿主环境的架构方案来制定本身的聚合方案,这里我列举下目前咱们尝试过的可行方案:

基于 npm 包架构

这种架构致力于将通用的布局组件拆分为 npm 包的形式提供给子应用。这样的架构具备如下的优势:

  • 开发落地简单,子应用单独开发单独部署,仅须要引入布局组件便可;
  • 不依赖宿主环境,宿主环境能够采起任意架构,这种方案都不会受到太大的影响;

可是也会有如下的缺点:

  • 布局组件中不能包含太重的业务逻辑,频繁的业务更迭将致使子应用须要频繁同步更新组件版本。
  • 毕竟是基于 MPA,相比于其余两种方案的无刷体验差些。

基于 iframe 架构

这种方案我就不赘述了,以前的文章已经有较为详细的架构分析了。这里我直接列举下区别于当前场景的一些缺点:

  • 依赖宿主环境的架构,若是宿主环境也是 iframe 架构,那么一层层的 iframe 嵌套比较蛋疼;

基于微前端架构

同理,这种方案我就不赘述了,以前的文章已经有较为详细的架构分析了。这里我直接列举下区别于当前场景的一些缺点:

  • 依赖宿主环境的架构,若是宿主也是微前端架构,由于目前我尚未尝试过微前端嵌套的场景,可行性以及将来的风险不可控。若是宿主是 iframe 架构,其实这也是一个不错的方案(彻底的沙箱隔离),目前咱们组内也有此种方案的尝试和落地;

最后,咱们的应用按照以下层次进行拆分:

结语

以上即是我对大型 SPA 进行分层治理的一些思考,固然我所介绍的只是万千应用中的一种场景,而且真实拆分的过成功遇到的问题也比文中描述的多得多,路子不少,但愿你们都能找到适合本身应用的架构设计。

推荐阅读

相关文章
相关标签/搜索