基于umi4使用的微前端
前言
在上一篇umi4的文章中简单学习了umi4框架的使用,接下来继续使用umi4相关的东西。达到对umi4的进一步理解。
微前端
微前端是一种架构风格,它将不同的前端应用组合在一起,形成一个整体。微前端的核心思想是将前端应用拆分成更小的、独立的部分,每个部分都可以独立开发、部署和运行。
微前端的优势
- 独立开发:每个微前端应用可以独立开发,互不干扰。
- 独立部署:每个微前端应用可以独立部署,互不干扰。
- 独立运行:每个微前端应用可以独立运行,互不干扰。
如何使用微前端
在umi4中使用微前端,使用qiankun
库来实现。但是在umi4中使用基于qiankun
的微前端,需要使用umi-plugin-qiankun
插件。具体文档可以参考@umijs/plugin-qiankun(这个插件是支持umi3的,但原理一样)。由于使用的是umi4 max来新建的项目,其中已经内置了umi-plugin-qiankun
插件,所以可以直接使用。如果是umi4,那么需要安装@umijs/plugins
插件,然后使用qiankun
插件。具体使用方式在下面会有介绍。
微前端项目结构
一般来说微前端项目会有一个主应用和多个子应用。主应用负责管理子应用的加载和运行,子应用负责具体的业务逻辑。
主应用
主应用是整个微前端项目的入口,用来加载和管理子应用。这里使用umi4 max新建一个主应用。
npx create-umi@latest micro-main
新建项目后,开启此项目为微前端的主应用。修改.umirc.ts
文件,开启qiankun
插件。
export default defineConfig({
...
qiankun: {
master: {},
},
...
});
启动主应用,访问http://localhost:8000
,可以看到主应用的页面。然后配置子应用。
umi4主应用配置子应用
配置子应用有两种方式
如果是固定不变的子应用地址,可以配置在主应用的
.umirc.ts
文件中。如果是动态变化的子应用地址,可以配置在主应用的
src/app.tsx
文件中。配置在主应用的
.umirc.ts
文件中
qiankun: {
master: {
apps: [
{ name: 'micro-sub1', entry: 'http://localhost:8001' },
],
},
},
- 配置在主应用的
src/app.tsx
文件中
先开启主应用的qiankun
插件。
export default defineConfig({
...
qiankun: {
master: {},
},
...
});
然后在src/app.tsx
文件中配置子应用。
// src/app.ts
export const qiankun = {
apps: [
{
name: 'micro-sub1',
entry: 'http://localhost:8001',
},
],
}
当然也可以两种方式同时使用,固定不变的放在配置文件中,动态变化的放在src/app.tsx
文件中。
使用umi4创建子应用
使用umi4 max新建子应用
npx create-umi@latest micro-sub1
然后把项目设置为子应用。修改.umirc.ts
文件,开启qiankun
插件。
export default defineConfig({
...
qiankun: {
slave: {},
},
...
});
启动子应用,访问http://localhost:8001
,可以看到子应用的页面。但是不出意外的话肯定会出意外,果不其然报错了,如图
通过报错得知是需要设置package.json
文件中的name
为一个值。设置为micro-sub1
后,再次启动子应用,访问http://localhost:8001
,可以看到子应用的页面。那是为什么需要设置name
呢?文档没有说,那只能去社区找答案了。突然看到插件有一个文档有提及
虽然这个插件是支持umi3的,那大概umi4中的插件实现方式类似,去看看源码,因为umi4使用的乾坤插件@umijs/plugins/dist/qiankun
。这个是接下来踩的坑,先说一下。去这个文件里看看能不能找到原因。找到源码相关仓库umijs/plugins。相关插件在plugin-qiankun。找到了原因,需要用package.json中的name
来标识子应用的base。看图
至此,找到报错原因了,设置之后就可以正常启动了。
使用umi4新建子应用
npx create-umi@latest micro-sub2
选择简单模板,如图
开启子应用,修改.umirc.ts
文件,开启qiankun
插件。这里就有点坑了,因为'@umijs/plugin-qiankun
插件并不支持umi4,所以需要继续尝试了。经过一番尝试和看文档,发现如果umi中没有使用max版本,那么需要安装@umijs/plugins
插件,然后使用qiankun
插件。是这样使用的看下面:
export default defineConfig({
...
plugins: [
'@umijs/plugins/dist/qiankun',
],
qiankun: {
slave: {},
},
...
});
文档可是一笔带过,但是实际操作起来还是有点坑的。其他问题同上。就不展开说了。
引用子应用并使用
从umi4的官网看到主应用使用子应用有三种方式
- 路由绑定引入子应用。
<MicroApp />
组件引入子应用。<MicroAppWithMemoHistory />
组件引入子应用。
路由绑定引入子应用
在主应用的配置文件.umirc.ts
文件中,配置子应用的路由。何时使用:
- 子应用包含完整的路由切换逻辑时。
- 父子应用路由相互关联时。
routes: [
{ name: 'micro-sub1', path: '/micro-sub1/*', microApp: 'micro-sub1' },
],
启动主应用,访问http://localhost:8000/micro-sub1/home
,可以看到子应用的页面。
这里有两个需要注意的地方
- 子应用的路由需要和子应用的
base
一致。 - 子应用的路由需要用
*
通配符,这个是和umi3不一样的地方。
<MicroApp />
组件引入子应用
何时使用:
- 子应用包含完整的路由切换逻辑时。
- 父子应用路由相互关联时。
一个子应用为一个页面引入的组件,需要使用<MicroApp />
组件。所以先在主应用的src/pages
目录下新建一个页面。
// src/pages/microSub1/index.tsx`
import { MicroApp } from 'umi'
export default function MicroSub1() {
return <MicroApp name="micro-sub1" />
}
然后就像正常配置页面路由一样配置路由,但是注意路径也得和子应用的base
一致。
routes: [
{ name: 'micro-sub1', path: '/micro-sub1', component: '@/pages/microSub1' },
],
还有需要注意的是使用该方式引入子应用时,父子应用的路由将一一对应。例如,当父应用路由为 /some/page
时,子应用路由同样为 /some/page
。切换子应用路由时,父应用将同步切换。
如果父应用的路由包含前缀,可以通过配置 base
属性保证父子应用的路由正确对应。例如,父应用路由为 /prefix/router-path/some/page
时,我们希望子应用的路由为 /some/page
,可以修改代码如下:
import { MicroApp } from 'umi'
export default function Page() {
return <MicroApp name="micro-sub1" base="/prefix/router-path" />
}
<MicroAppWithMemoHistory />
组件引入子应用
通过 组件加载(或卸载)子应用。何时使用:
- 仅使用子应用的指定路由时。
- 父子应用路由相互独立时。
<MicroAppWithMemoHistory />
组件是 <MicroApp />
组件的变体,您需要显式提供 url
属性作为子应用的路由。当父应用的路由发生变化时,子应用的路由不会改变。
现在,我们想在父应用的某个组件内部引入 micro-sub1
子应用,子应用的路由为 /micro-sub1/home
,可以编写代码如下:
import { MicroAppWithMemoHistory } from 'umi'
export default function Page() {
return <MicroAppWithMemoHistory name="micro-sub1" url="/micro-sub1/home" />
}
小结
因为这里都是围绕着umi4来做的微前端,所以其他技术栈的微前端的接入就不展开了,如果有需要可以参考qiankun
的文档。如果有问题欢迎留言讨论,如果有需要其他方式接入要求的同学多的话,可以考虑写一篇其他技术栈的微前端接入。如果觉得文章对你有帮助欢迎点个赞。