一、为什么会使用qiankun ???
1、一个后管平台迭代了很多版本之后,整个工程的体积很大,本地编译的速度很慢,而且经常是多人分别开发不同模块,不管哪个模块的改动,也需要整个工程重新进行编译、打包、部署。
2、技术选型独立
1、每个开发团队自行选择技术栈(Vue、React、Angular、Jquery),不受其他团队影响
2、业务独立:每个交付产物既可以独立使用,也可以融合成一个大型应用使用
3、样式隔离:父子应用之间、子应用之间不会有样式冲突、覆盖
3、当然qiankun也相对成熟
二、微前端介绍???
微前端不仅仅是"为了独立部署和兼容不同的技术栈",还有包含一些比如父子应用之间的值传递,路由监听等,让它们看着就是一个整体,一个应用。具体是这样子!
三、微前端的使用
参考链接1:记录使用 qiankun 遇到的一些问题 参考链接2:零基础带你基于vue2架构搭建qiankun父子项目微前端架构
四、微前端中教训
性能:
- 1、加重了浏览器的加载负担:引入微前端框架,浏览器加载页面时需要最先加载微前端框架代码,而后加载各个组件和MFA
- 2、为了减少页面加载时间,一方面需要借助工件最小化,Treeshaking,以及在Cloudfront
&浏览器等层面上的缓存等手段加快每一个JS脚本文件的加载速度;另一方面需要在确保功能完整的情况下,尽可能提高JS脚本并行加载能力。
操作复杂:
- 1、需要在开发中运行许多不同的应用程序以测试完成的体验
- 2、跟踪和调试问题需要跨全部系统 (页面跳转,需要启动多个模块)
- 3、跨系统进行版本控制
- 本质上讲,是通过前端的简单性换取整个系统(前端/后端)的复杂性。
五、微前端中遇到的问题?
1、咱们项目使用的微前端,每个模块可以单独发布,那么我A模块引用B模块的方法,发布A模块,不会报错嘛??
不会,因为在每次打包的时候都会将相关的依赖给加载过来,如果没有会报错
2、base基座路由只能用history模式吗?
history:由于 qiankun 是通过 location.pathname 值来判断当前应该加载哪个子项目的,所以需要给每个子项目注入不同的路由 path,而 hash 模式子项目路由跳转不改变 path,所以无影响,history 模式子项目路由设置 base 属性即可。
hash:如果主项目使用 hash 模式,那么得用 location.hash 值来判断当前应该加载哪个子项目,并且子项目都得是 hash 模式,还需要给子项目所有的路由都添加一个前缀,子项目的路由跳转如果之前使用的是 path 也需要修改,用 name 跳转则不用。
3、路由跳转问题???
不能直接使用 router-link跳转,而是用 history.pushState,
3.1、为什么不能使用router-link跳转???
http://localhost:8080/financepc/#/financePc/myDocuments?companyId=company240162259000000102 比如这个地址就是qiankun跳转financepc(registerMicroApps中的activeRule)路由配置,然后#后面开始渲染financePc路由下的页面,?后面是携带的参数
4、各模块之间通信问题??
4.1主应用新建一个actions.js文件
利用initGlobalState方法来定义全局变量(其属于qiankun的全局状态储存机制)并调用setGlobalState来存储需要传出的数据,子应用中使用onGlobalStateChange来接收
//actions.js 具体代码如下
import { initGlobalState } from 'qiankun'
const initialState = {}
const actions = initGlobalState(initialState)
export default actions
4.2、主应用配置需要传出的数据(调用setGlobalState)
4.3、子应用在mount生命周期中使用onGlobalStateChange来接收参数
export async function mount(props) {
console.log('应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法', props)
props.onGlobalStateChange((state) => {
console.log('子应用接收的参数', state)
console.log('子应用接收参数--menuId', state.menuId)
console.log('子应用接收参数--路由', JSON.parse(state.childrenRouter))
if (state.menuId) {
store.commit('SET_MENU_ID', state.menuId)
}
}, true)
render(props)
}
5、qiankun中样式处理?两个模块切换样式异常??如何处理??
模块跟模块之间如何解决??
默认情况下切换应用,他会采用动态样式表,加载的时候添加样式,删除的时候卸载样式
主应用跟子应用如何隔离??
1、(BEM)规范,就是在每个模块中定义唯一的Id名,特别弱—》css-modules,每次加载模块都动态生成一个前缀,在
start({
sandox:{
experimentalStyleIsolation: true // 临时解决方案增加前缀 div[data-qiankun='m-vue']
}
})
缺点:
如果使用 strictStyleIsolation 方案全局样式会丢失
ElementPlus ,子应用使用了 ElementUI ,如果使用 experimentalStyleIsolation 会导致子应用无法启动(应该是 Vue 不能找到挂载节点)
2、shadowDOM(影子DOM) 在video 标签中 的 快进 放大功能
缺点:兼容性不好,太封闭了,访问不到
js沙箱的概念 我的应用在切换的时候 可能window会被污染???
// vue window.m-vue
// react window.m-react
(会导致混乱) 除了对样式要隔离之外 还需要对我们的 js进行隔离
js的沙箱如何实现(经常问到) , 使用proxy代理,最后改的都是代理后的对象