微前端

作者: shaokang 时间: December 13, 2023字数:2286

微前端

微前端架构是一种将单体应用拆分成多个子应用的架构模式,每个子应用可以独立开发、测试、部署。

微前端架构可以解决单体应用难以扩展、难以维护的问题。

更相关内容请参考:
qiankun 上的描述:什么是微前端
single-spa 上的描述:微前端概念

微前端的应用场景

  • 新旧业务系统隔离,新业务系统独立开发、测试、部署。
  • 系统需要动态插拔能力,比如系统权限管理、系统配置。
  • 内聚的单个产品中部分需要独立发布、灰度等能力。
  • 跨团队及企业级应用协作开发

更多描述参考:你可能并不需要微前端

微前端的技术栈

微前端框架:qiankun、single-spa、icestrak 等。

  • single-spa:single-spa 是一个用于管理多个单页应用的微前端框架。
  • qiankun:阿里出品的微前端框架,基于 single-spa。技术栈无关。
  • icestark:飞冰团队出品的微前端框架。 可视化开发,配置化能力。主应用必须是 React。

微前端的技术架构

在微前端架构下,有主应用和子应用两个基本角色。子应用负责具体的业务逻辑,主应用负责调度子应用。考虑到主应用的特殊性功能,为了保证整个框架的可用性,通常主应用不负责任何业务逻辑。

路由管理

主应用负责调度子应用,因此主应用需要具备路由管理和资源加载能力。

主应用维护路由表,提供 Router Map,当页面路由发生变化,主应用启动哪个子应用。

加载资源主要有两种方式:

  • HTML Entry:通过入口 HTML 文件来加载资源。

    子应用构建输出的是一个 HTML 文件,主应用通过加载这个 HTML 文件完成子应用的加载。(qiankun 内部使用的就是 Fetch HTML 的方式加载子应用)

  • JS Entry:通过 JS 文件来加载资源。

    将子应用的所有资源打包成一个入口文件

隔离

JS 沙箱(sandbox)

通常,子应用在运行期间会有一些污染性的副作用产生,比如全局变量、全局事件、定时器、网络请求、localStorage、全局 Style 样式、全局 DOM 元素等。为了保证应用能够稳定的运行且互不影响,需要提供安全的运行环境,能够有效地隔离、收集、清除应用在运行期间所产生的副作用,也就是沙箱的设计目标。

有两种沙箱的设计思路。一种是快照模式,另一种是虚拟机(virtual machine)模式。

快照模式

所谓快照模式,就是将启动子应用之前,对当前环境打一个快照,子应用退出之后,再重新加载这个快照来恢复环境。

在实现层面,我们可以针对每一种副作用设计一个 save 方法保存当前状态,在设计一个 load 方法来加载保存的状态。

框照模式的缺陷是对操作的顺序要求非常严格,当页面有多个子应用的时候,快照沙箱就会有多个实例存在,此时不同顺序的 save 和 load 会产生问题。

VM(虚拟机)模式

虚拟机想必大家都听说过,是一种计算机系统的仿真器,通过软件模拟具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。使用虚拟机就跟使用真实的计算机一样。

NodeJS 中也提供了 VM 模块,不过不同于传统的 VM,它并不具备虚拟机那么强的隔离性,并没有模拟完整的硬件系统,仅仅将指定代码放置了特定的上下文中编译并执行,无法用来执行不可信来源的代码。

基本原理:

let code = `(function(document, window){ /* 代码逻辑 */ })`(
    new Function('document', 'window', code)(fakeDocument, fakeWindow)
);

下面借助于 Proxy,我们可以轻松的对当前的执行上下文进行劫持,创建新的执行上下文。下面的代码展示了如何劫持 window 对象。

const varBox = {};
const fakeWindow = new Proxy(window, {
    get(target, key) {
        return varBox[key] || window[key];
    },
    set(target, key, value) {
        varBox[key] = value;
        return true;
    },
});

const code = `(function(window) {
  window.a = '111';
  console.log(window.a);
})`;

const fn = new Function('window', code);
fn(fakeWindow);

VM 模式的沙箱,可以有效的解决子应用之间、主子应用之间各种副作用的有效隔离问题。qiankun 的沙箱模式就是 VM 模式。

aliyun 团队的 browser-vm

样式隔离

  • CSS-Modules 技术来保持样式隔离。
  • BEM (Block Element Modifier) 命名约定项目前缀,通过 PostCSS 插件实现。
  • css-in-js 方案,比如 styled-components。
  • Shadow DOM 实现真正意义上的样式隔离,要考虑兼容性。

业界大厂的一些实践经验