微前端实践(qiankun2.43.3 + umi3.5.41)
搭建应用(全 umi: 1 主 + 2 子)
环境配置
umi 基于react
qiankun 基于single-spa
新建umi工程:1主2子
版本依赖: node>10.13.0
配置国内源:tyarn
npm i yarn tyarn -g
tyarn -v
创建主应用
mkdir master-app && cd master-app && yarn create @umijs/umi-app && tyarn
yarn start
创建子应用 1
mkdir app1 && cd app1 && yarn create @umijs/umi-app && tyarn
yarn start
创建子应用 2
mkdir app2 && cd app2 && yarn create @umijs/umi-app && tyarn
yarn start
配置主应用
安装 umi 的 qiankun 插件
cd /master-app
yarn add @umijs/plugin-qiankun -D
/master-app/.umirc.ts (此处为带路由子应用方式,不带路由的子应用可用 MicroApp 组件装载方式)
import { defineConfig } from "umi";
export default defineConfig({
nodeModulesTransform: {
type: "none",
},
routes: [
{
path: "/",
component: "@/layouts/index",
// // 配置应用关联的路由
routes: [
{
path: "/app1",
microApp: "app1",
},
{
path: "/app2",
microApp: "app2",
},
],
},
],
fastRefresh: {},
qiankun: {
master: {
// 注册子应用
apps: [
{
name: "app1",
entry: "http://localhost:8001",
},
{
name: "app2",
entry: "http://localhost:8002",
},
],
},
},
});
/master-app/src/layouts/index.tsx
import React from "react";
import { Link } from "umi";
const Layout: React.FC = ({ children }) => {
return (
<>
<Link to="/app1">app1</Link>
<Link to="/app2">app2</Link>
{children}
</>
);
};
export default Layout;
配置子应用 app1 (app2 参考 app1)
安装 umi 的 qiankun 插件
cd /app1
yarn add @umijs/plugin-qiankun -D
/app1/.umirc.ts
添加属性 qiankun
export default defineConfig({
qiankun: {
slave: {},
},
});
完整代码
import { defineConfig } from "umi";
export default defineConfig({
nodeModulesTransform: {
type: "none",
},
routes: [{ path: "/", component: "@/pages/index" }],
fastRefresh: {},
qiankun: {
slave: {},
},
});
/app1/package.json
增加 name 命名项目
{
"name": "app1"
}
完整代码
{
"name": "app1",
"private": true,
"scripts": {
"start": "umi dev",
"build": "umi build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
"test:coverage": "umi-test --coverage"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,less,md,json}": ["prettier --write"],
"*.ts?(x)": ["prettier --parser=typescript --write"]
},
"dependencies": {
"@ant-design/pro-layout": "^6.5.0",
"react": "17.x",
"react-dom": "17.x",
"umi": "^3.5.41"
},
"devDependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@umijs/plugin-qiankun": "^2.43.3",
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.5.41",
"lint-staged": "^10.0.7",
"prettier": "^2.2.0",
"typescript": "^4.1.2",
"yorkie": "^2.0.0"
}
}
/app1/src/pages/index.tsx
修改内容
<h1 className={styles.title}>App1</h1>
完整代码
import styles from "./index.less";
export default function IndexPage() {
return (
<div>
<h1 className={styles.title}>App1</h1>
</div>
);
}
父子通信
主应用安装依赖 @umijs/preset-react
cd /master-app/src/app.ts
yarn add @umijs/preset-react -D
主应用传值(传动态值 masterState && 传静态值 testUmircProps)
/master-app/src/app.ts 父向子传值方式一:app.ts 传动态值 masterState
import { useState } from "react";
export function useQiankunStateForSlave() {
const [masterState, setMasterState] = useState({
testApptsProp: 123,
});
return {
masterState,
setMasterState,
};
}
/master-app/.umirc.ts 父向子传值方式二:.umirc.ts 传静态态值 testUmircProps
import { defineConfig } from "umi";
export default defineConfig({
nodeModulesTransform: {
type: "none",
},
routes: [
{
path: "/",
component: "@/layouts/index",
// // 配置应用关联的路由
routes: [
{
path: "/app1",
microApp: "app1",
},
{
path: "/app2",
microApp: "app2",
},
],
},
],
fastRefresh: {},
qiankun: {
master: {
// 注册子应用
apps: [
{
name: "app1",
entry: "http://localhost:8001",
props: {
testUmircProps: 123, // 父向子传值方式二:.umirc.ts 传静态态值 testUmircProps
},
},
{
name: "app2",
entry: "http://localhost:8002",
},
],
},
},
});
子接收值
/app1/src/pages/index.tsx
import styles from "./index.less";
import { useModel } from "umi";
export default function IndexPage() {
const { masterState, setMasterState, testUmircProps } = useModel(
"@@qiankunStateFromMaster"
);
console.log("masterState.testApptsProp +++++ :", masterState.testApptsProp); // appts方式,可传动态值
console.log("testUmircProps +++++ :", testUmircProps); // umirc方式,只能静态传一次
const onClickChangeTestApptsProp = () => {
setMasterState({
...masterState,
testApptsProp: 321,
});
};
return (
<div>
<h1 className={styles.title}>App1</h1>
<div>testApptsProp:{masterState.testApptsProp}</div>
<div>testUmircProps:{testUmircProps}</div>
<button onClick={onClickChangeTestApptsProp}>修改testApptsProp</button>
</div>
);
}
/app2/src/pages/index.tsx
import styles from "./index.less";
import { useModel } from "umi";
export default function IndexPage() {
const { masterState, setMasterState, testUmircProps } = useModel(
"@@qiankunStateFromMaster"
);
return (
<div>
<h1 className={styles.title}>App2</h1>
<div>testApptsProp:{masterState.testApptsProp}</div>
</div>
);
}
子组件生命周期
/app1/src/app.ts
export const qiankun = {
// 应用加载之前
async bootstrap(props) {
console.log("app1 bootstrap", props);
},
// 应用 render 之前触发
async mount(props) {
console.log("app1 mount", props);
},
// 应用卸载之后触发
async unmount(props) {
console.log("app1 unmount", props);
},
};
...待续:不带路由的子应用可用 MicroApp 组件装载方式
...待续:本地开发环境不能加载静态资源问题解决
...待续:子应用为 umi4 发现的问题
...待续:多框架(vue3,vue2,react,umi)
参考
实践
- 动态装载:umi +qiankun 主应用动态装载子应用(路由)解决方案
- 全流程:umi3 + qiankun 搭建微前端
- 不带路由子应用:微前端-Vue3.0+qiankun 完整实例
- react18:qiankun+vue2+vue3+umi 微前端集成开发落地实践
- 非 umi 主应用:微前端 umi + qiankun 从搭建到部署的实践
- 带 cross-env:umi3 + qiankun 快速搭建微应用实践
- and pro 搭建 UMI + QIANKUN + ANTD 的微前端平台
- umi3 + qiankun 实现一个简单的微前端 demo | 🏆 技术专题第四期征文
- 微前端 umi + qiankun 从搭建到部署的实践
- nginx 部署相关:基于 qiankun 落地部署微前端爬”坑“记
- 多页签: 基于微前端 qiankun 的多页签缓存方案实践
- [搭建教程]手把手从 0 搭建微前端(umi+qiankun)
- umi+qiankun 微前端(2022/3/7 百分百成功搭建)
- qiankun 微前端引入 vite+vue3 项目子应用
- vue3 + 微前端(qiankun)学习笔记
- 使用 umi4+qiankun 搭建微前端项目
科普
- 目标是最完善的微前端解决方案 - qiankun 2.0
- 多页签:手把手带你在微前端(qiankun)中实现多页签功能(路由keepalive)
- 微前端框架 之 qiankun
- 涉及配置跨域:微前端应用(qiankun+umi+antd)
- 2 子 mui,1 子 vue: umijs/plugin-qiankun 微前端 记录
- 「微前端实践」umi 不同版本接入 qiankun,踩坑到解决的过程
- 基于 qiankun 的微前端实践
- 这可能是你见过最完善的微前端解决方案
- umi 之 qiankun 全局传值的三种解决方案
- [搭建教程]手把手从0搭建微前端(umi+qiankun
问题解决
- 在开发模式下,主应用加载微应用的图片等静态资源的代理: 【实践】使用 UMI + Qiankun 搭建主基座应用和微应用
- 微前端(qiankun)中,主应用无法加载子应用的静态资源
- 微前端 qiankun webpack 打包后静态资源路径 404 问题解决
- 路由相关:基于 Umi 探索微前端以及其融合方案
探究