你想知道的 qiankun 原理解读?

551 阅读5分钟

本文使用「署名 4.0 国际 (CC BY 4.0)」 许可协议,欢迎转载、或重新修改使用,但需要注明来源。

qiankun 官网:可能是你见过最完善的微前端解决方案🧐

我的理解 qiankun 能快速的支持大型微应用部署,上手成本低。无需关心子应用技术栈负担、支持 JS 环境隔离、样式隔离、预加载、应用的生命周期管理等。同时与一些 React 周边的技术栈结合使用会产生问题,需要结合这些库的实现和 qiankun 的实现分析产生问题的原因,这就要求对开发者的能力有较强的要求。

一、微前端概念

微前端是指存在于浏览器中的微服务。

微前端作为用户界面的一部分,通常由许多组件组成,并使用类似于React、Vue 和 Angular 等框架来渲染组件。每个微前端可以由不同的团队进行管理,并可以自主选择框架。虽然在迁移或测试时可以添加额外的框架,出于实用性考虑,建议只使用一种框架。

每个微前端都拥有独立的 git 仓库、package.json 和构建工具配置。因此,每个微前端都可以独立开发和部署,并且独立访问。

二、了解 single-spa 的使用

浏览器渲染过程

浏览器渲染网页的过程

主要是下面这 6 个过程,使 SPA 的子应用加载和卸载变得可控,我们可以在哪几个过程进行干预?

思考一下,single-spa 内部实现了哪些功能?

演示代码 🧑🏻‍💻

如果控制应用的加载能力,就要有控制 js 资源的是否加载的权力。js 脚本加载完后,同时可以控制我们应用的入口和退出函数(react 视图 mount 和 unmount)。

具备 SPA 应用能力,切换应用浏览器必然不能刷新。所以通过 history 控制路由的变化,根据 actveiWhen 的规则进行匹配,从而使用应用暴露出的协议方法(bootstrap、mount、unmount)控制应用生命周期。

所以 single-spa 内部主要实现了 控制应用加载的方法控制顶层路由。

single-spa 使用时会存在的问题?

  1. 使用不灵活,需要开发者自己决定 js 资源的加载
  2. 样式不隔离
  3. 应用环境不隔离,没有沙箱机制
  4. 子应用预加载
  5. 子应用状态恢复等

三、基于 single-spa 之上的 qiankun

qiankun 解决了我们什么问题?

  1. 基座提供全局状态和组件的能力
  2. 多 react、antd 版本共存
  3. 应用独立开发、独立维护和部署
  4. 业务可以快速复用产品能力(试着想一下,如果不采用微前端,AICOS 的产品怎么组合)

qiankun 的优势

简单 - 任意 js 框架均可使用,接入像 iframe 一样简单

完备 - 几乎包含后见微前端系统的基本能力,如样式隔离、沙箱隔离、资源预加载等

稳定 - 国内比较成熟的方案、经过蚂蚁内部大量系统验证

qiankun 的问题

改写原生方法 - 导致第三方库使用的问题(sc、react-router、地图)

排查问题难 - 功能不可用(没出现报错),需要对相关技术栈有全面的了解

qinakun 运行时流程图

image.png

四、源码部分

核心的方法

  1. registerMicroApps 注册微应用,以及初始化配置;

  1. loadApp 主要做了几个事情。

获取 html 中的执行函数、生成沙箱实例、传入沙箱代理实例、获取协议方法、导出 single-spa 需要的 parcelConfigGetter 配置生成器。

  1. Import-html-entry 解析 html 中的静态资源,缓存应用静态资源、导出 execScripts 执行函数。
  2. 初始化沙箱
  3. 暴露出 nginx
  1. createSandboxContainer 创建沙箱

根据不同配置、以及兼容不支持 Proxy 的沙箱实现。沙箱的 mount 和 unmount 过程中会重建和清除一些副作用

  1. start 启动应用

三种沙箱的实现

  1. SanpshotSanbox: **公用一个 window 对象,基于 diff 方式实现的沙箱,用于不支持 Proxy 的低版本浏览器。不支持多应用沙箱
  2. ProxySandbox: window 和 proxyWindow 彻底隔离,不用还原快照,作用域完全隔离。可支持多应用沙箱
  3. LeagcySandbox:同一时间只存在一个沙箱实例,window 和 proxyWindow 值同步,新增 map 记录新增的值,修改 map 记录上一次 window 的值(window 上存在,修改 map 中不存在),快照 map 记录实时的值。支持单例模式下使用代理沙箱

五、其他微前端解决方案

  1. iframe 可以直接加载其他应用,但无法做到单页导致许多功能无法正常在主应用中展示
  2. Nginx 配置多应用,也会刷新
  3. 字节跳动实现的 garfish 库,支持应用见依赖共享、可以获取和设置真实 Wndow 的值、开发者可以清除副作用等
  4. 无界微前端是一款基于 Web Components + iframe 微前端框架,具备成本低、速度快、原生隔离、功能强等一系列优点
  1. web Components 及 ESM 是浏览器提供给开发者的能力,能在单页中实现微前端,不过后者需要做好代码隔离,并且他们都是浏览器的新特性,都存在兼容性问题,微前端方面的探索也不成熟,只能作为面向未来的微前端手段
  2. EMP 作为最年轻微前端解决方案,也是吸收了许多web优秀特性才诞生的,它在实现微前端的基础上,扩充了跨应用状态共享跨框架组件调用远程拉取ts声明文件动态更新微应用等能力。同时,细心的小伙伴应该已经发现,EMP能做到第三方依赖的共享,使代码尽可能地重复利用,减少加载的内容