🚀 一、Qiankun 的使用方法(主应用 + 子应用)
1. 主应用配置(React / Vue 都一样)
① 安装
npm i qiankun --save
② 注册子应用
import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'sub-vue', entry: 'http://localhost:8081', container: '#subapp', activeRule: '/vue', }, { name: 'sub-react', entry: 'http://localhost:8082', container: '#subapp', activeRule: '/react', }, ]); start();
③ 主应用 HTML 加载容器
<div id="subapp"></div>
2. 子应用配置(以 React 为例)
① public-path 设置(重点)
if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
② 导出生命周期函数
export async function bootstrap() { console.log('subapp bootstraped'); } export async function mount(props) { ReactDOM.render(<App />, document.getElementById('root')); } export async function unmount() { ReactDOM.unmountComponentAtNode(document.getElementById('root')); }
③ 子应用路由配置(必须设置 basename)
React-router:
<BrowserRouter basename="/react">
Vue-router:
new VueRouter({ base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/' })
🚨 二、Qiankun 实际项目中最常见的问题 + 解决方案(重头戏)
下面是企业开发中遇到最多的 20 大问题,每个都有解决方案。
1. ❗子应用刷新后 404
原因:
主应用是 SPA(history 模式),刷新时路径被主应用拦截,导致找不到子应用资源。
解决:
两种选一个:
✔ 方案 A:子应用使用 Hash 路由
<HashRouter basename="/react">
✔ 方案 B:Nginx 配置 fallback
location /react { try_files $uri $uri/ /react/index.html; }
2. ❗样式冲突(CSS 污染)
症状:
子应用样式影响主应用样式,或之间互相覆盖。
解决方案:
✔ A. CSS Modules
✔ B. BEM 命名法
✔ C. ShadowDOM(qiankun 内置 css scoped + 实验性 shadow)
✔ D. 主应用与子应用 UI 框架样式隔离(AntD、ElementUI)
企业中多数采用:
👉 子应用全部 CSS Modules + 一套 UI 库只给一端使用
3. ❗子应用无法获取正确的静态资源路径(publicPath 问题)
表现:
-
图片无法显示
-
chunk.js 路径不对
-
404
解决:
子应用入口设置 public-path(必须):
if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
4. ❗子应用之间版本冲突(React/Vue)
例如主应用是 React 17
子应用 React 18
导致 React 组件无法渲染 / 事件失效。
解决:
👉 使用 external 共享依赖
webpack:
externals: { react: 'React', 'react-dom': 'ReactDOM' }
并在主应用 index.html 注入 React CDN。
5. ❗子应用白屏,控制台提示:App x died in status LOADING_SOURCE_CODE
原因:
子应用入口 URL 无法访问。
解决:
-
entry 必须返回 index.html。
-
子应用必须允许跨域(Access-Control-Allow-Origin: *)
-
子应用 devServer 需要:
headers: { 'Access-Control-Allow-Origin': '*' }
6. ❗子应用 unmount 后内存泄漏
表现:
-
再次进入会慢
-
表格/图表重复渲染
-
内存不断增加
解决:
在 unmount 中:
✔ 卸载 React/Vue 实例
✔ 移除事件监听
✔ 清除定时器
✔ 清理全局变量
✔ 销毁第三方实例(echarts/map/video)
7. ❗子应用加载很慢(首次加载卡顿)
解决方案:
✔ 预加载子应用:
import { prefetchApps } from 'qiankun'; prefetchApps([{ name: 'sub-react', entry: 'xxx' }]);
✔ 设置 prefetch:true(默认)
✔ CDN 静态资源
✔ 子应用 code splitting
✔ 使用 gzip/brotli
8. ❗子应用切换时白屏闪一下
原因:
-
主应用切换子应用 route 时清空 container
-
加载子应用需要时间
解决:
✔ 主应用给子应用容器加 Loading UI(最佳实践)
9. ❗子应用里使用 window.getComputedStyle 报错
原因:sandbox 沙箱限制 window 一些属性。
解决:
在 sandbox 设置:
start({ sandbox: { loose: true } });
10. ❗子应用通信复杂、耦合度高
建议使用:
优先级:
-
props(最推荐)
-
eventBus(mitt)
-
全局状态(redux / vuex / pinia)
-
custom event
11. ❗多个子应用切换时事件重复绑定
解决:
在 unmount 中:
window.removeEventListener('resize', handler)
12. ❗子应用使用 Antd / Element UI 样式冲突
解决:
-
强制 css-modules
-
或者每个子应用使用不同版本 UI 库
-
或者每个 UI 样式包添加命名空间前缀
13. ❗qiankun 沙箱导致第三方库不兼容
例如富文本、图表库、地图 SDK。
解决:
start({ sandbox: { experimentalStyleIsolation: true } });
必要时给子应用开启 ShadowDOM。
14. ❗子应用 iframe 内部跳转不能触发 mount/unmount
解决:
iframe 内不适合做微前端子应用,需要使用原生子应用方式。
15. ❗子应用 history 模式导致重复跳转
解决:
子应用的 basename 必须与 activeRule 对应。
16. ❗子应用打包后的 publicPath 不正确
webpack:
output: { publicPath: '/', }
子应用内部通过注入路径来控制。
17. ❗主子应用的 global 变量冲突
解决:
启用严格沙箱:
start({ sandbox: { strictStyleIsolation: true } });
18. ❗子应用热更新失败
解决:
子应用 devServer 必须:
hot: true, historyApiFallback: true, headers: { 'Access-Control-Allow-Origin': '*' }
19. ❗打包后子应用路径前缀不对(访问 404)
解决:
改 base:
vue-router base: '/sub/' react-router basename='/sub'
20. ❗微前端拆分后性能下降
原因:
子应用资源需要按需加载。
解决:
✔ 一次性预加载多个子应用
✔ 子应用内部 code-split
✔ CDN 资源加速
✔ 整体降 JS 体积、按需加载 UI 库
🚀 三、企业级最佳实践(重点非常重要)
✔ 1. 主应用只负责布局 + 路由
不要在主应用写业务逻辑,否则耦合度爆炸。
✔ 2. 子应用必须能独立运行
确保开发环境、生产环境均可直接访问子应用 URL。
✔ 3. 主、子应用依赖必须保持独立或统一
React / Vue 最好锁版本。
✔ 4. 子应用之间不共享 CSS
避免污染。
✔ 5. 子应用按模块拆分,而不是按页面拆
粒度太小反而复杂。
✔ 6. 子应用资源强制 CDN & hash
解决缓存问题。
✔ 7. 加 loading skeleton 提升体验
避免白屏。