qiankun微前端学习笔记
qiankun微前端学习笔记
Junsqiankun 微前端学习笔记
仓库地址: https://github.com/Juns-g/qiankun-learn
参考链接:
介绍
什么是微前端
微前端的概念其实类似于后端的微服务架构,出发点就是把一个复杂的大应用分为多个子应用,每个子应用可以独立运行、开发、部署,从而达到分布式,多团队并行的项目需求。
微前端也有一个主应用称为基座项目,嵌入其他 n 个子应用,子应用之间相互独立,不过也可以相互通信
价值
技术栈无关
主框架不限制接入应用的技术栈,微应用具备完全自主权
独立开发、独立部署
微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
增量升级
在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
独立运行时
每个微应用之间状态隔离,运行时状态不共享
个人认为核心价值在于技术栈无关。由于历史原因,前端框架还是比较多的,jQuery
, Angular
, React
, Vue
,他们都有过大规模的应用,但是都不能保证谁笑到最后。不管是一个老项目,还是一个新项目,都需要考虑长远维护的问题,需要保证这套方案在 3 ~ 5 年还有生命力,但是目前很多前端框架/库有的也有过破坏性的更新,难以保证一年后,把所有依赖包都更新到最新版本还能正常运行。
实际上这种微前端的需求在 ToB 市场更加常见,ToC 软件少有活得过 3 年以上的,ToB 就常见多了,企业内部的中台后台的使用年限可以很长。同时企业软件的升级也会有很多麻烦,项目升级或者迁移绝对不是一个轻松的事情,因此,微前端这样的解决方案就很有价值,它能够实现代码平滑的迁移,以及确保在若干年后还能用上当时热门的技术栈。
所以说微前端最开始诞生的初衷,是为了给遗产项目续命。
架构姿势
秉承着核心价值为「技术栈无关」,那么在整个架构方案的是线上,就不应该违背这一原则,应用之间不应该有任何直接或间接的技术栈、依赖、以及实现上的耦合。
所以正确的微前端目标应该是:方案上和使用 iframe 一样简单,同时也解决的了 iframe 带来的体验问题
微前端方案对比
iframe
iframe 最大的特性就是提供了浏览器原生的硬隔离方案,不论是样式隔离、js 隔离这类问题统统都能被完美解决。但他的最大问题也在于他的隔离性无法被突破,导致应用间上下文无法被共享,随之带来的开发体验、产品体验的问题。
- url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
- UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中..
- 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
- 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。
其中有的问题比较好解决(问题 1),有的问题可以睁一只眼闭一只眼(问题 4),但有的问题我们则很难解决(问题 3)甚至无法解决(问题 2),而这些无法解决的问题恰恰又会给产品带来非常严重的体验问题。
简而言之就是 iframe 隔离太彻底了,带来了很多不便。
single-spa
链接:https://zh-hans.single-spa.js.org/docs/getting-started-overview/
最早出现的微前端框架,可以兼容很多技术栈
首先在基座中注册所有子应用的路由,当 URL 改变时就会去匹配,匹配到哪个子应用就去加载对应的。
相较于 iframe,single-spa 中基座和各个子应用之间共享一个全局上文,并且不存在 URL 不同步和 UI 不同步的情况,但是也有缺点:
- 没有实现 js 隔离和 css 隔离
- 需要修改大量的配置,不能开箱即用
qiankun
- 基于 single-spa 封装的,提供了更加开箱即用的 API
- 技术栈无关
- HTML Entry 的方式接入,像用 iframe 一样简单
- 实现了样式隔离和 js 隔离
- 资源预加载,在浏览器空闲时加载未打开的微应用资源
实战
以仓库的 readme 为准,删库重开了,下面的属于是废弃的了
仓库地址: https://github.com/Juns-g/qiankun-learn
项目目录:
qiankun-learn |
- 基座(主应用):主要负责集成所有的子应用,提供一个入口能够访问所需要的子应用,尽量不要写复杂的业务逻辑
- 子应用:根据不同业务划分的模块,每个子应用都打包成
umd
模块的形式供基座来加载
基座
下载 qiankun,在入口 js 文件中写如下代码
import { registerMicroApps, start } from 'qiankun' |
api 使用见:registerMicroApps(apps, lifeCycles?)
react 子应用
使用 vite 创建,然后就是改造子应用的入口文件
import { createRoot } from 'react-dom/client' |
- 配置微应用的打包工具
官方没有提供 vite 支持,需要自己下载插件配置:vite-plugin-qiankun
import { defineConfig } from 'vite' |
尝试了几次失败了,暂时下放下,搞 vue 的试试
Vue 子应用
pnpm i vite-plugin-qiankun |
vite 配置文件
import { defineConfig } from 'vite' |
修改 main.ts
import { createApp } from 'vue' |
同时将 vue 子应用的 index.html 中的 app 改为 sub-vue-app,不然会出现俩个 id 是 app 的 div
不过也存在问题,挂载的时候会闪一下,预计是样式没有隔离的问题
qiankun 官方还没有支持 vite,引入的三方库似乎没有解决 js 隔离和样式隔离
明天再进行 react 子应用的处理,改成 webpack 创建 react 子应用