React 17与18版本Module Federation集成报错求助
模块联邦跨React版本集成BrowserRouter错误解决
项目信息
- app1(远程应用):React 18、Webpack 5
- app2(宿主应用):React 17、Webpack 5
问题场景
将完整app1通过模块联邦暴露给宿主app2时,出现BrowserRouter相关错误,错误截图如下:
当前Webpack配置
app1(远程)配置
new ModuleFederationPlugin( { name: 'app1', filename: 'app1.js', library: { type: 'var', name: 'app1' }, exposes: { './app1': path.resolve(__dirname,'./src/module.tsx'), './newReact': 'react', './newReactDOM': 'react-dom', }, shared: { react: { import: 'react', shareKey: 'newReact', shareScope: 'default', singleton: true, requiredVersion:'^18.2.0' }, 'react-dom':{requiredVersion:'^18.2.0',singleton:true}, '@reduxjs/toolkit': { singleton: true, requiredVersion:'^1.9,5'}, 'react-router-dom': { singleton: true, requiredVersion:'^6.0.1' }, 'react-redux':{singleton:true} } } )
app2(宿主)配置
new ModuleFederationPlugin( { name: 'app2', shared: { react: { singleton: true, eager:true, requiredVersion:deps['react'] }, 'react-dom': { import: 'react-dom', shareKey: 'react-dom', shareScope: 'legacy', singleton: true, eager:true }, '@reduxjs/toolkit': { singleton: true,eager:true, requiredVersion:deps['@reduxjs/toolkit'] }, 'react-router-dom': { singleton: true,eager:true, requiredVersion:deps['react-router-dom'] }, 'react-redux':{singleton:true}, reactNew: { import: "react", shareKey: "reactNew", shareScope: "modern", singleton: true, } }, remotes: { "app1": "app1@[window.APP1_UI_URL]" }, } )
参考方案
参考了模块联邦官方示例中React 16/18跨版本集成的TypeScript实现方案
解决步骤
1. 核心问题定位
react-router-dom与React版本强绑定,app1用React18+react-router-dom v6,app2用React17,强制共享react-router-dom会导致版本冲突,进而引发BrowserRouter的实例错误。
2. 配置修正
修改app1的Webpack配置
移除react-router-dom的共享配置,让app1独立使用自身的react-router-dom版本:
new ModuleFederationPlugin( { name: 'app1', filename: 'app1.js', library: { type: 'var', name: 'app1' }, exposes: { './app1': path.resolve(__dirname,'./src/module.tsx'), './newReact': 'react', './newReactDOM': 'react-dom', }, shared: { react: { import: 'react', shareKey: 'newReact', shareScope: 'default', singleton: true, requiredVersion:'^18.2.0' }, 'react-dom':{requiredVersion:'^18.2.0',singleton:true}, '@reduxjs/toolkit': { singleton: true, requiredVersion:'^1.9.5'}, // 修正原配置的逗号错误 // 移除react-router-dom共享,避免版本冲突 'react-redux':{singleton:true} } } )
修改app2的Webpack配置
同样移除react-router-dom的共享配置,避免宿主的版本影响远程应用:
new ModuleFederationPlugin( { name: 'app2', shared: { react: { singleton: true, eager:true, requiredVersion:deps['react'] }, 'react-dom': { import: 'react-dom', shareKey: 'react-dom', shareScope: 'legacy', singleton: true, eager:true }, '@reduxjs/toolkit': { singleton: true,eager:true, requiredVersion:deps['@reduxjs/toolkit'] }, // 移除react-router-dom共享 'react-redux':{singleton:true}, reactNew: { import: "react", shareKey: "reactNew", shareScope: "modern", singleton: true, } }, remotes: { "app1": "app1@[window.APP1_UI_URL]" }, } )
3. 确保远程应用路由独立
在app1的导出模块src/module.tsx中,使用自身的BrowserRouter包裹路由,避免依赖宿主环境:
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import YourPage from './pages/YourPage'; export default function App1Module() { return ( <BrowserRouter> <Routes> <Route path="/" element={<YourPage />} /> {/* 其他路由 */} </Routes> </BrowserRouter> ); }
内容的提问来源于stack exchange,提问作者tadain
相关产品推荐
相关产品推荐

