微前端是一种新兴的前端架构模式,是一种类似于微服务的架构,将微服务的理念应用于浏览器端。其核心理念是将一个大而单一的前端应用拆分为多个小型独立的微应用。这些微应用各自独立,可以由不同团队开发维护,部署,组合这些微应用,行成一个聚合应用。
微前端不是一门具体的技术,而是整合了技术、策略和方法,可能会以脚手架、辅助插件和规范约束这种生态圈形式展示出来,是一种宏观上的架构。
微前端技术方案
微前端主要分两种架构模式
- 基座模式
通过一个主应用,来管理其它应用。设计难度小,方便实践,但是通用度低。
- 自组织模式
应用之间是平等的,不存在相互管理的模式。设计难度大,不方便实施,但是通用度高
微前端技术方案对比:
方案 | 开发成本 | 维护成本 | 实现难度 | 缺点 |
路由分发 | 低 | 高 | 低 | 配置较多,性能较差 |
iframe | 低 | 低 | 低 | 1、无法保持路由状态,刷新后路由状态就丢失 2、完全的隔离导致与子应用的交互变得极其困难 3、iframe 中的弹窗无法突破其本身,无法应用到整个大应用中,只能在对应的窗口内展示 4、由于可能应用间不是在相同的域内,主应用的 cookie 要透传到根域名都不同的子应用中才能实现免登录效果。 5、每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程,占用大量资源的同时也在极大的消耗资源,有严重的性能问题 |
single-spa | 中 | 中 | 中 | 共享及隔离粒度不统一 |
web-components | 高 | 低 | 高 | 需要一定的学习成本和使用成本,对兼容性有要求的项目无法使用 |
Module-Federation | 中 | 低 | 中 | 多个项目组合,需要考虑组合情况 |
微前端技术框架对比:
技术框架 | 优点 | 缺点 |
qiankun(基座模式)(阿里) | 1、HTML Entry接入方式 2、资源预加载 3、沙箱隔离 4、技术栈无关 5、业界应用较多的方案,导入导出有手动加载的实践,其他产品线也有应用 | 1、子应用和子应用的数据共享需要主应用做转发 2、共用组件方法困难 3、css隔离方案并不完美,子应用会影响主应用的样式 |
EMP(去中心模式) | 1、去中心化,基站应用只用来共享组件,业务应用可以随意组合,可跨技术栈调用 2、应用间直接通信 3、可直接暴露需要共享的模块 4、按需加载,不用加载完整项目 5、资源复用,减少编译体积 | 1、业界应用没有qiankun广,技术较新 2、无法适配旧框架 3、单页微前端应用解决方案 4、没有使用过,有更多的学习成本 |
micro-app(基座模式)(京东) | 1、支持静态资源地址补全 2、支持元素隔离 3、支持插件系统 4、轻量化,侵入性低,改造简单 | 1、业界应用没有qiankun广,技术较新 2、子应用和子应用的数据共享需要主应用做转发 3、共用组件方法困难 |
背景及问题分析
OceanMind海睿思数据中台产品采用松耦合架构,基于海睿思数据计算基础平台(PaaS)提供数据集成、数据处理分析、数据治理、元数据管理、数据管理等多个产品功能模块,支持用户根据自身需求组合搭配、逐步演进。
然而,随着产品不断的迭代开发,页面数量越来越多,形成了一个上百个页面的巨型单体应用,因此带来以下问题:
- 文件和依赖过多,造成本地开发和打包部署的性能问题;
- 应用数量多、耦合性强,造成维护成本高,往往出现改一处而动全身的问题;
- 当部分内容功能在面临技术升级和重构诉求时,面临改一处而动全身的问题。
为了解决这些问题,需要对项目进行拆分、渐进式的重构、同时兼容老项目。此时微前端架构符合我们的诉求。
改造方案
OceanMind分为元数据管理,数据集成,数据处理分析,站内信,运维管理等多个模块,这些模块最初都是在一个项目工程下,技术栈统一,交互十分相似。在要求复用已经开发好的组件的前提下,我们基于Module-Federation核心技术,采用emp框架,依托于导航页进行页面模块划分,逐步完成微前端改造计划。
每个具体的子应用都包含公共侧边栏,公共头部,统一的拦截逻辑,和请求逻辑。
首先拆分出公共组件项目,用来开发公共功能,如统一拦截,统一方法,必备依赖,公共通用的交互组件,公共样式,权限管理等,通过empShare配置导出,引用项目时,正确引用remotes配置,按照正常组件方式引用,也可通过在路由配置地址,当做页面使用。
按照不同的业务模块,进行业务微前端项目拆分,模块仅保留原业务相关逻辑,用户信息等通用能力移交给公共项目组件去实现,业务微前端项目无需考虑。对于状态存储,每个业务模块将自己的store注册到公共项目的store中,做为一个模块。这样整个OceanMind只有一个唯一顶层store,方便业务模块使用公用信息。
为方便本地开发,将所有微前端项目放在同一目录,在同级增加node脚本,便于一键启动多个微前端项目及本地打包构建。
改造中遇到的问题及解决方案:
- 原OceanMind为vue-cli创建,改为emp后,webpack版本变更为5,部分依赖需要进行升级兼容,部分代码写法要进行改变。
- 业务应用在store中使用持久化插件时需要注意,需要自定义名称,否则会造成持久化信息被覆盖问题。
- 启动项目有些警告信息,是由于新版babel增加提示造成的,无需考虑。
- 样式污染问题,通过规范样式,增加scoped解决。
价值
在微前端改造过程中,团队成员对整体代码更加熟悉,业务代码更专注于业务层面的开发,无需再考虑通用性能力;
需求增加或修改时,对代码的侵入程度更小了,提高了迭代稳定性和开发效率,可实现按需按模块发布;
加速构建速度,拆分后只需专注影响模块,不需要考虑其他模块,打包和本地开发速度大幅提升