微前端原理&Garfish代码解读

225 阅读3分钟

近期又开始帮团队同学看基座的一些问题,突然想起之前记录的微前端原理,复习&水一篇文章

  • 入口

image.png

  • new Garfish

微前端子应用的生命周期为

  • 渲染阶段
    • 若入口类型为 HTML 类型,将开始解析和拆解子应用资源
    • 若入口类型为 JS,创建子应用的挂点 DOM
    • 主应用通过路由驱动或手动挂载的方式触发子应用渲染
    • 开始加载应用的资源内容,并初始化子应用的沙箱运行时环境
    • 判断入口类型
    • 将子应用存在”副作用“(对当前页面可能产生影响的内容)交由沙箱处理
    • 开始渲染子应用的 DOM 树
    • 触发子应用的渲染 Hook
  • 销毁阶段
    • 若路由变化离开子应用的激活范围或主动触发销毁函数,触发应用的销毁
    • 清除应用在渲染时和运行时产生的副作用
    • 移除子应用的 DOM 元素

最重要的几个节点

  • 加载器(Loader)
    • HTML 入口类型,拆解 HTML Dom、Script、Style
    • JS 入口类型,提供基础 Dom 容器
    • 负责注册平台侧提供的应用列表
    • 负责加载和解析子应用入口资源
    • 预加载能力
    • 解析子应用导出内容
  • 沙箱隔离(Sandbox)
    • 提供代码执行能力,收集执行代码时存在的副作用
    • 提供销毁收集副作用的能力
    • 支持沙箱多实例,收集不同实例的副作用
  • 路由托管(Router)
    • 解决不同应用间的路由不同步问题
    • 提供路由劫持能力,在主应用上管控子应用路由
    • 提供路由驱动能力来拼装完整的平台的能力
  • 子应用通信(Store)
    • 建立通信桥梁
    • 提供共享机制

资源加载

loader实现

资源加载都是先通过fetch下载源代码,然后根据不同文件类型进行处理。 常见的有html、js、css的loader

  • html loader 在fetch下载html文本后,通过document.createElement('html').inner(code)来生成node树,然后遍历树节点来获取特定的元素(如meta link style script),然后再加载这些js和css资源的内容
  • css loader 下载css文件后,在需要渲染template的时候创建style元素,将内容注入进style
  • js loader 下载js文件后,包裹new Function,注入proxyEnv,再eval执行

provider查找

微前端的子模块需要提供provider函数给底层进行执行,那我们在加载众多资源后如何才能找到这个provider函数呢? image.png

参考umd的打包代码,会将入口文件的exports属性赋值给module.exports或者window image.png

那么我们可以自定义一个exports对象去接收,或者在window上查找provider函数

沙箱隔离

snapshot快照模式

  • activate和deactivate时是触发patchLists里不同的对比方法 image.png

  • 全局变量patch。主要维护了原始对象、变更对象,拿原始对象的属性和目标对象对比,进行增加和删除,同时存储下变更 image.png

  • style patch 通过对比document.head下的节点,来进行变更和还原

  • event patch 代理window的addEventListener和removeEventListener函数,内部维系一个event注册map

  • interval patch 和event同理,代理+内部维护map

  • 其他patch history、webpackJsonp都是代理

vm虚拟机模式

snashot还是会存在污染window变量的问题,同时无法保证同时存在多个子应用之间的隔离 vm模式主要是通过proxy,将一个对象作为window的proxy,同时也对event、storage、timer、history等api进行代理 然后通过 new function(window,this)(proxyWindow)的方式运行,完成代码环境隔离

路由托管

路由的切换通常是通过pushState、replaceState方法,以及popState和hashchange事件来实现 所以可以对pushState、replaceState方法进行重写 && popstate hashchange事件进行代理,dispatch一个私有event,进行router的自管理

image.png

应用通信

参考eventEmitter

Garfish介绍见 mp.weixin.qq.com/s/L9wbfNG5f…