微前端框架篇一,了解qiankun

  • ① 前置知识补充
    • Ⅰ 什么是微前端?
    • Ⅱ 什么是JS CSS沙箱?
    • Ⅲ 什么是spa单页面应用?
    • Ⅳ SystemJS 与 import-html-entry
    • Ⅴ 现有的微前端方案
  • ② 了解single-spa 微前端框架
  • ③ 了解qiankun框架

① 前置知识补充

Ⅰ 什么是微前端?

微前端是一种将复杂单体应用拆分为多个小型独立前端应用,然后将这些小应用按需加载并集成到主应用的技术方案。
每个子应用都有自己的 JavaScript 和 CSS 代码。

Ⅱ 什么是JS CSS沙箱?

Ⅲ 什么是spa单页面应用?

单页Web应用(single page web application,SPA),就是只有一张Web页面的应用。所有页面都来回在这张页面上切换。

所以很容易暴漏出来单页面应用的两个缺点。

单页面SPA的两种路由形式:

Hash与History

本质区别:
Hash:锚点。通过锚点跳到对应位置
History:History栈。通过history.pushState或者history.replaceState向栈内维护信息,并跳转到对应位置。

Ⅳ SystemJS 与 import-html-entry

SystemJS是一个模块加载器,用于在浏览器和Node.js环境中加载JavaScript模块。它提供了动态导入加载模块的功能,使得开发者可以按需加载代码,提高应用程序的性能和响应速度。

import-html-entry 做的就是把如上代码中的 js、css 通过 fetch 拉取出源代码并内嵌到这个 html 中,变为一个包含内嵌 js、css 源码的 html 文件。

  1. SystemJS 不仅是个模块加载工具更是有一套标准的模块规范,single-spa 赖 SystemJS 规范通过JS Entry 实现微应用、微模块的加载。
  2. import-html-entry只支持 umd 的 js 文件,qiankun 通过 import-html-entry解析 html 模板分析资源 实现 HTML Entry 的方式加载 微应用。

Ⅴ 现有的微前端方案

1.iframe
iframe大家都很熟悉,通过iframe实现的话就是每个子应用通过iframe标签来嵌入到父应用中,iframe具有天然的隔离属性,各个子应用之间以及子应用和父应用之间都可以做到互不影响。但是iframe保护性太强了,导致了很多问题

  • url不同步,如果刷新页面,iframe中的页面的路由会丢失。
  • 全局上下文完全隔离,内存变量不共享。
  • UI不同步,比如iframe中的页面如果有带遮罩层的弹窗组件,则遮罩就不能覆盖整个浏览器,只能在iframe中生效。
  • 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。

比如我们新建个html,里面用iframe嵌入一个200*200的element-ui页面

当我们登陆element-ui,并且打开table页面后,刷新整体html页面。element-ui又会回到主页

html的内存与iframe中的不共享

我打开element-ui的loading,只能在200*200的区域显示,整体html没法显示

并且慢

2.single-spa

3.qiankun

② 了解single-spa 微前端框架

为啥要了解single-spa,是因为qiankun 是一个基于 single-spa 的微前端。由single-spa优化而来的库

single-spa 微前端框架主要就完成了一件事:就是在 url 变化的时候,加载、卸载对应的子应用

single-spa 长期开发后,会遇到的问题:

③ 了解qiankun框架

1. 打包逻辑的问题

一般我们会结合 SystemJS 来用,简化加载的逻辑,但是依然要知道子应用有哪些资源要加载,子应用打包逻辑变了,这里加载的方式就要跟着变

能不能把这个加载过程给自动化了呢?

比如我根据 url 加载子应用的 html,然后解析出其中的 JS、CSS,自动去加载。

qiankun 就是按照这个思路来解决的:

它会加载入口 html,解析出 scripts、styles 的部分,单独去加载,而其余的部分,会做一些转换之后放到 dom 里。 (HTML Entry)

2. JS、CSS 沙箱

子应用之间肯定要实现隔离,不能相互影响,也就是要实现 JS 和 CSS 的隔离。single-spa 没有做这方面的处理,而 qiankun 实现了这个功能。

JS 的隔离也就是要隔离 window 这个全局变量,其余的不会有啥冲突,本来就是在不同函数的作用域执行的。

qiankun 实现 window 隔离有三种思路:

  • 快照,加载子应用前记录下 window 的属性,卸载之后恢复到之前的快照
  • diff,加载子应用之后记录对 window 属性的增删改,卸载之后恢复回去
  • Proxy,创建一个代理对象,每个子应用访问到的都是这个代理对象

一般常用的还是第三种 Proxy 的思路

qiankun 实现 CSS 的隔离有两种思路:

  • 严格的样式隔离模式,为每个微应用的容器包裹上一个 shadow dom 节点,从而确保微应用的样式不会对全局造成影响
  • 实验性的方式,通过动态改写 css 选择器来实现,可以理解为 css scoped 的方式

3.应用间的状态管理

多个子应用、子应用和主应用之间自然有一些状态管理的需求,qiankun 也实现了这个功能。

  • 主应用里做全局状态的初始化定义子应用获取全局状态的方法 getGlobalState 和全局状态变化时的处理函数 onGlobalStateChange
  • 子应用里可以通过参数拿到 global state 的 get、set 方法:

蚂蚁官方文章