You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 06:41:29