沙箱类型
SnapshotSandbox:记录 window 对象,每次 unmount 都要和微应用的环境进行 DiffLegacySandbox:在微应用修改 window.xxx 时直接记录 Diff,将其用于环境恢复ProxySandbox:为每个微应用分配一个 fakeWindow,当微应用操作 window 时,其实是在 fakeWindow 上操作
隔离原理 import-html-entry
- 把要执行 JS 代码放在一个立即执行函数中,且函数入参有 window, self, globalThis
- 给这个函数 绑定上下文 window.proxy
- 执行这个函数,并 把上面提到的沙箱对象 window.proxy 作为入参分别传入
其它方案比较
iframe
特点
- 接入比较简单
- 隔离非常稳完美
不足
- dom割裂感严重,弹框只能在iframe,而且有滚动条
- 通讯非常麻烦,而且刷新iframe url状态丢失
- 前进后退按钮无效
qiankun
qiankun 方案是基于 single-spa 的微前端方案。
特点
- html entry 的方式引入子应用,相比 js entry 极大的降低了应用改造的成本;
- 完备的沙箱方案,js 沙箱做了 SnapshotSandbox、LegacySandbox、ProxySandbox 三套渐进增强方案,css 沙箱做了 strictStyleIsolation、experimentalStyleIsolation 两套适用不同场景的方案;
- 做了静态资源预加载能力;
不足
- 适配成本比较高,工程化、生命周期、静态资源路径、路由等都要做一系列的适配工作;
- css 沙箱采用严格隔离会有各种问题,js 沙箱在某些场景下执行性能下降严重;
- 无法同时激活多个子应用,也不支持子应用保活;
- 无法支持 vite 等 esmodule 脚本运行;
无界微前端
特点
- 接入简单只需要四五行代码
- 不需要针对vite额外处理
- 预加载
- 应用保活机制
不足
- 隔离js使用一个空的iframe进行隔离
- 子应用axios需要自行适配
- iframe沙箱的src设置了主应用的host,初始化iframe的时候需要等待iframe的location.orign从'about:blank'初始化为主应用的host,这个采用的计时器去等待的不是很悠亚。
通信
ts
// 子应用发送事件
window.dispatchEvent(
new CustomEvent('micro-event', {
detail: { type: 'login' },
})
)
// 主应用监听
window.addEventListener('micro-event', handler)