Qiankun 微前端(React+Vue)基础速通
Qiankun 是基于 single-spa 的微前端框架,核心是主应用注册、子应用独立接入,技术栈无关,适合 React/Vue 混部或独立部署的业务拆分。以下是极简落地流程,覆盖主应用、React/Vue 子应用配置与通信。
📦 核心概念与前置准备
- 核心术语 :
- 主应用(Master):承载所有子应用的"容器",不限技术栈。
- 子应用(Micro App):独立开发/部署的 React/Vue 应用,需暴露生命周期。
- 生命周期:
bootstrap(初始化)、mount(挂载)、unmount(卸载)。
- 前置要求:Node.js 16+、React/Vue 基础、Webpack/Vite 配置基础。
🚀 快速上手(主应用 + React/Vue 子应用)
1. 主应用(以 React 为例)
步骤 1:安装依赖
bash
npm install qiankun --save
# 或 yarn add qiankun
步骤 2:配置子应用与启动
在主应用入口文件(src/main.jsx)注册子应用,指定路由匹配、挂载容器和入口地址:
jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { registerMicroApps, start } from 'qiankun';
import App from './App';
// 注册子应用:React子应用 + Vue子应用
registerMicroApps([
{
name: 'react-subapp', // 子应用唯一名称
entry: '//localhost:3001', // React子应用本地地址
container: '#subapp-container', // 挂载DOM节点
activeRule: '/react', // 路由匹配规则(访问/react加载该子应用)
props: { user: 'admin' }, // 向子应用传参
},
{
name: 'vue-subapp',
entry: '//localhost:8080', // Vue子应用本地地址
container: '#subapp-container',
activeRule: '/vue',
props: { role: 'user' },
},
]);
// 启动qiankun(开启预加载与沙箱)
start({
prefetch: true, // 预加载提升性能
sandbox: { strictStyleIsolation: true }, // 样式隔离避免冲突
});
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
步骤 3:添加挂载容器
在主应用的 App.jsx 中预留子应用挂载节点:
jsx
import { Link } from 'react-router-dom';
function App() {
return (
<div>
<nav>
<Link to="/">主应用首页</Link>
<Link to="/react">React子应用</Link>
<Link to="/vue">Vue子应用</Link>
</nav>
{/* 子应用挂载容器 */}
<div id="subapp-container" style={{ minHeight: '500px' }}></div>
</div>
);
}
export default App;
2. React 子应用配置
步骤 1:添加 public-path 配置
在 src 目录新建 public-path.js,解决子应用资源路径问题:
js
// 关键:动态设置publicPath,兼容主应用加载
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
步骤 2:修改入口文件(src/index.js)
导出 Qiankun 生命周期,支持独立运行与主应用加载:
jsx
import './public-path'; // 必须在顶部引入
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
// 渲染函数:支持主应用传入的container
function render(props = {}) {
const { container } = props;
const rootElement = container ? container.querySelector('#root') : document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
<BrowserRouter basename={window.__POWERED_BY_QIANKUN__ ? '/react' : '/'}>
<App user={props?.user} />
</BrowserRouter>
);
}
// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 暴露Qiankun生命周期
export async function bootstrap() {
console.log('React子应用初始化');
}
export async function mount(props) {
console.log('接收主应用参数:', props);
render(props);
}
export async function unmount(props) {
const rootElement = props.container ? props.container.querySelector('#root') : document.getElementById('root');
ReactDOM.unmountComponentAtNode(rootElement);
}
步骤 3:修改 Webpack 配置(支持 CORS)
- 若用
create-react-app,安装react-app-rewired覆盖配置; - 若用 Vite,添加
vite-plugin-qiankun插件。
示例(react-app-rewired) :
安装依赖:
bash
npm install react-app-rewired customize-cra --save-dev
新建 config-overrides.js:
js
module.exports = {
webpack: (config) => {
// 输出库格式,支持主应用加载
config.output.library = 'react-subapp';
config.output.libraryTarget = 'umd';
return config;
},
devServer: (configFunction) => {
return (proxy, allowedHost) => {
const config = configFunction(proxy, allowedHost);
// 允许跨域,主应用可访问
config.headers = { 'Access-Control-Allow-Origin': '*' };
config.port = 3001; // 与主应用entry端口一致
return config;
};
},
};
修改 package.json 的 scripts:
json
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build"
}
3. Vue 子应用配置(Vue3 + Vite 示例)
步骤 1:安装插件
bash
npm install vite-plugin-qiankun --save-dev
步骤 2:修改 vite.config.js
js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import qiankun from 'vite-plugin-qiankun';
// 子应用名称,与主应用注册一致
const useDevMode = process.env.NODE_ENV === 'development';
export default defineConfig({
plugins: [
vue(),
qiankun('vue-subapp', {
useDevMode, // 开发模式下使用独立路由
}),
],
server: {
port: 8080, // 与主应用entry端口一致
cors: true, // 允许跨域
},
build: {
lib: {
name: 'vue-subapp',
formats: ['umd'], // 输出umd格式,支持主应用加载
},
},
});
步骤 3:修改入口文件(src/main.js)
js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { renderWithQiankun } from 'vite-plugin-qiankun/dist/helper';
let app = null;
// 渲染函数
function render(props = {}) {
const { container } = props;
app = createApp(App);
app.use(router);
// 主应用传入的props可通过app.provide传递
app.mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 暴露Qiankun生命周期
export async function bootstrap() {
console.log('Vue子应用初始化');
}
export async function mount(props) {
console.log('接收主应用参数:', props);
render(props);
}
export async function unmount() {
app.unmount();
app = null;
}
步骤 4:配置路由(src/router/index.js)
js
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: () => import('./views/About.vue') },
];
const router = createRouter({
history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/vue' : '/'),
routes,
});
export default router;
📡 应用间通信
Qiankun 提供两种通信方式,满足不同场景需求:
1. props 传参(简单场景)
主应用注册时通过 props 传参,子应用在 mount 生命周期接收:
jsx
// 主应用注册子应用时添加props
registerMicroApps([
{
name: 'react-subapp',
entry: '//localhost:3001',
container: '#subapp-container',
activeRule: '/react',
props: { token: 'xxx-123', userInfo: { name: '张三' } }, // 传参
},
]);
// React子应用mount中接收
export async function mount(props) {
console.log('token:', props.token);
console.log('userInfo:', props.userInfo);
// 可存储到React Context/Redux
}
2. 全局状态通信(复杂场景)
使用 Qiankun 内置的 onGlobalStateChange 和 setGlobalState 实现全局状态共享:
jsx
// React子应用中监听全局状态变化
export async function mount(props) {
// 监听全局状态变更
props.onGlobalStateChange((state, prev) => {
console.log('全局状态变化:', state, prev);
// 更新本地状态
if (state.token) {
setToken(state.token);
}
}, true); // 立即执行一次
// 修改全局状态
props.setGlobalState({ count: 1 });
}
⚠️ 常见问题与解决
| 问题现象 | 原因 | 解决方法 |
|---|---|---|
| 子应用资源 404 | publicPath 配置错误 | 子应用必须添加 public-path.js 并在入口顶部引入 |
| 样式冲突 | 主/子应用样式污染 | 启动时开启 strictStyleIsolation: true,或子应用使用 scoped 样式 |
| 跨域报错 | 子应用未配置 CORS | 子应用 devServer 中设置 headers: { 'Access-Control-Allow-Origin': '*' } |
| 路由跳转 404 | 子应用路由 basename 未设置 | React 子应用设置 basename,Vue 子应用通过 vite-plugin-qiankun 自动处理 |
📚 进阶学习资源
- 官方文档:https://qiankun.umijs.org/(权威 API 与配置说明)
- 示例仓库:https://github.com/umijs/qiankun/tree/master/examples(React/Vue/Angular 完整示例)
- 最佳实践 :
- 子应用独立部署,保证版本可控;
- 统一 UI 组件库,降低样式兼容成本;
- 使用
loadMicroAppAPI 实现动态加载子应用(适合按需加载场景)。
📌 总结
Qiankun 实现 React+Vue 混部的核心是主应用注册、子应用暴露生命周期、解决路径/跨域/样式隔离。按上述步骤完成配置后,即可实现子应用独立开发、独立部署,主应用统一调度。