微前端中如何正确共享 React 依赖避免重复加载?

夏侯新利 阅读 43

我用 qiankun 搭了个微前端项目,主应用和子应用都用了 React 18,但发现子应用加载时又把 React 打包进去了,导致页面报错说存在多个 React 实例。

我试过在 webpack 里配 externals 把 React 排除,也按文档在主应用挂载了 window.React = React,但子应用还是报 Invalid hook call。是不是哪里配置漏了?

这是我的子应用 webpack 配置片段:

externals: {
  react: 'React',
  'react-dom': 'ReactDOM'
}
我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
金利酱~
在微前端架构下共享 React 依赖确实容易出问题,特别是多个版本或者实例冲突。你现在的配置方向是对的,但可能少了关键一步。

首先确认主应用正确地把 React 挂载到全局了,像这样:
window.React = require('react');
window.ReactDOM = require('react-dom');


然后子应用这边除了配 externals,还需要确保 webpack 插件设置正确。建议加上这个插件:
new ModuleFederationPlugin({
name: 'subapp',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App'
},
shared: {
react: { singleton: true, eager: true },
'react-dom': { singleton: true, eager: true }
}
})


注意安全,这里设置了 singleton 确保只用一个 React 实例,eager 表示优先加载主应用的版本。另外检查下 qiankun 的 sandbox 配置,默认情况下它会隔离上下文,可能会导致全局变量不生效。

调试时可以用 console.log 检查 window.React 和 window.ReactDOM 是否被正确替换。这种微前端的坑还挺多的,慢慢来吧,我都踩过好几次了。
点赞
2026-03-27 14:02
司空爱棋
Invalid hook call 基本就是多个 React 实例导致的,你的 externals 配置本身没问题,但 qiankun 的 JS 沙箱隔离了 window 对象,子应用访问不到主应用挂载的 React。

改成这样,用函数形式的 externals 动态获取:

externals: {
'react': {
root: 'React',
commonjs: 'react',
commonjs2: 'react',
amd: 'react'
},
'react-dom': {
root: 'ReactDOM',
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'react-dom'
}
}


同时主应用挂载方式改成这样,确保在 qiankun 启动前就挂载好:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

// 必须在 registerMicroApps 之前挂载
window.React = React;
window.ReactDOM = ReactDOM;


如果还不行,最稳的方式是主应用直接用 script 标签加载 React CDN,这样全局变量在沙箱创建前就存在了,子应用 externals 配置不用改。
点赞
2026-03-01 19:03