@umi/max
内置了 Qiankun 微前端插件,它可以一键启用 Qiankun 微前端开发模式,帮助您轻松地在 Umi 项目中集成 Qiankun 微应用,构建出一个生产可用的微前端架构系统。
什么是微前端
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
特性
(1)基于 single-spa 封装,提供了更加开箱即用的 API。
(2)技术栈无关,任意技术栈的应用均可 使用/接入,不论是 React/Vue/Angular/JQuery 还是其他等框架。
(3)HTML Entry 接入方式,让你接入微应用像使用 iframe 一样简单。
(4)样式隔离,确保微应用之间样式互相不干扰。
(5)JS 沙箱,确保微应用之间 全局变量/事件 不冲突。
(6)资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
(7)umi 插件,提供了 @umijs/plugin-qiankun 供 umi 应用一键切换成微前端架构系统。
核心概念
- 主应用(基座):整个微前端应用的入口,负责加载和管理子应用。
- 子应用:独立的前端应用,可以独立开发、独立部署、独立运行。
- 生命周期:主应用和子应用之间的生命周期钩子,用于控制应用的加载、启动、卸载等过程。
- 沙箱:用于隔离子应用的 JavaScript 执行环境,防止子应用之间的冲突和污染。
- 应用间通信:主应用和子应用之间的通信机制,用于实现数据共享和事件传递。
实例
(1)umi创建父应用及子应用
创建文件夹test,vscode打开该文件夹,终端输入命令pnpm dlx create-umi@latest,输入父或子应用名称 回车,选择 简单应用程序 一项 回车,选择Npm客户端 回车,选择Npm注册表(建议使用taobao)回车,创建应用程序。
(2)配置父应用,注册子应用的相关信息
有两种方式:
- 插件注册子应用。
- 运行时注册子应用。
演示第一种方式--插件注册子应用,其余一种方式见:微前端
// .umirc.ts
import { defineConfig } from "umi";
export default defineConfig({
plugins: ['@umijs/plugins/dist/qiankun'],
qiankun: {
master: {
apps: [
{
name: 'zi-app', // 子应用的名称
entry: '//localhost:8001', // 子应用运行的 HTTP 地址
},
],
},
},
routes: [
{ path: "/", component: "index"},
{ path: "/docs", component: "docs" },
],
npmClient: 'pnpm',
});
注:该应用程序创建时模版选择的为简单应用程序,在普通的 Umi 应用中,默认不附带任何插 件 ,如需使用 Max 的功能(如 数据流、antd、qiankun’等),需要手动安装插件并开启他们。
a. cd到当前文件夹下
b. 下载 @umijs/plugins 命令:pnpm add -D @umijs/plugins
c. 开启qiankun插件
(3)配置子应用,子应用需要导出必要的生命周期钩子,供父应用在适当的时机调用
// .umirc.ts
import { defineConfig } from "umi";
export default defineConfig({
plugins: ['@umijs/plugins/dist/qiankun'],
qiankun: {
slave: {},
},
routes: [
{ path: "/", component: "index" },
{ path: "/docs", component: "docs" },
],
npmClient: 'pnpm',
});
这样,微前端插件会自动在项目中创建好 Qiankun 子应用所需的生命周期钩子和方法
注:同(2)下载插件开启qiankun插件
(4)引入子应用
-
路由绑定引入子应用。
-
<MicroApp />
组件引入子应用。 -
<MicroAppWithMemoHistory />
组件引入子应用。
演示第一种方式--路由绑定引入子应用,其余两种方式见:微前端
// .umirc.ts
import { defineConfig } from "umi";
export default defineConfig({
plugins: ['@umijs/plugins/dist/qiankun'],
qiankun: {
master: {
apps: [
{
name: 'zi-app',
entry: '//localhost:8001',
},
],
},
},
routes: [
{ path: "/", component: "index",
routes:[ //二级路由
{
path: '/zi-app/*', // 带上*通配符意味着将 /zi-app/ 下所有子路由都关联给微应用zi-app
microApp: 'zi-app',
},
]
},
{ path: "/docs", component: "docs" },
],
npmClient: 'pnpm',
});
配置好后,子应用的路由 base 会在运行时被设置为主应用中配置的 path
(5)父应用
创建二级路由跳转link
// layouts/index.tsx
import { Link, Outlet } from 'umi';
import styles from './index.less';
export default function Layout() {
return (
<div className={styles.navs}>
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/zi-app">二级</Link>
</li>
</ul>
<Outlet />
</div>
);
}
二级路由出口设置
// pages/index.tsx
import { Outlet } from 'umi';
export default function HomePage() {
return (
<div>
<span>xxxxxxxx</span>
<Outlet/>
</div>
);
}
(6)子应用--配置子应用名称
// package.json
{
"private": true,
"author": "xxxx",
"name": "zi-app", // 设置子应用的名称,与父应用配置的子应用名称相同
"scripts": {
"dev": "umi dev",
"build": "umi build",
"postinstall": "umi setup",
"setup": "umi setup",
"start": "npm run dev"
},
"dependencies": {
"umi": "^4.3.24"
},
"devDependencies": {
"@types/react": "^18.0.33",
"@types/react-dom": "^18.0.11",
"@umijs/plugins": "^4.3.24",
"typescript": "^5.0.3"
}
}
结果演示
前提:pnpm dev 启动父子应用
http://localhost:8000/
点击 二级 加载子应用 http://localhost:8000/zi-app