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

React v18 + Router v6 + Module Federation子应用路由失效问题

解决Module Federation + React Router v6子应用路由不生效问题

核心原因

根应用已挂载BrowserRouter,子应用不能重复嵌套路由实例;同时根应用路由未正确传递子路径给子应用,导致子应用内部路由无法匹配。

解决方案步骤

1. 修正根应用路由配置

确保根应用中指向Payments子应用的路由添加通配符*,让所有/payments开头的子路径都传递给子应用处理:

// 根应用主路由文件
import { BrowserRouter, Routes, Route } from 'react-router-dom';
// 通过Module Federation引入子应用组件
import Payments from 'payments/Payments';

function RootApp() {
  return (
    <BrowserRouter>
      <Routes>
        {/* 其他根路由 */}
        {/* 关键:path末尾添加*,传递子路径 */}
        <Route path="/payments/*" element={<Payments />} />
      </Routes>
    </BrowserRouter>
  );
}

2. 子应用路由配置(无需嵌套Router)

子应用内部直接使用Routes和Route,路径使用相对路径(基于根应用的/payments路径):

// .packages/payments/src/app/Payments.jsx
import { Routes, Route, Link } from 'react-router-dom';
import PaymentList from './PaymentList';
import PaymentDetail from './PaymentDetail';

export default function Payments() {
  return (
    <div className="payments-app">
      <nav>
        {/* 相对路径跳转 */}
        <Link to="list">支付列表</Link>
        <Link to="detail/1">支付详情(示例ID)</Link>
      </nav>
      <Routes>
        {/* 匹配/payments根路径 */}
        <Route index element={<PaymentList />} />
        {/* 匹配/payments/list */}
        <Route path="list" element={<PaymentList />} />
        {/* 匹配/payments/detail/:id */}
        <Route path="detail/:id" element={<PaymentDetail />} />
      </Routes>
    </div>
  );
}

3. 子应用本地开发兼容(可选)

如果需要子应用单独运行开发,可在bootstrap.jsx中添加条件渲染,仅在独立运行时挂载BrowserRouter:

// .packages/payments/src/bootstrap.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Payments from './app/Payments';

// 仅当子应用独立运行时(非被根应用加载)才初始化Router
if (!window.isModuleFederationHost) {
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(
    <React.StrictMode>
      <BrowserRouter>
        <Routes>
          <Route path="/*" element={<Payments />} />
        </Routes>
      </BrowserRouter>
    </React.StrictMode>
  );
}

4. 验证Module Federation配置

确保子应用的webpack配置正确暴露Payments组件,且共享路由依赖避免多实例冲突:

// 子应用webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'payments',
      filename: 'remoteEntry.js',
      exposes: {
        './Payments': './src/app/Payments', // 正确暴露组件路径
      },
      shared: {
        react: { singleton: true },
        'react-dom': { singleton: true },
        'react-router-dom': { singleton: true }, // 共享路由依赖,避免版本冲突
      },
    }),
  ],
};

常见排查点

  • 确认根应用路由的path="/payments/*"末尾的*没有遗漏,这是传递子路径的关键
  • 子应用内部路由路径不要用绝对路径(如/list),改用相对路径(如list)
  • 确保react-router-dom在Module Federation的shared配置中设为singleton: true,避免多实例冲突

内容的提问来源于stack exchange,提问作者Timur Ivanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:37:04