Module Federation 加载远程模块时为什么会报“Shared module is not available”?
我在用 Webpack 5 的 Module Federation 搭建微前端,主应用加载子应用的组件时,控制台一直报 “Shared module is not available for eager consumption” 错误。明明 shared 配置里加了 react 和 react-dom,版本也对得上,但就是不行。
我试过把子应用的 exposes 改成异步加载,也检查了主应用的 remote 地址是否正确,还是没解决。是不是 shared 配置哪里写错了?
new ModuleFederationPlugin({
name: 'app1',
remotes: {
app2: 'app2@http://localhost:3002/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^18.2.0' },
react-dom: { singleton: true, requiredVersion: '^18.2.0' },
},
})
通用的做法是:
要么把远程模块改成异步加载,要么在主应用里把 shared 的加载策略统一改成 eager。
先说第一种,最简单的改法是在主应用里加载远程组件时,用动态 import 包一层,比如:
或者如果你用的是 React 的 Suspense + lazy:
第二种,如果你确实想在主应用初始化时就同步用远程模块(不推荐,除非你非常清楚副作用),那就在主应用的 webpack 配置里,给 shared 里每个包都加个
eager: true,比如:注意,这里要改的是主应用的 shared 配置,不是远程应用的。很多人改反了,以为是子应用的问题。
还有一种隐藏坑:如果你的 remoteEntry 里 exposes 的组件用了 suspense 或者 hooks,但主应用没包 suspense,也会触发这个报错。最稳妥的组合是:
主应用 shared 加 eager: true,或者远程模块用 lazy 加载 + 主应用用 Suspense 包裹。
我一般直接上 lazy + Suspense,最省心,也不容易踩 eager 的坑。