webcomponent
微前端:将产品的各个功能模块作为一个个独立的应用系统,然后将这些模块整合起来组装成完整的产品。
具体使用 https://qiankun.umijs.org/zh/guide/tutorial
注意:微应用需要配置打包格式和跨域;
- 打包格式:umd打包;
- 允许跨域:让基座加载微应用;
1 微前端架构有何价值?
- 技术栈无关;(优点)
普通的library是通过npm包引入,但是微应用library是通过script标签引入;
HTML entry - 微应用独立开发,部署(巨石应用解耦);(初衷)
- 增量升级(渐进式重构);
- 微应用状态隔离,运行时状态不共享;
沙箱设计;
2 为什么不使用iframe?
- URL不同步。浏览器刷新导致状态丢失、后退前进按钮无法使用(iframe内部跳转,url不做记录)。
- 主页面嵌入一个iframe,并在iframe内加载了另外一个网页;浏览器地址显示主页面的URL;而不是iframe内部网页的实际URL;
- 浏览器刷新导致iframe内部状态刷新;
微前端可以使用URL查询参数携带微应用的路由信息;也可以使用localStorage、sessionStorage保存用户登录状态、偏好设置等重要信息; - 针对“后退前进按钮无法使用”,可以使用面包屑导航、内嵌后退/前进按钮来导航;
- DOM结构不共享。
- 带遮罩层的弹框无法在整个应用中展示;
- 全局上下文完全隔离,内存变量不共享;微应用通信、微应用免登录都无法实现;
- 加载慢。每次微应用进入都需要资源重新加载;
3 基于single-spa路由劫持方案
通过劫持路由来做子应用的切换,接入方式需要融合自身的路由;
4 HTML Entry接入方式
实现了 import-html-entry
插件,允许以 html
文件为应用入口,通过html
解析器从文件中提取js
和css
依赖,并且通过 fetch
下载依赖。
const registerApps = [{name: 'app1',entry: 'http://localhost:8080',container: '#app',activeRule: '/app1',
}];
乾坤通过import-html-entry
请求 http://localhost:8080
,得到对应的html
文件,解析内部的所有 script
和 style
标签,依次下载和执行它们;
5 样式隔离
- shadowDom
为每个微应用的根节点创建一个 shadow root。最终整个应用的所有 DOM 将形成一棵 shadow tree;
shadowDom 的特点是,内部所有节点的样式对树外面的节点无效;
这种方案有缺陷,某些UI框架可能会生成一些弹出框直接改在到 document.body下,此时脱离了 shadow tree;所以样式仍然会对全局造成污染。
let fetchAppContent = `
<div id="qiankun"><style>div {color: red;}</style><div>我是子应用</div>
</div>
`;// 创建空div,将微应用填充到 div 中
const containerElement = document.createElement('div');
containerElement.innerHTML = fetchAppContent;// 找到子应用的根节点
const appElement = containerElement.querySelector('#qiankun');
let html = appElement.innerHTML;
appElement.innerHTML = '';// 开启沙箱
let shadow = appElement.attachShadow({ mode: 'closed' });
shadow.innerHTML = html;document.body.appendChild(appElement);
- CSS Modules
CSS Modules
6 JS沙箱
全局变量/事件不冲突;
参考 乾坤JS沙箱设计