微前端子应用部署后主应用加载不到资源怎么办?
我们用 qiankun 搭的微前端架构,本地开发没问题,但子应用部署到测试环境后,主应用加载时报 404,找不到子应用的 JS 和 CSS。子应用单独访问是正常的,路径也配了 publicPath,但还是不行。
尝试过在子应用的 webpack 配置里加 __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,也试过硬编码成部署的 CDN 地址,但要么报错,要么资源路径不对。现在卡在这儿了,不知道是部署配置问题还是 qiankun 的接入方式有问题?
你这情况大概率是两个问题:publicPath 动态设置没生效,或者 nginx 配置没对。
先说 publicPath 这块。动态设置是对的,但你得确保代码执行顺序没问题。在子应用 src 目录下建个 public-path.js 文件:
然后在子应用入口文件的最顶部引入这个文件,一定要是最顶部,在 import 其他东西之前:
还有个关键点,webpack 配置里的 publicPath 要设成空字符串或者 './',别设成具体地址,让 qiankun 动态注入。
然后是 nginx 配置,这个坑了我好久。子应用部署后,nginx 要支持 history 模式,不然刷新或者直接访问子应用路由会 404:
另外跨域问题也得注意,主应用从别的域加载子应用资源,nginx 得加响应头:
你排查的时候可以打开浏览器控制台,看下请求的资源路径到底是啥,对比一下实际部署的路径,基本就能定位问题了。
希望能帮到你,微前端这玩意儿配置确实有点折腾,搞定了就好了。
先说结论:子应用部署后资源 404,大概率是因为子应用在被 qiankun 加载时,Webpack 的 publicPath 没有被正确覆盖,导致它还是按默认路径(比如根路径 /)去找资源,但实际部署在子路径(比如 /sub-app/)下,自然就 404 了。
你提到试过
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,这个方向是对的,但要注意几点:1. 这个赋值必须在任何模块加载之前执行,最好放在子应用入口文件(比如
main.js或index.js)的最最最上面,甚至在 import 任何其他模块之前,比如:2. 如果你用的是 Vue + vue-cli,记得在
vue.config.js里把publicPath设为'./'(相对路径),或者留空(默认 ./),避免构建时打包成绝对路径:3. 子应用的 nginx(或部署服务)配置要注意:
- 不能对静态资源路径做重定向(比如把
/sub-app/xxx.js重定向到/sub-app/xxx.js?会破坏资源请求)- 确保子应用的
entry和assetsPublicPath与部署路径一致- 如果用了 CDN,要确认
__INJECTED_PUBLIC_PATH_BY_QIANKUN__是否真的注入了正确的 CDN 前缀(可以在浏览器里打印一下看看)4. 最后一个容易忽略的点:qiankun 2.4+ 版本之后,主应用注册子应用时,如果用了
entry: 'https://cdn.xxx.com/sub-app'这种完整 URL,qiankun 会自动注入__INJECTED_PUBLIC_PATH_BY_QIANKUN__;但如果 entry 是相对路径(比如'/sub-app'),那得确保主应用的微应用注册路径和子应用实际部署路径一致。我建议你先打印一下
window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__看看值对不对,再检查子应用入口文件里这个赋值是不是真的执行到了——有时候代码缩进或者模块导入顺序搞错了,就白写了。希望能帮到你,如果还不行可以贴下你的子应用入口文件和 nginx 配置,我帮你看看。