qiankun子应用加载时样式丢失是怎么回事?
我在用 qiankun 搭建微前端项目,主应用能正常加载子应用,但子应用的 CSS 样式完全没生效,页面光秃秃的。子应用单独运行时样式是正常的。
我试过在子应用的 webpack 配置里加 publicPath,也确认了主应用注册子应用时的 entry 地址是对的,但还是不行。控制台也没报错,就是样式不加载。有人遇到过类似问题吗?
// 子应用的 qiankun 配置
export async function bootstrap() {
console.log('子应用启动');
}
export async function mount(props) {
render({ props });
}
export async function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('root'));
}
首先最常见的问题是 webpack 配置不完整。你只配置了 publicPath 但可能漏了 output.library 相关配置。qiankun 需要子应用以 UMD 格式输出,这样才能正确识别生命周期函数。
看一下你的 webpack 配置,output 部分需要这样写:
然后第二个常见问题是样式文件的加载方式。开发环境下用 style-loader 是没问题的,但生产环境如果你用了 MiniCssExtractPlugin 把 CSS 提取成单独文件,可能会导致样式加载不上。因为 qiankun 的沙箱机制会拦截动态添加的 style 标签,但对外链 CSS 的处理有时候会出问题。
建议检查一下你的 webpack 配置里 CSS 相关的部分:
第三个要注意的是,你的子应用入口文件需要导出生命周期函数,这部分你代码里已经有了,但 render 函数的实现没贴出来。这里有个细节容易忽略,mount 的时候需要把容器挂载到主应用传入的 container 上,而不是直接找 document.getElementById('root')。
正确的写法应该是这样:
再有一个可能的原因是主应用注册子应用时 sandbox 配置的问题。qiankun 默认开启 JS 沙箱,但样式沙箱有两种模式:strictStyleIsolation 和 experimentalStyleIsolation。前者用的是 Shadow DOM,后者用的是 scoped CSS 方案。Shadow DOM 对某些 UI 框架兼容性不好,比如 antd 的一些弹窗组件样式会失效。
如果你用的是 antd 这类组件库,建议在主应用注册时这样配置:
最后还要检查一个东西,就是你子应用的 HTML 模板里,CSS 引用的路径是不是相对路径。如果是相对路径,在子应用独立运行时能正常加载,但被主应用加载时,这个相对路径会变成相对于主应用的地址,自然就 404 了。
打开子应用的 index.html,看看 link 标签是不是类似这样的:
这个路径必须确保是绝对路径或者能被正确解析的路径。
你可以打开浏览器开发者工具的 Network 面板,刷新一下页面,看看 CSS 文件的请求状态。如果是 404,那就是路径问题;如果是 200 但样式还是不生效,那就是沙箱隔离的问题。
按上面几个点排查一下,基本能解决 90% 的样式丢失问题。如果还有问题,可以把你的 webpack 完整配置贴出来,我再帮你看看。