微前端部署成败取决于子应用是否导出生命周期函数、主应用能否正确加载接管、部署路径是否与路由前缀对齐;90%失败源于未验证这三点。

HTML 本身不做微前端,也不能靠改 index.html 实现微前端部署——真正决定能否跑通的,是子应用是否满足运行时契约、主应用能否正确加载并接管生命周期,以及部署路径是否与路由前缀对齐。90% 的“部署失败”其实发生在上线前没验证好这三点。
子应用必须导出 bootstrap/mount/unmount 才能被主应用调用
Vue/React 项目默认构建产物不暴露这些函数,直接扔到线上会被主应用报 TypeError: app.mount is not a function。不是配置问题,是根本没导出。
- Vue 项目需在入口文件(如
main.js)外层包裹导出逻辑,不能只写createApp().mount('#app') - React 项目不能用
ReactDOM.render()一次性挂载,要改为接收容器节点参数的函数式挂载,例如function mount(props) { ReactDOM.createRoot(props.container).render(<app></app>) } - Webpack 构建必须设
output.library和output.libraryTarget: 'umd',否则主应用通过import()或window访问不到子应用模块 - 子应用
public/index.html中所有静态资源(.js、.css)必须用相对路径,或由主应用注入__webpack_public_path__,否则上线后 404
主应用注册子应用时,entry 地址必须可跨域访问且带正确协议
本地开发时用 //localhost:8080 没问题,但上线后若子应用部署在不同域名或子路径下,entry 必须是完整可访问 URL,且主应用所在域需允许跨域加载脚本。
- 子应用服务器需返回
Access-Control-Allow-Origin: *或明确列出主应用域名,否则fetch加载 JS 失败 - 如果子应用部署在
https://sub1.example.com/app1/,entry就得写成这个完整地址,不能只写/app1/ - 主应用中配置的
activeRule(如'/app1')必须和子应用实际的路由 base path 一致,否则子应用内useNavigate('/list')会跳到/list而非/app1/list,触发无限重定向 - 建议在子应用中显式设置
router.base = '/app1'(Vue Router)或basename="/app1"(React Router),而不是依赖主应用推断
样式隔离失效的典型场景不是沙箱关了,而是 CSS 逃逸了
qiankun 默认开启样式沙箱,但以下情况它管不了:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
立即学习“前端免费学习笔记(深入)”;
- 子应用
index.html里写了内联<style>body { margin: 0 }</style>—— 这类全局样式直接作用于 document,沙箱无法拦截 - 用了
styled-components或emotion:它们运行时动态插入的<style>标签不在沙箱管控范围内 - 子应用运行时又
document.body.appendChild(newStyle):沙箱只劫持首次加载的<link>/<style>,后续手动插入不感知 - Ant Design 等组件库的弹窗(
Modal、Tooltip)默认挂载到document.body,脱离子应用容器,事件和样式都可能错乱;解决方式是统一配getContainer={() => document.getElementById('subapp-container')}
部署顺序和环境变量必须严格对齐
主应用打包时依赖子应用线上地址,所以部署必须按顺序来,且环境变量不能写死在代码里。
- 先部署所有子应用,确认每个都能单独访问(比如打开
https://sub1.example.com能看到页面),再更新主应用配置 - 主应用中子应用地址应通过构建时
define注入(如DATALINK_MICRO_APP_HOST: 'https://sub1.example.com'),而不是硬编码在app.tsx里 - 测试环境和生产环境要用不同配置文件(如
config.test.ts和config.prod.ts),避免误把 localhost 地址打到线上 - 子应用构建产物最好加哈希(
filename: '[name].[contenthash:8].js'),避免 CDN 缓存旧 JS 导致生命周期函数不匹配
最常被忽略的是:子应用上线后没验证 entry 地址是否真能被主应用 fetch 到 JS 文件,以及是否真的导出了三个生命周期函数——建议上线前 curl 一下子应用入口 JS,搜索是否存在 export { bootstrap, mount, unmount } 或等效的 UMD 暴露逻辑。没有这一步,其他配置全对也白搭。


















