微前端框架

架构层级:系统架构 应用级 模块 代码

微前端:子应用调度(耦合) 共享 (巨石应用)单实例/多实例

架构质量:稳定性(回归) 健壮性(容错) 拓展性 维护性

微前端实现方式:

  1. Iframe -- 多域名鉴权问题

  1. web component --

  1. 自研框架 -- 定制化 独立通信机制 沙箱环境 首次加载资源大
    实现:路由分发 主应用控制路由匹配和子应用加载子应用实现功能
    主应用-- 注册子应用、加载渲染子应用、路由匹配、获取数据、通信

子应用-- 渲染、监听通信传递过来的数据

Micro-web微前端框架

主应用生命周期:

主应用 main 下的 util 中的 index.js 中,在 registerApp 中的 registerMicroApps 方法注册到微前端框架里,传入第二个参数生命周期,beforeLoad 是开始加载,mounted 是渲染完成,destoryed 是卸载完成

在 micro 下的 start.js 中,registerMicroApps 接收两个参数,appList 子应用参数列表和 lifeCycle 生命周期,然后通过 setMainLifecycle 设置主应用的生命周期

在 micro 下的 const 中 mainLifeCycle.js,lifecycle 是主应用的生命周期,getMainLifecycle 是获取主应用的生命周期,setMainLifecycle 是缓存主应用的生命周期

在micro 下的 util 中 index.js,findAppByRoute 查找上一个和下一个 app 里面的内容,isTurnChild 判断子应用是否做了切换,通过 window.__CURRENT_SUB_APP__ 判断当前路由以改变,修改当前路由,通过 window.__CURRENT_HASH__ 判断当前 hash 值是否改变

跳转时先将上一个子应用生命周期卸载,然后启动当前子应用的生命周期

在micro 下的 lifeCycle 中 index.js,在 lifecycle 中,prevApp 是获取到上一个子应用,卸载掉上一个子应用,nextApp 是获取到要跳转到的子应用,执行对应的子应用生命周期。若没有获取到下一个子应用,直接退出,后面的就不用执行。获取到上一个子应用,并且有它自己的生命周期,由其它子应用切换过来的,卸载掉上一个子应用。beforeLoad、mounted 和 destoryed 是主应用的生命周期,runMainLifeCycle 是运行主应用生命周期,等待所有的方法执行完成,subApp 是获取的是子应用的内容

获取子应用的html内容 子应用入口解析html并挂载到根元素进行渲染 解析其它dom/script

在micro 下的 loader 中 index.js,loadHtml 是加载 html 的方法,container 是第一个子应用需要显示在哪里,#id 内容,entry 是子应用的入口。parseHtml 是解析 html,在 fetchResource 后解析、加载、执行流程。通过 script.concat 处理 fetchedScripts,将得到且携带标签里面的内容、外部链接引入的内容结合到一起,构成子应用所有 script 的集合,在其它方法中将这些集合运行起来,得到完整的子应用渲染,最后将 dom、allScript 直接缓存,后面可以直接使用 cache,获取到对应的子应用。在 getResources 中,scriptUrl是 链接/src /href,script是写在 script 中的 js 脚本内容,dom 是需要展示到子应用上的 DOM 结构。deepParse 是深度解析,获取到所有 script 和 link 的链接、内容,先处理位于 script 中的内容,link 也会有 js 的内容,递归遍历进行处理

子应用生命周期改造

bootstrap mount unmount

微前端环境变量window.__MICRO_WEB__ == true,获取生命周期挂载到app上, 以sandBox暴露出去

快照沙箱(单实例)--应用于老版本浏览器中,代理window(共两层)->激活沙箱->销毁沙箱

代理沙箱(多实例) --激活沙箱->new Proxy(window,handler) 设置两个拦截方法 get() set() 获取到属性指向window -- (function) window.defaultValue[key] / window.target[key] -> 销毁沙箱

css样式隔离-- 三种方法 css modules / shadow dom / mimicss

css modules:webpack打包命名空间(略)

shadow dom:开启shadow dom模式(API):box1.attachShadow(init:{mode:’open’}) , appendChild添加到div容器, 新版本浏览器中支持

minicss: webpack插件loader打包输出不同的子应用单独css文件,子应用切换时会清空css的引入link,后再加载新的

父子组件通信-- 两种 props / customevent

props:依赖注入 - 主应用信息在组件中暴露出来(store) 生命周期mounted中传递app实例的参数对象,registerApp方法注入到子应用中,然后方法调用

customevent:事件监听on() window.addEventListener ,事件触发emit() new CustomEvent() window.dispatchEvent() detail可传递参数

子应用之间通信-- props通过父组件传递 / customevent

customevent : window.custom 先在一个子应用监听test2 再在另一个子应用监听到之后触发

全局状态管理-- 全局方法createSrore = (()=>{})() 接收初始数据initData为store ,其中定义一个方法getStore用于获取store , 定义第二个方法update 用于将store更新再通知到所有订阅者observers.forEach(async item=> await item(store,oldstore)),定义第三个方法 subscribe用于添加订阅者,暴露createStore携带三个方法。 主应用中获取 createStore() 挂到window.store= store, 子应用中获取 const storeData=window.store.getStore(), 然后可在子应用中进行store更新 window.store.update(value:{...storeData, a:1})

提高加载性能:两步缓存预加载

应用缓存-- 根据子应用name做缓存 psrseHtml=async (entry,name)=>{ 获取所有script资源 cache[name]=[dom,script]}

预加载-- 定义prefetch()方法获取其它子应用列表然后使用await Promise.all() ,在start.js中start()方法尾部执行prefetch(),这样会将其它未展示的子应用中的js资源保存到了当前的缓存对象中cache{}。

你可能感兴趣的:(前端,前端框架)