微前端(Micro Frontends)是一种将前端应用分解为独立开发、测试和部署的小型应用的架构风格。目前业界最主流的微前端框架主要有 qiankun(基于 single-spa)、Module Federation(Webpack 5 / Rspack 原生支持)以及新兴的 Wujie(无界)和 Micro App(京东)。
下面我将以国内生态最成熟、使用最广泛的 qiankun 为例,提供完整的功能介绍和使用示例。同时会在文末对比其他框架供你选型参考。
一、 微前端核心功能
| 功能 | 说明 |
|---|---|
| 技术栈无关 | 主框架不限制子应用的技术栈(React/Vue/Angular/jQuery 均可共存) |
| 独立部署 | 每个子应用有独立的构建产物和部署流水线 |
| JS 沙箱隔离 | 子应用之间的全局变量、样式互不污染 |
| 样式隔离 | 通过 Shadow DOM 或 CSS 前缀/作用域实现样式隔离 |
| 应用间通信 | 提供 props 传递、全局状态管理、自定义事件等通信机制 |
| 路由接管 | 主应用根据 URL 自动加载/卸载对应子应用 |
| 预加载 | 空闲时预加载子应用资源,提升切换速度 |
二、 qiankun 完整示例(主应用 React + 子应用 Vue3)
📁 项目结构
micro-frontend-demo/
├── main-app/ # 主应用 (React + Vite)
├── sub-app-vue/ # 子应用 (Vue3 + Vite)
└── README.md
1️⃣ 主应用(main-app)
安装依赖
npm create vite@latest main-app -- --template react-ts
cd main-app
npm install qiankun
注册并启动子应用 src/main.tsx
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'sub-app-vue', // 唯一名称
entry: '//localhost:7100', // 子应用入口地址
container: '#sub-app-container',// 挂载容器
activeRule: '/sub-vue', // 激活路由规则
props: { // 向子应用传递数据
token: 'xxx',
userInfo: { name: 'Admin' }
}
}
]);
start({
prefetch: true, // 开启预加载
sandbox: { strictStyleIsolation: false, experimentalStyleIsolation: true }
});
主应用布局 src/App.tsx
import { Link, Route, Routes } from 'react-router-dom';
export default function App() {
return (
<div>
<nav style={{ padding: '16px', background: '#001529', color: '#fff' }}>
<Link to="/" style={{ color: '#fff', marginRight: 16 }}>首页</Link>
<Link to="/sub-vue" style={{ color: '#fff' }}>Vue 子应用</Link>
</nav>
<Routes>
<Route path="/" element={<h2 style={{padding:24}}>🏠 主应用首页</h2>} />
</Routes>
{/* 子应用挂载容器 */}
<div id="sub-app-container" />
</div>
);
}
2️⃣ 子应用(sub-app-vue)
安装依赖
npm create vite@latest sub-app-vue -- --template vue-ts
cd sub-app-vue
npm install vite-plugin-qiankun
Vite 配置 vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import qiankun from 'vite-plugin-qiankun';
export default defineConfig({
plugins: [
vue(),
qiankun('sub-app-vue', { useDevMode: true }) // name 必须与主应用注册一致
],
server: {
port: 7100,
cors: true, // ⚠️ 必须开启跨域
origin: 'http://localhost:7100'
}
});
导出生命周期钩子 src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/helper';
let app: ReturnType<typeof createApp>;
// ✅ qiankun 要求的三个生命周期
export async function bootstrap(props: any) {
console.log('sub-app-vue bootstrap', props);
}
export async function mount(props: any) {
console.log('sub-app-vue mount', props);
app = createApp(App);
// 将主应用传来的数据注入到全局
app.provide('mainProps', props);
const container = props.container
? props.container.querySelector('#app')
: document.getElementById('app');
app.mount(container);
}
export async function unmount() {
console.log('sub-app-vue unmount');
app?.unmount();
}
// 非 qiankun 环境独立运行
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
createApp(App).mount('#app');
}
renderWithQiankun({ bootstrap, mount, unmount });
接收主应用数据 src/App.vue
<script setup lang="ts">
import { inject } from 'vue';
const mainProps = inject<any>('mainProps', {});
</script>
<template>
<div style="padding: 24px; border: 2px dashed #42b883;">
<h2>🟢 Vue3 子应用</h2>
<p>来自主应用的数据:{{ mainProps?.userInfo?.name }}</p>
</div>
</template>
3️⃣ 启动
# 先启动子应用
cd sub-app-vue && npm run dev # http://localhost:7100
# 再启动主应用
cd main-app && npm run dev # http://localhost:5173
访问 http://localhost:5173/sub-vue 即可看到 Vue 子应用被嵌入到 React 主应用中。
三、 应用间通信方案对比
| 方式 | 适用场景 | 示例 |
|---|---|---|
| props 传参 | 主 → 子单向传递初始化数据 | registerMicroApps 中的 props |
| initGlobalState | 全局共享状态(推荐) | import { initGlobalState } from 'qiankun' |
| CustomEvent | 任意应用间解耦通信 | window.dispatchEvent(new CustomEvent(...)) |
| URL 参数 | 简单状态同步 | /sub-vue?id=123 |
| Shared Store | 复杂状态管理 | 共享 localStorage / IndexedDB / BroadcastChannel |
initGlobalState 示例
// 主应用
import { initGlobalState, MicroAppStateActions } from 'qiankun';
const state = { user: 'admin', theme: 'dark' };
const actions: MicroAppStateActions = initGlobalState(state);
actions.onGlobalStateChange((newState, prev) => {
console.log('主应用监听到状态变化:', newState);
});
// 子应用 mount(props) 中
props.onGlobalStateChange((state) => {
console.log('子应用收到全局状态:', state);
}, true); // true = 立即触发一次
props.setGlobalState({ user: 'editor' }); // 修改全局状态
四、 主流微前端框架选型对比
| 特性 | qiankun | Wujie (无界) | Micro App (京东) | Module Federation |
|---|---|---|---|---|
| 隔离方案 | Proxy 沙箱 + CSS 前缀 | WebComponent + iframe | WebComponent + Proxy | 运行时模块共享 |
| 接入成本 | ⭐⭐⭐ 中等 | ⭐⭐ 低 | ⭐⭐ 低 | ⭐⭐⭐⭐ 较高 |
| Vite 支持 | 需插件 | ✅ 原生 | ✅ 原生 | ✅ Rspack/Webpack5 |
| 性能 | 良好 | 🚀 优秀(iframe 预渲染) | 良好 | 🚀 最优(按需加载模块) |
| 样式隔离 | 实验性 | ✅ 完美(Shadow DOM) | ✅ 完美 | ❌ 需自行处理 |
| 社区/文档 | ⭐⭐⭐⭐⭐ 最成熟 | ⭐⭐⭐ 快速增长 | ⭐⭐⭐ 稳定 | ⭐⭐⭐⭐ 国际化 |
| 推荐场景 | 企业级中后台、遗留系统改造 | 新项目、强隔离需求 | 京东系/类 WebComponent | 同技术栈模块共享 |
💡 2025-2026 趋势建议:
五、 常见坑与注意事项
- 子应用必须允许跨域:开发环境和生产环境的响应头都需要设置
Access-Control-Allow-Origin: * - publicPath 问题:子应用的静态资源路径必须设为绝对路径或运行时动态设置(
__webpack_public_path__/ Vite 的base) - 路由模式:子应用推荐使用
history模式,且base要与activeRule一致 - 避免重复加载:确保子应用在
unmount时正确销毁实例、清除定时器、移除全局监听 - CSS 泄漏:即使开了样式隔离,也建议子应用使用 CSS Modules / Scoped / BEM 命名规范作为第一道防线
针对特定技术栈(如 Next.js、Nuxt、Angular)的微前端方案,可进一步实践!
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/bsklhao/article/details/166136718



