qiankun源码解读笔记

154 阅读2分钟

微前端跟微服务的区别 微服务是将多个模块独自拆分成多个项目,独立部署在独立的服务主机上,服务与服务之间是解耦的 采用rpc进行交互

微前端是在开发阶段将多个依赖度不高的模块拆分成多个项目,独立打包,但最终还是会在同一个浏览器宿主上运行 原理就是 在主应用上设置子应用的挂载锚点 然后根据浏览器url监听判断要请求哪个子应用的资源,使用fetch可以请求子应用 整个document 然后再根据里面的script来请求子应用的静态资源 交互的方式采用的发布订阅模式

注册子应用的关键属性:name/entry/activeUrl

关键API: 1.registerApplication -single-spa提供 2.loadApp-- qiankun提供 核心api 3.importEntry-->html-import-entry提供 fetch(可以获取document/css/js) 4.fetchScript-->>fetch 5.createSandboxContainer

乾坤css隔离方式 隔离父子应用样式的污染 1.shadow dom strictStyleIsolation严格样式隔离

// 采用BEM 通过在根元素设置data-qiankun等属性 然后让子应用所有的class都加上这个前缀 // 从而实现主应用跟子应用的隔离 2.scopedCSS

js隔离方式 沙箱隔离 目的就是防止全局变量的污染 同时在子应用切换时全局对象是干净的 1.createSandboxContainer 2.window.Proxy

new ProxySandbox // 利用复制window-->fakeWindow 借助proxy对fakewindow增加set/get等对象监听方法 set方法中 借助了Map格式来存储原来的值以及新增的值 以便后续子应用销毁和重新进入时能正常恢复属性 也就是说子应用进来我要给他一个属于自己的全局对象,销毁时又要还原全局对象 3.defineProperty 支持给真实全局window设置属性 也支持给当前子应用的虚拟window对象设置属性

4.diff 快照

SnapshotSandbox 对于不支持proxy的低版本浏览器 采用快照的方式 进行真假window对象的值拷贝和恢复

常用的钩子函数: 子应用 bootstrap mount unmount

通过importEntry---》execScripts---》根据子应用名称获取绑定在全局对象上的钩子函数bootstrap、mount、unmount、update导出 不过子应用需要export出来

父子通信方式:发布订阅模式 1.initGlobalState 2.getMicroAppStateActions 3.onGlobalStateChange 4.setGlobalState 5.emitGlobal

// 触发全局监听 function emitGlobal(state: Record<string, any>, prevState: Record<string, any>) { Object.keys(deps).forEach((id: string) => { if (deps[id] instanceof Function) { deps[id](cloneDeep(state), cloneDeep(prevState)); } }); } deps[id] = callback; 注意这里的id就是子应用的AppinstanceId 实例id

场景:当子应用调用setGlobalState 改变全局state时 先做diff判断是否有真的更改 如果有则调用onGlobalStateChange传入的回调函数 emitGloba

类似依赖收集和调用

建议大家源码阅读方式可以是:先看入参 再看返回值 最后再看逻辑细节