场景一:常规子应用接入(基于 Umi/Webpack)
在这个场景中,主应用和子应用通常都是基于 UmiJS 或标准的 Webpack 构建。
1. 主应用配置
主应用需要在路由中注册子应用,并在配置文件中指明子应用的真实访问地址(区分开发环境和生产环境)。
路由配置 (routes.ts)
添加子应用的路由匹配规则,注意路径后面的 /* 是必须的:
typescript
export default[
// ...其他路由
{
path: '/iocPage/*',
name: 'ioc大屏',
layout: false,
microApp: 'app1', // 这里的 microApp 名字必须与下面 config 中配置的 name 保持一致
microAppProps: {
autoSetLoading: true,
},
},
];
开发环境配置 (config.develop.ts)
开发环境下,entry 直接指向子应用本地启动的服务地址:
typescript
import { defineConfig } from 'umi';
export default defineConfig({
qiankun: {
slave: {},
master: {
apps:[
{
name: 'app1',
entry: 'http://192.168.2.12:8111' // 子应用本地测试环境地址
}
],
},
},
});
生产环境配置 (config.production.ts)
生产环境下,entry 通常指向 Nginx 或后端的代理路径:
typescript
import { defineConfig } from 'umi';
export default defineConfig({
qiankun: {
slave: {},
master: {
apps:[
{
name: 'app1',
entry: '/ioc/' // 生产环境的后端/Nginx代理路径
}
],
},
},
});
访问地址演示: 部署后,通过
http://192.168.2.120:9080/iocPage/home即可访问该子应用。
2. 子应用(app1)配置
基础配置 (config.ts)
开启 qiankun 插件支持:
typescript
import { defineConfig } from 'umi';
export default defineConfig({
base: '/',
qiankun: {
slave: {},
master: {}
}
});
生产环境配置 (config.production.ts)
由于生产环境主应用通过 /ioc/ 代理访问子应用资源,因此必须配置 publicPath:
typescript
import { defineConfig } from 'umi';
export default defineConfig({
// publicPath 需同主应用 config.production.ts 中的 entry 保持一致
publicPath: '/ioc/',
});
项目配置 (package.json)
确保项目名称配置正确,这会作为 qiankun 识别的标识之一:
json
{
"name": "ioc"
}
场景二:Vite 项目作为子应用接入
由于 Vite 默认的 ESM 模块加载方式与 Qiankun 目前基于代码包裹的沙箱机制存在冲突,因此接入 Vite 子应用需要借助 vite-plugin-qiankun 插件。
1. 主应用配置增加 Vite 子应用
与场景一类似,主应用仍需增加路由和应用注册信息。
路由配置:
typescript
{
path: '/policyMatchPage/*',
name: '政策匹配',
layout: false,
microApp: 'app2',
microAppProps: {
autoSetLoading: true,
},
}
主应用注册配置:
typescript
qiankun: {
slave: {},
master: {
apps:[
// ...之前的 app1
{
name: 'app2',
entry: '/policyMatch' // 生产环境后端代理路径
}
],
},
}
2. Vite 子应用(app2)配置
首先需要安装对应的插件:
bash
npm install vite-plugin-qiankun qiankun -S
Vite 构建配置 (vite.config.js)
需要引入插件、配置跨域、并修改 build 产物格式:
javascript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import md from 'vite-plugin-md';
import qiankun from 'vite-plugin-qiankun';
export default defineConfig({
// 生产环境配置为代理路径,开发环境为 '/'
base: process.env.NODE_ENV === 'production' ? '/policyMatch/' : '/',
plugins:[
vue({
include: [/\.vue$/, /\.md$/], // 让 Vite 处理 .md 文件
}),
md(),
// 'app2' 必须与主应用注册的 name 一致
qiankun('app2', {
useDevMode: true
}),
],
server: {
port: 5173,
cors: true, // 必须开启跨域,主应用才能动态 fetch 拉取资源
origin: 'http://localhost:5173',
headers: {
'Access-Control-Allow-Origin': '*',
},
},
build: {
rollupOptions: {
output: {
format: 'umd' // 配合 qiankun 的模块加载
}
}
},
});
入口文件修改 (main.js)
Vite 子应用不再通过导出生命周期函数的方式,而是通过 renderWithQiankun 进行生命周期的劫持和渲染:
javascript
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
let app = null;
function render(props = {}) {
const { container } = props;
app = createApp(App);
app.use(router);
// 判断是作为子应用挂载到主应用 DOM 内,还是独立运行
app.mount(container ? container.querySelector('#app') : '#app');
}
// 核心:判断是否在 Qiankun 环境内
if (qiankunWindow.__POWERED_BY_QIANKUN__) {
renderWithQiankun({
bootstrap() {
console.log('===qiankun bootstrap===');
},
mount(props) {
console.log('===qiankun mount===', props);
render(props);
},
unmount(props) {
console.log('===qiankun unmount===');
if (app) {
app.unmount();
app = null;
}
},
update(props) {
console.log('===qiankun update===');
}
});
} else {
// 独立运行
render();
}
路由配置修改 (router.js)
Vue Router 的 history 模式需要根据环境动态设置 base 路径:
javascript
import { createRouter, createWebHistory } from "vue-router";
import { qiankunWindow } from "vite-plugin-qiankun/es/helper";
import routes from './routes'; // 你的路由表
const router = createRouter({
// 当在微前端环境下时,基础路径需设为主应用中配置的路由路径
history: createWebHistory(
qiankunWindow.__POWERED_BY_QIANKUN__ ? '/policyMatchPage/' : '/'
),
routes
});
export default router;
💡 总结与避坑指南
- 路由与 PublicPath 对应关系 :主应用的路由 Path(例如
/iocPage/*)决定了子应用 Router 的base;而主应用的entry代理地址(例如/ioc/)决定了子应用构建时的publicPath或 Vite 的base。这两者不要混淆。 - Vite 接入的坑 :原生 Qiankun 对 Vite 的支持不完善,千万不要忘了引入
vite-plugin-qiankun并按需调整入口文件生命周期的写法。 - 跨域问题 :子应用的
server配置中一定要加上cors: true以及Access-Control-Allow-Origin: '*',否则主应用在开发环境下 fetch 子应用资源会报跨域错误。