微前端:将不同功能按照不同的维度拆分成多个子应用,通过主应用来加载这些子应用。重点在于拆分,之后是合并。
微前端解决的问题:
- 不同团队(技术栈不同)同时开发一个应用
- 每个团队开发的模块都可以独立开发,独立部署
- 实现增量迁移
iframe实现微前端:
- 微前端最简单方案,通过iframe加载子应用
- 通信可以通过postMessage进行通信
- 完美的沙箱机制自带应用隔离 缺点:用户体验差(弹框只能在iframe中,在内部切换刷新会丢失状态)
Web Components实现微前端:
- 将前端应用程序分解为自定义HTML元素。
- 基于CustomEvent实现通信
- ShadowDOM天生的作用域隔离(缺点:浏览器支持问题、学习成本、调试困难、修改样式困难等)
Single-spa实现微前端:
- Single-spa通过路由劫持实现应用的加载(采用SystemJs),提供应用间公共组件加载+公共业务逻辑处理。子应用需暴露固定钩子 bootstrap、mount、unmount 接入协议。
- 基于props 父子应用间通信
- 无沙箱机制,需实现自己实现js沙箱+css沙箱。(缺点:学习成本、无沙箱机制、需对原有的应用进行改造、子应用间相同资源重复加载问题)
Module federation实现微前端:
- 通过联盟模块,将组件进行打包导出使用
- 共享模块的方式进行通信
- 无css沙箱+js沙箱(缺点:需webpack5)
依赖复用问题:
- 创建共享模块,独立打包部署到CDN上,通过加载应用时传入,或在子应用中引入。
- 通过联盟模块(需webpack5)进行打包处理公共资源。
- 两个应用之间加载资源的ip地址相同,即可复用(http缓存)
应用之间的组件复用问题:
- 应用中,将共享的组件进行单独打包,加载应用时进行传入。
Vite支出问题:
- 基于vite构建的项目中,含有 import、export 并没有被转码,导致直接报错。解决方案:vite打包后在生产环境下(umd格式)介入。
qiankun嵌套问题:
- 避免多重沙箱嵌套,子应用中需要关闭沙箱。
css沙箱不完美:
- strictStyleIsolation完全隔离问题,样式无法传递到子应用中。
- experimentalStyleIsolation 子应用dom结构插入到body中,样式无法生效。
- 会移除 globalState、addGlobalUncaughtErrorHandler\shadowDOM样式隔离方案。
micro-app中,关于WebComponent:
- 自定义元素(Custom element):允许用户自定义
- ShadowDOM样式隔离,是它的一部分
- 支持组件的特点、插槽、生命周期、属性 都是组件的特点
- 兼容性不好,IE不支持
- 支持vite、scss
template标签是浏览器内置的,默认不显示。
Shadow DOM含义与作用:
- 创建封闭的、隔离的DOM树,主要作用是,将DOM树的一部分与常规的DOM树隔离开,防止css和js从主文档影响到shadow tree的内容。 主要作用:样式隔离、脚本隔离、封装功能(可将HTML结构、css、js封装在一个独立的组件内,有助于创建可重用、可维护的组件,提高代码模块化)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadow DOM Example</title>
</head>
<body>
<div id="myComponent">I'm the host element.</div>
<script>
const host = document.getElementById('myComponent');
// 创建一个 shadow tree 并将其附加到 host 元素上
const shadow = host.attachShadow({ mode: 'open' });
// 在 shadow tree 内添加内容
const paragraph = document.createElement('p');
paragraph.textContent = 'I\'m inside the shadow tree!';
shadow.appendChild(paragraph);
</script>
</body>
</html>
host 元素通过 attachShadow 方法创建了一个 shadow tree,并在 shadow tree 内添加了一个段落元素.