Umi 开启 MFSU 后浏览器出现 React 多实例问题怎么解决
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
在 Umi 项目开发中,如果浏览器控制台报出 React 多实例错误(React 的代码被打包了多份,运行时产生了多个 React 实例),通常与 MFSU 有关。MFSU 在 Umi 项目中默认开启,所以即使没有手动配置,也可能直接遇到这个问题。这篇说明该报错的根因,以及通过shared配置解决的完整路径。
为什么 MFSU 会引入多个 React 实例
MFSU 是基于 webpack5 新特性 Module Federation 的打包提速方案:把应用源代码的编译和应用依赖的编译分离,将变动较小的应用依赖构建为一个 Module Federation 的 remote 应用,热更新时不再重新编译依赖(见 MFSU 文档)。
正因为依赖被单独构建进 remote 应用,在某些复杂场景下 React 的代码会被打包多份,运行时产出多个 React 实例,浏览器中就会出现 React 多实例报错。
另外要知道:MFSU 默认开启,配置mfsu: false可以关闭它(见 配置文档 mfsu 一节)。默认的mfsu配置为{ mfName: 'mf', strategy: 'normal' }。
解法:为 react 配置 shared
根因是 React 被打包多份,解法是通过 Module Federation 的shared配置来避免多实例的出现。在 Umi 配置的mfsu字段中加入shared:
mfsu: { shared: { react: { singleton: true, }, }, }singleton: true表示该依赖只保留单实例。如果项目里其他依赖也出现多实例问题,可以用同样的方式把它们加进mfsu.shared。
分支:开启了 MF 插件的项目
如果项目使用了 MF 插件,需要按 MF 插件文档的「和 MFSU 一起使用」 开启shared,即通过mf.shared声明:
export default defineConfig({ mf: { name: 'remoteMFName', remotes: [ { name: 'remote1', entry: 'https://to.the.remote.com/remote.js', }, ], shared: { react: { singleton: true, eager: true, }, 'react-dom': { singleton: true, eager: true, }, }, }, });上面代码块来自 MF 插件文档的示例,其中name、entry等是示例值,实际项目需替换为自己的 remote 应用名与入口地址。配置mf.shared后,mf 插件会自动填充与 MFSU 兼容的默认配置(包括对应的mfsu.shared),这样开启了 MFSU 也能在 DEV 阶段调试 MF 的模块。
验证与兜底
- 判断依据:修复前浏览器报 React 多实例错误;按上述方式配置后,该错误不再出现即为解决(
shared配置的目的就是避免多实例的出现)。 - 调试时如果配置未生效,MFSU 的构建缓存默认存放在
node_modules/.cache/mfsu目录下(可用cacheDirectory自定义),可据此定位 MFSU 的构建产物。 - 如果配置
shared后仍无法解决,可以配置mfsu: false关闭 MFSU 作为兜底;代价是依赖重新和应用代码一起编译,失去 MFSU 的热更新提速效果。
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考