跳至主要內容

微前端概念

XinYang's Blog大约 6 分钟微前端

前言

以前只知道微前端的概念,但没有具体的了解过,最近正好因公司需求可以深入微前端。在微前端的架构上了解到有阿里的乾坤,腾讯的无界。本来简单记录介绍下微前端。

微前端是什么

微前端是一个多个团队独立发布功能的方式来共同构建现代化web应用的技术手段及方法策略。
通俗来讲,就是一个web应用中可以独立的运行另一个web应用。

微前端的应用场景:

  • 比如制作一个企业管理平台,把已有的采购系统和财务系统统一接入这个平台;
  • 比如有一个巨大的应用,为了降低开发和维护成本,分拆成多个小应用进行开发和部署,然后用一个平台将这些小应用集成起来;
  • 又比如一个应用使用vue框架开发,其中有一个比较独立的模块,开发者想尝试使用react框架来开发,等模块单独开发部署完,再把这个模块应用接回去。

一个完善的微前端框架应该具备哪些能力呢?

  • 子应用的加载和卸载能力
    页面需要从一个子应用切换到另一个子应用,框架必须具备加载、渲染、切换的能力
  • 子应用独立运行的能力
    子应用运行会污染全局的 window 对象,样式会污染其他应用,必须有效的隔离起来
  • 子应用路由状态保持能力
    激活子应用后,浏览器刷新、前进、后退子应用的路由都应该可以正常工作
  • 应用间通信的能力
    应用间可以方便、快捷的通信

微前端的收益呢?

  • 技术栈无关
    主框架不限制接入应用的技术栈,微应用具备完全自主权

  • 独立开发、独立部署
    微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新

  • 增量升级
    在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略

  • 独立运行时
    每个微应用之间状态隔离,运行时状态不共享

微前端技术有哪些

目前微前端技术都是技术基于single-spaopen in new window的,而国内也已经有人进行对其二次封装。知道的有以下这些:

iframe方案

采用iframe优点:

  • 非常简单,使用没有任何心智负担
  • web应用隔离的非常完美,无论是js、css、dom都完全隔离开来

采用ifame缺点:

  • 路由状态丢失,刷新一下,iframe的url状态就丢失了
  • dom割裂严重,弹窗只能在iframe内部展示,无法覆盖全局
  • web应用之间通信非常困难
  • 每次打开白屏时间太长,对于SPA 应用来说无法接受

乾坤方案

qiankun 方案是基于 single-spa 的微前端方案。

特点:

  1. html entry 的方式引入子应用,相比 js entry 极大的降低了应用改造的成本;
  2. 完备的沙箱方案,js 沙箱做了 SnapshotSandbox、LegacySandbox、ProxySandbox 三套渐进增强方案,css 沙箱做了 strictStyleIsolation、3. 3. 3. experimentalStyleIsolation 两套适用不同场景的方案;
  3. 做了静态资源预加载能力;

不足:

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

底层原理 js沙箱使用的是proxy进行快照然后用用 with(window){} 包裹起来 with内的window其实就是proxy.window 我们声明变量 var name = '小满' 实际这个变量挂到了proxy.window 并不是真正的window css沙箱原理 第一个就是shadowDom隔离 第二个类似于Vue的scoped [data-qiankun-426732]

micro-app 方案

micro-app 是基于 webcomponent + qiankun sandbox 的微前端方案。

特点:

  1. 使用 webcomponet 加载子应用相比 single-spa 这种注册监听方案更加优雅;
  2. 复用经过大量项目验证过 qiankun 的沙箱机制也使得框架更加可靠;
  3. 组件式的 api 更加符合使用习惯,支持子应用保活;
  4. 降低子应用改造的成本,提供静态资源预加载能力;

缺点:

  1. 接入成本较 qiankun 有所降低,但是路由依然存在依赖; (虚拟路由已解决)
  2. 多应用激活后无法保持各子应用的路由状态,刷新后全部丢失; (虚拟路由已解决)
  3. css 沙箱依然无法绝对的隔离,js 沙箱做全局变量查找缓存,性能有所优化;
  4. 支持 vite 运行,但必须使用 plugin 改造子应用,且 js 代码没办法做沙箱隔离;
  5. 对于不支持 webcompnent 的浏览器没有做降级处理;

EMP方案

EMP 方案是基于 webpack 5 module federation 的微前端方案。

特点:

  1. webpack 联邦编译可以保证所有子应用依赖解耦;
  2. 应用间去中心化的调用、共享模块;
  3. 模块远程 ts 支持;

不足:

  1. 对 webpack 强依赖,老旧项目不友好;
  2. 没有有效的 css 沙箱和 js 沙箱,需要靠用户自觉;
  3. 子应用保活、多应用激活无法实现;
  4. 主、子应用的路由可能发生冲突;

无界微前端方案

特点:

  1. 接入简单只需要四五行代码
  2. 不需要针对vite额外处理
  3. 预加载
  4. 应用保活机制

不足:

  1. 隔离js使用一个空的iframe进行隔离
  2. 子应用axios需要自行适配
  3. iframe沙箱的src设置了主应用的host,初始化iframe的时候需要等待iframe的location.orign从'about:blank'初始化为主应用的host,这个采用的计时器去等待的不是很优雅。