2022-03-08-微前端qiankun实践

1、什么是微前端?为什么微前端方案?
2016 年底在 ThoughtWorks 技术雷达中提出,将多个独立的前端应用聚合在一起组成一个全新的应用,各个应用之间彼此独立,互不干扰,应用内高内聚,应用间松耦合;对于用户来说就是一个完整的应用,但是在技术角度上是由一个个独立的应用组合组合而成;
- 拆分、聚合
- 源码交付,自由组合 – 拆
- 应用接入 – 合
- 需求体量较大,避免巨石应用 – 拆
2、什么是 qiankun、为什么 qiankun?
- qiankun 是一个基于 single-spa 的微前端实现库,解决了应用加载,以及 js/css 污染问题,更简单好用。
- 方案成熟可靠、口碑较好,部门内部也有不少项目生产实践
- 接入简单,不会对原有工程造成很大“破坏”。
- 避免巨石应用,方便应用接入
- 与 emp 相比更适合当前技术底座
3、带来怎样的收益,价值在哪里?
- 技术栈无关、易扩展:主框架不限制接入应用的技术栈,项目无限扩展
- 独立开发、独立部署:微应用仓库独立,前后端可独立开发,独立部署互不干扰
- 增量升级:微前端是一种非常好的实施渐进式重构的手段和策略
- 对团队来说,快速实践产出文档,形成组织过程资产
4、缺点
- 依赖不共享,重复加载资源
- 通过主应用共享依赖,子应用独立运行时需要启动主应用
1. qiankun 本地实践
1.1 SwitchyOmega+whistle 代理
前言:前端开发过程中经常会遇到需要对请求做拦截,然后通过代理工具或者其他方式转发到指定的服务器上。最常见的场景就是在单点登录的情况下,需要用域名来访问,带上登录 token,后端才能识别成合法的用户请求。下文介绍一下 chrome 插件 SwitchyOmega 和基于 nodejs 的代理工具 whistle 的使用方法
- whistle
whistle(读音[ˈwɪsəl],拼音[wēisǒu])基于 Node 实现的跨平台 web 调试代理工具,类似的工具有 Windows 平台上的 Fiddler,主要用于查看、修改 HTTP、HTTPS、Websocket 的请求、响应,也可以作为 HTTP 代理服务器使用,不同于 Fiddler 通过断点修改请求响应的方式,whistle 采用的是类似配置系统 hosts 的方式,一切操作都可以通过配置实现,支持域名、路径、正则表达式、通配符、通配路径等多种匹配方式,且可以通过 Node 模块扩展功能。
1 | |
作为 chrome 的浏览器插件,安装后可以随时方便地使用。支持设置不同的场景模式,并且可以按照预定规则进行自动切换场景。直接在 chrome 网上应用店搜索就可以安装:
项目分为三大层,底层调度层,核心层和业务层。
- 底层调度层:主要借助 single-spa 做应用的调度,加载,卸载;qiankun 主要提供 js 隔离,样式隔离,以及应用注册和应用通信功能等上层功能和业务无关
- 核心层:主要接入 qiankun 框架,抽离出系统中的公共模块,例如登录注册,头部 header、侧边菜单 sidebar 等功能,负责鉴权、全局事件处理,应用分发等
- 业务层:主要负责业务,根据主系统的要求,做系统的改造,接入微前端
1.2 项目配置
将普通的项目改造成 qiankun 主应用基座,需要进行四步操作:
- 当前 qiankun 版本 “qiankun”: “^2.4.10”,
- 创建微应用容器 - 用于承载微应用,渲染显示微应用;
- 注册微应用 - 设置微应用激活条件,微应用地址等等;
- 创建子应用 - 微前端接入配置;
- 启动 qiankun - 主应用基座中启动。
1.2.1 创建微应用容器
app.vue 中通过$route.name判断是否为项目路由
1 | |
1.2.2 注册微应用
vue.config.js改造配置文件
用于给主应用接入时进行注册,对应主应用注册子应用时的 registerMicroApps 中的某一个自入口的 name
1 | |
- src/qiankun/config.js 子应用注册信息
1 | |
- 注册子应用信息
1 | |
1.2.3 创建子应用
- 子应用导出钩子函数
1 | |
2. 依赖共享优化
虽然 qiankun 微前端方案,能带来应用独立部署独立开发的好处,但是独立部署时,各子应用将重复引入相同依赖包,使项目整体包体积。这里可以将 chunk-vendor 中的依赖包通过 webpack 的 externals 忽略,再通过外链方式引入 html 模板中,依赖包可通过 copy-webpack-plugin 从 node_modules 取出。
- 复用主应用公共依赖
- 子应用间共享依赖
具体实现
1. 主应用提取”公共“依赖
1 | |
2. 主应用外链引入
1 | |
3. main.js 加载子应用前注入依赖
1 | |
4. 主应用下发
1 | |
4. 子应用打包忽略公共依赖
1 | |