微前端
写在前面
中台部分业务模块多,单个仓库存放代码量多,阅读困难,难以维护,所以按照业务区分来拆分微前端,方便维护。本文介绍微应用的基本应用,并在最后介绍基本api。
links
什么是微前端
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
核心价值
技术栈无关
- 主框架不限制应用技术栈接入,微应用完全具备自主权
独立开发、独立部署
- 微应用仓库独立,前后端可以独立开发,部署完成后主框架自动完成同步更新
增量升级
- 在面对各种复杂场景时候,很难对一个已经存在的系统进行全量的升级或者重构,而微前端是一种非常好的实施渐进式重构的手段和策略
独立运行时
- 每个微应用之间状态隔离、运行时状态不共享
主应用
在对应的微应用仓库运行项目,在主应用注册相关微应用配置即可。
主应用不限制技术展 只需提供一个容器DOM,然后start即可
安装qiankun
$ yarn add qiankun # 或者 npm i qiankun -S
1、主应用 配置文件添加微应用注册配置
注册微应用并start
1 | // src/micro/config.ts |
这里我们是拆分中台应用,所以使用的语言都为vue,所以向微应用传递store、router、BaseRequest(axios请求封装),并且使用prefetchApps手动预加载指定的微应用静态资源
1 | import { registerMicroApps, prefetchApps } from 'qiankun' |
2、微应用 项目配置
微应用分为有 webpack
构建和无 webpack
构建项目,有 webpack
的微应用(主要是指 Vue、React、Angular)
这里只介绍有webpack构建且用vue框架时如何应用
1.新增 public-path.js
文件,用于修改运行时的 publicPath
。
注意:运行时的 publicPath 和构建时的 publicPath 是不同的,两者不能等价替代。
2.微应用建议使用history模式的路由,需要设置路由base,值和它的activeRule是一样
3.在入口文件最顶部引入public-path.js,修改并导出三个生命周期函数
4.修改webpack打包,允许开发环境跨域和umd打包
vue微应用
1.在src目录新增 public-path.js
文件
1 | if (window.__POWERED_BY_QIANKUN__) { |
2.这里在vue中使用hash路由
3.在入口文件最顶部引入public-path.js,修改并导出三个生命周期函数
- 在微应用的入口文件中导出相应的生命周期钩子
以Vue3.x的入口文件为例:src/main.ts
1 | import Vue, { createApp } from 'vue' |
4.修改webpack打包,允许开发环境跨域和umd打包
除了代码中暴露出相应的生命周期钩子之外,为了让主应用能正确识别微应用暴露出来的一些信息,微应用的打包工具需要增加如下配置:
1 | // webpack |
配置gitlab CI
// 参考subapp-admin gitlab-ci.yml
微应用单独编译打包
这里只做简单解释 具体需要先了解 gitlab ci/cd 极狐GitLab CI/CD 入门 | 极狐GitLab
1 | stages: |
常见api
registerMicroApps(apps, lifeCycles?)
参数
- apps -
Array<RegistrableApp>
- 必选,微应用的一些注册信息 - lifeCycles -
LifeCycles
- 可选,全局的微应用生命周期钩子
- apps -
类型
RegistrableApp
name -
string
- 必选,微应用的名称,微应用之间必须确保唯一。entry -
string | { scripts?: string[]; styles?: string[]; html?: string }
- 必选,微应用的入口。- 配置为字符串时,表示微应用的访问地址,例如
https://qiankun.umijs.org/guide/
。 - 配置为对象时,
html
的值是微应用的 html 内容字符串,而不是微应用的访问地址。微应用的publicPath
将会被设置为/
。
- 配置为字符串时,表示微应用的访问地址,例如
container -
string | HTMLElement
- 必选,微应用的容器节点的选择器或者 Element 实例。如container: '#root'
或container: document.querySelector('#root')
。activeRule -
string | (location: Location) => boolean | Array<string | (location: Location) => boolean>
- 必选,微应用的激活规则。- 支持直接配置字符串或字符串数组,如
activeRule: '/app1'
或activeRule: ['/app1', '/app2']
,当配置为字符串时会直接跟 url 中的路径部分做前缀匹配,匹配成功表明当前应用会被激活。 - 支持配置一个 active function 函数或一组 active function。函数会传入当前 location 作为参数,函数返回 true 时表明当前微应用会被激活。如
location => location.pathname.startsWith('/app1')
。
- 支持直接配置字符串或字符串数组,如
LifeCycles
type Lifecycle = (app: RegistrableApp) => Promise
; - beforeLoad -
Lifecycle | Array<Lifecycle>
- 可选 - beforeMount -
Lifecycle | Array<Lifecycle>
- 可选 - afterMount -
Lifecycle | Array<Lifecycle>
- 可选 - beforeUnmount -
Lifecycle | Array<Lifecycle>
- 可选 - afterUnmount -
Lifecycle | Array<Lifecycle>
- 可选
- beforeLoad -
用法
注册微应用的基础配置信息。当浏览器 url 发生变化时,会自动检查每一个微应用注册的
activeRule
规则,符合规则的应用将会被自动激活。示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import { registerMicroApps } from 'qiankun';
registerMicroApps(
[
{
name: 'app1',
entry: '//localhost:8080',
container: '#container',
activeRule: '/react',
props: {
name: 'kuitos',
},
},
],
{
beforeLoad: (app) => console.log('before load', app.name),
beforeMount: [(app) => console.log('before mount', app.name)],
},
);
prefetchApps(apps, importEntryOpts?)
参数
- apps -
AppMetadata[]
- 必选 - 预加载的应用列表 - importEntryOpts - 可选 - 加载配置
- apps -
类型
AppMetadata
- name -
string
- 必选 - 应用名 - entry -
string | { scripts?: string[]; styles?: string[]; html?: string }
- 必选,微应用的 entry 地址
- name -
用法
手动预加载指定的微应用静态资源。仅手动加载微应用场景需要,基于路由自动激活场景直接配置
prefetch
属性即可。示例
1
常见问题
1、Sass变量全局配置问题
场景:新项目安装node-sass、和sass-loder后,自动导入样式文件还是无法读取全局变量。
解决方案:还需安装sass-resources-loader 包
疑问:其他项目同样版本并无安装以上依赖照样可以运行。估计是Webpack版本兼容问题。
1 | // vue.config.js |
2、Vue路由切换卡顿问题
解决方案:watch route.name 而不是整个route响应式对象
3、样式隔离问题
解决方案:添加命名空间
4、打包缓存问题
解决方案:强制刷新,打包添加md5命名
Uncaught TypeError: Cannot read property ‘call’ of undefined · Issue #959 · webpack/webpack
5、KeepAlive方案
解决方案:子应用使用KeepAlive,主应用控制需要缓存的组件列表
[Feature Request] 主应用多页签切换不同子应用的页面状态保持 · Issue #361 · umijs/qiankun
6、Hash路由模式不触发unmont问题
解决方案:不同子项目才会触发,同子项目路由变更不触发
[Bug]似乎不支持hash路由 · Issue #118 · umijs/qiankun
7、子路由前缀相同时,路由切换报错
报错提示: https://single-spa.js.org/error/?code=31&arg=mount&arg=application&arg=subapp-market&arg=3000
解决方案:精确匹配路由规则即可