🚀 微前端落地实践指南(qiankun框架)
🌈 微前端核心架构图
graph TD
A[主应用] --> B[vue子应用]
A --> C[react子应用]
A --> D[angular子应用]
B --> E{通信机制}
C --> E
D --> E
🔧 主应用配置详解
1. 主应用注册流程
// main.js
import { registerMicroApps, start } from 'qiankun';
const apps = [
{
name: 'vueApp', // 🏷️ 子应用唯一标识
entry: '//localhost:10000', // 🌐 子应用访问地址
container: '#vue', // 📦 DOM容器ID
activeRule: '/vue', // 🚦 路由激活规则
props: { authToken: 'xxx' } // 📦 共享数据
},
// 可添加多个子应用...
]
// 🚀 注册微应用
registerMicroApps(apps, {
beforeLoad: app => console.log('开始加载:', app.name), // 🔔 生命周期钩子
afterMount: app => console.log('挂载完成:', app.name)
});
// ⚡ 启动微前端
start({
prefetch: 'all', // 🚫 关闭预加载
sandbox: { strictStyleIsolation: true } // 🛡️ 严格样式隔离
});
🧩 子应用接入规范
1. 子应用入口改造
// 子应用 main.js
let vueInstance = null;
function render(props = {}) {
vueInstance = new Vue({
router,
store: props.sharedStore, // 💡 接收主应用共享的store
render: h => h(App)
}).$mount('#app'); // ⚠️ 必须挂载到自己的容器
}
// 🌈 独立运行判断
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 📦 导出生命周期钩子
export async function bootstrap() {
console.log('子应用初始化');
}
export async function mount(props) {
console.log('接收主应用参数:', props);
render(props);
}
export async function unmount() {
vueInstance.$destroy();
vueInstance.$el.innerHTML = ''; // 🧹 彻底清理DOM
}
⚙️ 配置对比表
| 配置项 | 主应用 | 子应用 |
|---|---|---|
| 入口文件 | 注册微应用列表 | 导出生命周期钩子 |
| 路由处理 | 定义激活规则(activeRule) | 保持相对路径 |
| 构建配置 | 无特殊要求 | 设置libraryTarget: 'umd' |
| 通信机制 | 通过props传递数据 | 监听主应用事件 |
| 样式隔离 | 开启沙箱模式 | 使用CSS Modules |
🛠️ 子应用webpack配置
// vue.config.js
module.exports = {
devServer: {
port: 10000,
headers: {
'Access-Control-Allow-Origin': '*' // 🌍 允许跨域
}
},
configureWebpack: {
output: {
library: `vueApp-[name]`, // 🏷️ 唯一命名
libraryTarget: 'umd', // 📦 模块化格式
jsonpFunction: `webpackJsonp_vueApp` // 🚨 避免命名冲突
}
}
}
📡 应用通信方案
1. 主->子通信
// 主应用传递数据
registerMicroApps([{
props: {
userInfo: { name: '张三' },
onEvent: (msg) => console.log(msg)
}
}]);
// 子应用接收
export function mount(props) {
props.onEvent('子应用已加载!');
}
2. 子->主通信
// 子应用
window.dispatchEvent(new CustomEvent('child-event', {
detail: { type: 'alert', msg: 'Hello!' }
}));
// 主应用监听
window.addEventListener('child-event', e => {
console.log('收到子应用消息:', e.detail);
});
🚨 常见问题解决方案
| 问题现象 | 解决方案 | 工具方法 |
|---|---|---|
| 样式冲突 | 开启严格沙箱模式 | sandbox: { strictStyleIsolation: true } |
| 路由跳转失效 | 使用history路由模式 | router = new VueRouter({ mode: 'history' }) |
| 静态资源加载404 | 设置publicPath动态路径 | __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ |
| 全局变量污染 | 使用命名空间隔离 | window.YourApp = { ... } |
| 通信数据丢失 | 使用localStorage中转 | JSON.parse(localStorage.getItem('sharedData')) |
🚀 部署流程图
sequenceDiagram
主应用->>Nginx: 请求/vue路由
Nginx->>主应用服务器: 返回主应用HTML
主应用->>子应用服务器: 动态加载子应用资源
子应用服务器-->>主应用: 返回JS/CSS
主应用->>浏览器: 渲染子应用内容
💡 最佳实践建议
-
版本管理
📌 使用package.json锁定qiankun版本:"dependencies": { "qiankun": "^2.10.8" } -
性能优化
🚀 按需加载子应用:start({ prefetch: 'all' }) // 🚫 关闭预加载 -
错误监控
🔍 添加全局错误监听:window.addEventListener('error', e => { Sentry.captureException(e.error); });
通过以上配置和实践,可以快速搭建高可用微前端架构!🎉 不同技术栈的团队可以独立开发部署,主应用只需更新子应用路由配置即可实现无缝集成。