前言:微前端现已是一个非常老到的范畴了,但开发者不论选用哪个现有方案,在适配本钱、款式隔绝、工作功用、页面白屏、子运用通讯、子运用保活、多运用激活、vite 结构支撑、运用同享等用户中心诉求都或存在问题,或无法供应支撑。本文供应一种依据 iframe 的全新微前端方案,完善的处理了这些中心诉求。

为什么还要造微前端结构

现在较老到的微前方案有 qiankun、micro-app、EMP 方案,下面别离剖析这三个微前端方案:

qiankun 方案

qiankun 方案是依据 single-spa 的微前端方案。

特征

  1. html entry 的方法引入子运用,比较 js entry 极大的下降了运用改造的本钱;
  2. 齐备的沙箱方案,js 沙箱做了 SnapshotSandbox、LegacySandbox、ProxySandbox 三套渐进增强方案,css 沙箱做了 strictStyleIsolation、experimentalStyleIsolation 两套适用不同场景的方案;
  3. 做了静态资源预加载才干;

缺少

  1. 适配本钱比较高,工程化、生命周期、静态资源路径、路由等都要做一系列的适配作业;
  2. css 沙箱选用严厉隔绝会有各种问题,js 沙箱在某些场景下实行功用下降严峻;
  3. 无法一同激活多个子运用,也不支撑子运用保活;
  4. 无法支撑 vite 等 esmodule 脚本工作;

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. 主、子运用的路由或许发生冲突;

结论

qiankun 方案对 single-spa 微前端方案做了较大的提高一同也遗留下来了不少问题长期没有处理; micro-app 方案对 qiankun 方案做了较多提高但依据 qiankun 的沙箱也相应会继承其存在的问题; EMP 方案依据 webpack 5 联邦编译则约束了其运用范围; 现在的微前端方案在用户的中心诉求上都没有很好的满足,有很大的优化提高空间。

无界方案

无界微前端方案依据 webcomponent 容器 + iframe 沙箱,可以完善的处理适配本钱、款式隔绝、工作功用、页面白屏、子运用通讯、子运用保活、多运用激活、vite 结构支撑、运用同享等用户的中心诉求。

文档地址,demo 地址,git 地址

下面就本钱、速度、隔绝、功用等多个方面进行论述。

本钱低

无界微前端的本钱非常低,首要体现在主运用的运用本钱、子运用的适配本钱两个方面。

主运用运用本钱

主运用运用无界不需求学习额定的知识,无界供应依据 vue 封装的 wujie-vue 和依据 react 封装的 wujie-react,用户可以当初一般组件相同加载子运用,以 wujie-vue 举例:

<WujieVue
  width="100%"
  height="100%"
  name="xxx"
  url="xxx"
  :sync="true"
  :fiber="true"
  :degrade="false"
  :fetch="fetch"
  :props="props"
  :plugins="plugins"
  :beforeLoad="beforeLoad"
  :beforeMount="beforeMount"
  :afterMount="afterMount"
  :beforeUnmount="beforeUnmount"
  :afterUnmount="afterUnmount"
></WujieVue>

子运用加载和一般 vue 组件加载并无二致,全部装备都收敛到组件的特色上。

子运用适配本钱

子运用首要需求做支撑跨域恳求改造,这个是全部微前端结构工作的前提,除此之外子运用可以不做任何改造就可以在无界结构中工作,不过此时工作的方法是重建方式。

子运用在无界中会依据是否保活、是否做了生命周期适配进入不同的工作方式:

将微前端做到极致-无界微前端方案

其中保活方式、单例方式、重建方式适用于不同的事务场景,就算复杂点的单例方式用户也只是需求做一点简略的生命周期改造作业,可以说子运用适配本钱极低。

速度快

无界微前端非常快,首要体现在首屏翻开快、工作速度快两个方面。

首屏翻开快

现在大部分微前端只能做到静态资源预加载,但是就算子运用全部资源都预加载完毕,比及子运用翻开时页面依然有不短的白屏时间,这部分白屏时间首要是子运用 js 的解析和实行。

无界微前端不只可以做到静态资源的预加载,还可以做到子运用的预实行。

预实行会阻塞主运用的实行线程,所以无界供应 fiber 实行方式,采纳相似 react fiber 的方法接连实行 js,每个 js 文件的实行都包裹在 requestidlecallback 中,每实行一个 js 可以返回呼应外部的输入,但是这个颗粒度是 js 文件,如果子运用单个 js 文件过大,可以通过拆包的方法下降体积抵达 fiber 实行方式效益最大化。

工作速度快

子运用的 js 在 iframe 内工作,因为 iframe 是一个天然的 js 工作沙箱,所以无需选用 with ( fakewindow ) 这种方法来指定子运用的实行上下文,然后防止因为选用 with 语句实行子运用代码而导致的功用下降,全体的工作功用和原生功用不同不大。

原生隔绝

无界微前端完成了 css 沙箱和 js 沙箱的原生隔绝,子运用不必担忧污染问题。

将微前端做到极致-无界微前端方案

css 沙箱隔绝

无界将子运用的 dom 放置在 webcomponent + shadowdom 的容器中,除了可继承的 css 特色外完成了运用之间 css 的原生隔绝。

js 沙箱隔绝

无界将子运用的 js 放置在 iframe(js-iframe)中工作,完成了运用之间 window、document、location、history 的完全解耦和隔绝。

js 沙箱和 css 沙箱连接

无界在底层选用 proxy + Object.defineproperty 的方法将 js-iframe 中对 dom 操作绑架代理到 webcomponent shadowRoot 容器中,开发者无感知也无需关心。

功用健壮

无界微前端的功用非常健壮,支撑子运用保活、子运用内嵌、多运用激活、去中心化通讯、生命周期、插件系统、vite 结构支撑、兼容 IE9、运用同享。

子运用保活

当子运用设置为保活方式,切换子运用后依然可以坚持子运用的情况和路由不会丢掉。

将微前端做到极致-无界微前端方案

子运用嵌套

无界支撑子运用多层嵌套,嵌套的运用和正常运用一致,支撑预加载、保活、同步、通讯等才干,需求留心的是内嵌的子运用 name 也需求坚持唯一性,否则将复用之前烘托出来的运用

多运用激活

无界支撑一个页面一同激活多个子运用而且坚持这些子运用路由同步的才干。

去中心化通讯

无界供应多种通讯方法:window.parent 直接通讯、props 数据注入、去中心化 EventBus 通讯机制:

  1. 子运用 js 在和主运用同域的 iframe 内工作,所以 window.parent 可以直接拿到主运用的 window 目标来进行通讯
  2. 主运用可以向子运用注入 props 目标,里面可以注入数据和方法供子运用调用
  3. 内置的 EventBus 去中心化通讯方案可以让运用之间便当的直接通讯

生命周期

无界供应完善的生命周期钩子供主运用调用:

  1. beforeLoad:子运用初步加载静态资源前触发
  2. beforeMount:子运用烘托前触发 (生命周期改造专用)
  3. afterMount:子运用烘托后触发(生命周期改造专用)
  4. beforeUnmount:子运用卸载前触发(生命周期改造专用)
  5. afterUnmount:子运用卸载后触发(生命周期改造专用)
  6. activated:子运用进入后触发(保活方式专用)
  7. deactivated:子运用脱离后触发(保活方式专用)

插件系统

无界供应健壮的插件系统,便当用户在工作时去批改子运用代码然后防止将适配代码硬编码到库房中。

将微前端做到极致-无界微前端方案

无界插件首要才干如下:

  1. html-loader 可以对子运用 template 进行处理
  2. js-excludes 和 css-excludes 可以排除子运用特定的 js 和 css 加载
  3. js-before-loaders、js-loader、js-after-loaders 可以便当的对子运用 js 进行自定义
  4. css-before-loaders、css-loader、css-after-loaders 可以便当的对子运用 css 进行自定义

vite 结构支撑

无界子运用工作在 iframe 中原生支撑 esm 的脚本,而且不必担忧子运用工作的上下文问题,因为子运用读取的就是 iframe 的 window 上下文,所以无界微前端原生支撑 vite 结构。

将微前端做到极致-无界微前端方案

运用同享

一个微前端系统或许一同工作多个子运用,不同子运用之间或许存在相同的包依托,那么这个依托就会在不同子运用中重复打包、重复实行构成功用和内存的浪费。

无界供应一种工程上的战略结合无界的插件才干,可以有用的处理这个问题(其他微前端结构也可以做到),这儿以一个场景举例:主运用运用到了 ant-design-vue,子运用 A 也运用到了相同版其他 ant-design-vue。

主运用:

1、批改主运用的 index.js,将同享包挂载到主运用的 window 目标上

// index.js
import Antdv from "ant-design-vue";
// 将需求同享的包挂载到主运用大局
window.Antdv = Antdv;

2、加载子运用时注入插件,将主运用的 Antdv 赋值到子运用的 window 目标上

<WujieVue name="A" url="xxxxx" :plugins="[{ jsBeforeLoaders: [{ content: 'window.Antdv = window.parent.Antdv' }] }]">
</WujieVue>

子运用: webpack 设置 externals

module.exports = {
  externals: {
    "ant-design-vue": {
      root: "Antdv",
      commonjs: "Antdv",
      commonjs2: "Antdv",
      amd: "Antdv",
    },
  },
};

如果子运用需求独自工作可以参看文档

总结

无界微前端选用 webcomponent + iframe 的来加载子运用,具有本钱低、速度快、原生隔绝、功用健壮等一系列利益,在满足用户中心诉求的一同让运用微前端的体会就像运用一般组件相同简略,极大的下降了运用门槛。

无界现已开源 ,欢迎 star ⭐️⭐️⭐️

结构具体原理可以检查文章