一种基于微前端的云组件方案设计与实现
背景
在传统模式下,尽管通过各种框架工具,合理分层来控制开发的复杂度,但随着参与人员、团队的增多变迁,业务逻辑的复杂度升高,经常性地出现一个普通应用演变成一个巨石应用,同时由于代码的层次结构、编写规范以及习惯等差异,很难实现团队自洽,这种巨石应用如果没有良好的治理就会变得越来越难以维护,另一个缺陷就是无法快捷独立实现跨应用级别的组件共享,即一个应用中想要使用另一个应用中的组件。实现这种跨应用共享组件有若干种做法,首先最简单实现是将组件代码直接进行迁移,耗时费力,需要太多人工干预与协调,并且实现组件更新不直观;第二种方法是通过页面嵌套,通过 iframe 的方式将要复用的部分插入页面,简单快速,但不同应用中使用的相同部分是完全耦合的,并且这种完全隔离导致主应用和子应用之间通信繁杂
研究现状
- single-spa: 是一种类似于状态机的方案,在一个项目中含有多个应用,可以将其看成一个个状态,通过监听路由的变化来渲染不同的应用,实现方式是以路由的方式进行耦合,加载的应用和页面的 URL 路径强关联,好处是简单易用,同时实现起来复杂度不高,通过路由可以降低组件间的耦合性,间接实现状态隔离;缺点就是灵活性不够,只能依靠路由进行应用组件的切换
- Web Components: 是Google推出的浏览器原生组件,由Custom elements(自定义元素)、Shadow DOM(影子 DOM)、HTML Template(HTML 模板)、HTML Imports(模板导入)组成,主要的实现方式就是用户侧编写定制化的组件,通过其提供的接口进行封装,对使用者而言这个组件就变成一个黑盒,通过这样的方式实现封装功能的定制元素,可以在任何地方使用并且无需担心有冲突。这种方式因为封装的是浏览器原生组件,完全与技术栈无关,同时独立开发,应用 shadow DOM 技术能够实现各微应用之间的有效隔离,但其缺点在于浏览器对它的兼容性不好,实现难度大
- qiankun: 阿里推出的基于 single-spa 的微前端实现库,Qiankun 在 single-spa上做了一层封装处理,其本质还是基于路由的方式实现,增加一些特性化功能,如接入方式、样式隔离、插件等。其设计的核心理念是简单易用和解耦技术栈,从使用方式上说,封装内部实现,提供 API 调用,同时对接 HTML 接入的方式来简化使用;从实现目标上秉承了微前端将巨石应用拆分成松耦合微应用的原则,确保微应用独立开发、部署、运行能力。其缺点就是不能快捷实现组件级别的跨应用共享
- icestark: 阿里淘宝推出的完全自研的微前端实践方案,采用的方式是框架应用和子应用相配合,框架应用作为子应用注册、加载、渲染的父应用,子应用是一个SPA应用,打包出 bundle ,发布到 CDN,在框架应用中注册管理所有的子应用,通过劫持路由变化 API 函数进行监听实现子应用的切换。框架应用职责明确,管理方便,子应用引入方式灵活,缺陷就是子应用的切换还是和路由强耦合,灵活性低
- Emp:是欢聚集团基于Module Federation开发的微前端框架webpack中的Module Federation可以让不同的项目之间通过远程调用,直接共享任意内容,包括上下文、状态、组建、方法、模块等。基于这种技术,Emp 提供了基站应用来管理共享资源,需要搭建专用的应用基站,基站内部放置多个应用的共享资源(组件、模块、方法等),基站的共享资源需要专人维护来确保稳定和可靠性。这种微前端方案可以满足需求,通过专人维护的基站实现组件的共享,拥有跨应用组件共享、跨框架组件调用的能力,但其缺点在于成本较高,组件共享之间存在壁垒,如没有一个公共的可复用组件市场形成快捷高效的开发流程。另外的缺陷就是组件共享缺乏灵活性,分发方式固定,组件内容可定制化能力弱
各种已有微前端方案实现方式
| 方案 | single-spa | Web Components | qiankun | icestark | Emp |
|---|---|---|---|---|---|
| 切换方式 | 与路由耦合 | 任意 | 与路由耦合 | 与路由耦合 | 任意 |
| 适用对象 | 应用 | 组件 | 应用 | 应用 | 组件 |
| js隔离 | 无 | 无 | proxy | proxy | 无 |
| 样式隔离 | css命名空间 | Shadow DOM | css命名空间、Shadow DOM | css module、css样式前缀 | 无 |
研究意义
为了改善现有微前端与路由强耦合、灵活性不够、定制化能力不强的缺陷,在已有方案的基础上,提出了一种基于微前端的云组件实现方案
云组件借用云端技术,将组件资源上传到云端,通过网络请求的方式进行云端组件的下发。与大部分微前端实现方案相比其优点主要包含以下三点
- 云组件的引入方式更灵活,在项目中就可以进行直接引用,无需关注页面的路由信息,解耦路由
- 云端组件的方式更加适用于组件的版本控制,通过请求下发的方式可以通过各种参数进行定制化的下发配置能力,即根据不同的请求策略下发不同版本的组件,可以进行灰度实验和对比实验
- 云端组件有利于进行组件的定制化,下发的资源还可以包含各种自定义的配置,在组件运行时渲染时进行注入,这对用户使用上来说更加人性化
需求分析
组件开发方

总体活动图

初始化活动图

打包活动图

组件使用方

系统概要设计
系统架构设计

软件结构设计

数据结构设计
