Appearance
qiankun
概念
如何处理子应用的资源的, 如 JS、css
主要借助于 import-html-entry去将子应用的入口 html 文件转换成以 template、script、css 为核心的对象(提取出入口 html 中的静态 script 和 css 链接),然后将子应用的静态 script 和 css 资源通过 JS 执行加载
如何处理子应用的 JS 沙箱执行环境
其核心是通过 Proxy 拦截的方式去处理 window 对象,当子应用中访问或者赋值了 window 就会触发 Proxy 的 get 和 set 方法,对于 get 类型的如果子应用没有赋值那就访问 parentWindow ,赋值了就是使用子应用本身的
- set 类型: 使用 Map 缓存子应用 window 的信息
核心代码:
样式的隔离
- Web Components 的 shadow DOM(影子 DOM) 去进行子应用样式的隔离 CSS
- 实验性质的 strictStyleIsolation , 类似于 Vue 的 scoped
在加载子应用的时候 在根节点上添加了一个 data-qiankun的属性,对于通过子应用加载的 CSS 资源都在其样式前统一加上 div[data-qiankun="xxx"]的前缀
问题:
但是对于我们子应用中有很多组件其插入的目标不是子应用根节点 而是整个应用的 body 下面,如 dialog message 等,那么这时候子应用的样式隔离就失效了。
处理方法:
- 对于我们历史的模块: 我们是将所有的应用都添加了一个统一的前缀,需要修改公共组件样式的时候 需要使用这个统一的前缀修改
提供了一个 scss 的生成统一命名规则的函数
对于新的应用: 我们是使用的 Webpack5 的模块联邦模式,将我们的公共组件打包提供了一个统一入口文件 ,在子应用初始化的进行全局引入(虽然损耗了一些性能,但是不需要一个个引入了)
另外因为我们兼容的 Vue2 和 Vue3 且使用的不同的 UI 组件库 element-ui 和 element-plus,其中 element-plus 的很多组件样式定义跟 element-ui 相同但是内容不同, 导致了子应用影响了父应用的样式。
问题
- 子应用改造大
因为需要其他团队的配合,所以他们有些时候来不及改造,所以当时对于他们这种问题,我们在主应用上也通过获取路由的类型去判断加载模式:
- 乾坤微前端
- iframe
- 本地存储的问题
提供了统一的缓存工具,通过获取 config 中应用名称去生成统一的前缀
应用通信
我们是使用的 qiankun 内置的通信功能,借助发布订阅者模式实现通信的 (initGlobalState , onGlobalStateChange)
微前端架构
- 路由分发
主要借助于后端 nginx 的反向代理的功能,将请求路由发送到对应的应用上
问题: 切换应用需要从新加载资源
- 前端微服务化
通过设计应用的加载机制、通信方式 ,在一个应用内去加载对应应用的资源
- iframe 容器化
借助于 iframe
- 应用组件化
借助于 Web Components 技术,来构建跨框架的前端应用。
qiankun
micro-app
wujian
