# 微前端后台改造方案

# 背景

随着后台应用的迭代功能的新增,导致项目变的越来越大,进而出现这些问题。

  1. 构建速度越来越慢
  2. 应用越来越庞大,难以维护
  3. 不能单独回滚(同时上线的两个功能)
  4. 无法平台化
  5. 无法体验新技术带来的提升

# 微前端的概念

微前端是什么:微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。有一个基座应用(主应用),来管理各个子应用的加载和卸载。

基本原理 它的基本原理是将子应用的 JS、CSS 等静态资源加载到基座应用渲染,本质上这两个应用都是在同一个页面,只是渲染的区域不同,并通过一些手段防止多个应用之间的冲突。

# 微前端的优势

  1. 将没有关联的几个应用融合为一个应用
  2. 减少项目之间的耦合,提升项目扩展性。
  3. 项目可以单独维护,不受主框架影响
  4. 容易组合,可以将任意项目相互组合

# 微前端框架

框架名 issues数 star数 开源时间 最后更新时间 地址
single-spa 74 12.6k 2015.10.5 2023-06-16 查看 (opens new window)
蚂蚁金服qiankun 355 14.8k 2019.05.23 2023-09-18 查看 (opens new window)
京东零售micro-app 360 4.6k 2021.07.09 2023-09-23 查看 (opens new window)
腾讯无极wujie 250 3.2k 2022.06.30 2023-09-23 查看 (opens new window)
iframe - - - -
Module Federation - - - 查看 (opens new window)

# iframe

iframe 是在页面中创建一个独立的 window 窗口,它完全和自己所在的页面隔离,具有天然的样式和 JS 隔离特性,这也是实现微前端最简单、最稳定的方案。

特点

  • 使用简单
  • 应用之间天然隔离

不足

  • 双滚动条
  • 弹窗无法覆盖全局
  • 刷新页面路由状态丢失
  • 破坏了语义化,对无障碍可访问性支持不好哦
  • 不利于seo,会当成2个页面
  • url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。性能不高
  • 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
  • 性能不高。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

# single

Single-spa 是一个将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架

特点

  • 在同一页面上使用多个前端框架 而不用刷新页面 (React, AngularJS, Angular, Ember, 你正在使用的框架)
  • 独立部署每一个单页面应用
  • 新功能使用新框架,旧的单页应用不用重写可以共存
  • 改善初始加载时间,延迟加载代码

不足

  • JS 和 CSS 的没有隔离,需要自己处理
  • 不支持开箱即用,配置复杂
  • 没有解决资源加载、全局状态管理的问题

# qiankun

qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 目前 qiankun 已在蚂蚁内部服务了超过 2000+ 线上应用,在易用性及完备性上,绝对是值得信赖的

特点

  • 技术栈无关 - 主框架不限制接入应用的技术栈,微应用具备完全自主权
  • 独立开发、独立部署 - 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
  • 增量升级 - 在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
  • 独立运行时 - 每个微应用之间状态隔离,运行时状态不共享
  • 基于 single-spa 封装,提供了更加开箱即用的 API。
  • HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
  • 样式隔离,确保微应用之间样式互相不干扰。
  • JS 沙箱,确保微应用之间 全局变量/事件 不冲突,js 沙箱做了 SnapshotSandbox、LegacySandbox、ProxySandbox 三套渐进增强方案。css 沙箱做了 strictStyleIsolation、experimentalStyleIsolation 两套适用不同场景的方案
  • 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。

不足

  • 适配成本比较高,工程化、生命周期、静态资源路径、路由等都要做一系列的适配工作;
  • css 沙箱采用严格隔离会有各种问题,js 沙箱在某些场景下执行性能下降严重;
  • 无法同时激活多个子应用,也不支持子应用保活;
  • 无法支持 vite 等 esmodule 脚本运行;

# Micro-app

类WebComponent组件

micro-app并没有沿袭single-spa的思路,而是借鉴了WebComponent的思想,通过CustomElement结合自定义的ShadowDom,将微前端封装成一个类WebComponent组件,从而实现微前端的组件化渲染。并且由于自定义ShadowDom的隔离特性,micro-app不需要像single-spa和qiankun一样要求子应用修改渲染逻辑并暴露出方法,也不需要修改webpack配置,是目前市面上接入微前端成本最低的方案。

特点

  • 上手简单:使用方式类似 iframe
  • 侵入性低:对原代码几乎没有影响
  • 组件化:基于 webComponents 思想实现微前端
  • 功能丰富:js沙箱、样式隔离、元素隔离、预加载、数据通信、静态资源补全等一系列完善的功能。
  • 轻量的体积:≈10kb (gzip)
  • 零依赖:不依赖于任何第三方库
  • 兼容所有框架

# wujie

实现方式:基于 WebComponent 容器 + iframe 沙箱

特点

  • 多应用同时激活在线
    • 框架具备同时激活多应用,并保持这些应用路由同步的能力
  • 组件式的使用方式
    • 无需注册,更无需路由适配,在组件内使用,跟随组件装载、卸载
  • 应用级别的 keep-alive
    • 子应用开启保活模式后,应用发生切换时整个子应用的状态可以保存下来不丢失,结合预执行模式可以获得类似ssr的打开体验
  • 纯净无污染
    • 无界利用iframe和webcomponent来搭建天然的js隔离沙箱和css隔离沙箱
    • 利用iframe的history和主应用的history在同一个top-level browsing context来搭建天然的路由同步机制
    • 副作用局限在沙箱内部,子应用切换无需任何清理工作,没有额外的切换成本
  • 性能和体积兼具
    • 子应用执行性能和原生一致,子应用实例instance运行在iframe的window上下文中,避免with(proxyWindow){code}这样指定代码执行上下文导致的性能下降,但是多了实例化iframe的一次性的开销,可以通过 preload 提前实例化
    • 体积比较轻量,借助iframe和webcomponent来实现沙箱,有效的减小了代码量
  • 开箱即用
    • 不管是样式的兼容、路由的处理、弹窗的处理、热更新的加载,子应用完成接入即可开箱即用无需额外处理,应用接入成本也极低

# 综合对比

对比 single-spa 类WebComponent WebComponent + iframe
框架 qiankun micro-app wujie-micro
ie ✅,自动切换成iframe
接入成本 较低
开箱即用 Yes
数据通信机制 props addDataListener props、window、eventBus
js沙箱 ✅,iframe来实现js沙箱
样式隔离 ✅,webcomponent来实现页面的样式元素隔离
元素隔离
静态资源地址补全
预加载
keep-alive
应用共享同一个资源
应用嵌套
插件系统
子应用不改造接入
内置降级兼容处理

从框架特性来看,wujie> micro> qiankun 从稳定程度来看,qiankun > micro>wujie 从接入成本来看,qiankun > micro>wujie 从更新时间来看,micro > qiankun>wujie

结合后台现有功能

  • 全局组件 - vue项目使用
  • 全局指令 - vue项目使用
  • 全局函数Vue.prototype.xx共享 - vue项目使用
  • 动态路由 - 主项目及子项目使用
  • 权限 - 通用
  • 低代码 - 通用
  • 通用的工具函数(不区分库)单独处理
  • 公共库 比如 lodash dayjs

qiankun

  • 通过主应用和子应用通信,可以解决Vue.prototype.xx
  • 其他需要通过单独引入的方式解决

micro-app

  • 通过主应用和子应用通信,可以解决Vue.prototype.xx
  • 其他需要通过单独引入的方式解决

wujie

  • 通过主应用和子应用通信,可以解决Vue.prototype.xx
  • 其他需要通过单独引入的方式解决
  • 应用共享 可以解决lodash dayjs等公共库 共享的问题

综合来看,wujie更加适合用来改造现有后台项目

# 参考资料

关于微前端架构的几种技术选型,看这篇就够了 (opens new window)

接入成本最低微前端框架:京东零售micro-app (opens new window)

微前端与 Monorepo 的架构设计 (opens new window)

深入调研了微前端,还是 iframe 最香 (opens new window)

基于 iframe 的微前端框架 —— 擎天 (opens new window)

【第2689期】将微前端做到极致-无界方案 (opens new window)

Why Not Iframe (opens new window)

微前端框架 之 single-spa 从入门到精通 (opens new window)

微前端框架 之 qiankun 从入门到源码分析 (opens new window)

微前端将微服务思想延伸到前端开发 (opens new window)

可能是你见过最完善的微前端解决方案 (opens new window)

微前端的核心价值 (opens new window)