微前端
微前端架构是一种将单体应用拆分成多个子应用的架构模式,每个子应用可以独立开发、测试、部署。
微前端架构可以解决单体应用难以扩展、难以维护的问题。
更相关内容请参考:
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 实现真正意义上的样式隔离,要考虑兼容性。
业界大厂的一些实践经验
- 阿里 qiankun
- 字节 garfishjs
- 美团
- 阿里云 alfajs
- 飞冰 ice
- 京东 micro-app 基于 WebComponent
- 腾讯 wujie 基于 WebComponent + iframe