# 微前端后台改造方案
# 背景
随着后台应用的迭代功能的新增,导致项目变的越来越大,进而出现这些问题。
- 构建速度越来越慢
- 应用越来越庞大,难以维护
- 不能单独回滚(同时上线的两个功能)
- 无法平台化
- 无法体验新技术带来的提升
# 微前端的概念
微前端是什么:微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。有一个基座应用(主应用),来管理各个子应用的加载和卸载。
基本原理 它的基本原理是将子应用的 JS、CSS 等静态资源加载到基座应用渲染,本质上这两个应用都是在同一个页面,只是渲染的区域不同,并通过一些手段防止多个应用之间的冲突。
# 微前端的优势
- 将没有关联的几个应用融合为一个应用
- 减少项目之间的耦合,提升项目扩展性。
- 项目可以单独维护,不受主框架影响
- 容易组合,可以将任意项目相互组合
# 微前端框架
框架名 | 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)
← 微信H5移动端真机调试 逆向抓包 →