Module Federation 加载远程模块时为什么会报“Shared module is not available”?

设计师宇硕 阅读 27

我在用 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' },
  },
})
我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
FSD-梓希
这个问题我踩过好多次了,核心不是 shared 配置错了,而是“eager consumption”导致的——主应用在初始化阶段就同步加载了远程模块,但 shared 的依赖还没准备好,特别是当远程模块用的是默认的 lazy 模式时。

通用的做法是:
要么把远程模块改成异步加载,要么在主应用里把 shared 的加载策略统一改成 eager。

先说第一种,最简单的改法是在主应用里加载远程组件时,用动态 import 包一层,比如:

import('app2/Button').then(({ Button }) => {
// 用 Button
})


或者如果你用的是 React 的 Suspense + lazy:

const RemoteButton = React.lazy(() => import('app2/Button'));


第二种,如果你确实想在主应用初始化时就同步用远程模块(不推荐,除非你非常清楚副作用),那就在主应用的 webpack 配置里,给 shared 里每个包都加个 eager: true,比如:

shared: {
react: { singleton: true, requiredVersion: '^18.2.0', eager: true },
'react-dom': { singleton: true, requiredVersion: '^18.2.0', eager: true },
}


注意,这里要改的是主应用的 shared 配置,不是远程应用的。很多人改反了,以为是子应用的问题。

还有一种隐藏坑:如果你的 remoteEntry 里 exposes 的组件用了 suspense 或者 hooks,但主应用没包 suspense,也会触发这个报错。最稳妥的组合是:
主应用 shared 加 eager: true,或者远程模块用 lazy 加载 + 主应用用 Suspense 包裹。

我一般直接上 lazy + Suspense,最省心,也不容易踩 eager 的坑。
点赞 2
2026-02-25 03:01