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

Nx Monorepo React与标准React(CRA)的模块联邦配置

在Nx React远程应用中暴露组件给非Nx标准React应用(模块联邦方案)

一、Nx React 远程应用配置

1. 调整Webpack配置

在Nx远程应用的apps/[remote-app-name]/webpack.config.js中添加模块联邦配置:

const { composePlugins, withNx } = require('@nrwl/webpack');
const { withReact } = require('@nrwl/react');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = composePlugins(withNx(), withReact(), (config) => {
  // 注册模块联邦插件
  config.plugins.push(
    new ModuleFederationPlugin({
      name: 'nxRemote', // 远程应用标识,宿主端需对应
      filename: 'remoteEntry.js', // 暴露的入口文件名
      exposes: {
        // 配置要暴露的组件路径,键名是宿主端引用的路径
        './Button': './apps/remote-app/src/lib/Button.tsx',
        './Card': './apps/remote-app/src/lib/Card.tsx',
      },
      // 共享依赖,避免重复加载React核心库
      shared: {
        react: { singleton: true, requiredVersion: '^18.2.0' },
        'react-dom': { singleton: true, requiredVersion: '^18.2.0' },
      },
    })
  );

  // 设置远程应用的公共访问路径(需与启动地址一致)
  config.output.publicPath = 'http://localhost:4201/';

  return config;
});

2. 拆分应用入口

修改远程应用的src/main.tsx,改为延迟加载入口文件:

import('./bootstrap');

创建src/bootstrap.tsx作为实际运行入口:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './app/app';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

3. 启动远程应用

指定端口启动,确保与publicPath配置一致:

nx serve remote-app --port 4201

二、非Nx标准React宿主应用配置

以Create React App创建的应用为例,使用Craco修改Webpack配置:

1. 安装依赖

npm install @craco/craco --save-dev

2. 配置Craco

在项目根目录创建craco.config.js:

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  webpack: {
    plugins: {
      add: [
        new ModuleFederationPlugin({
          name: 'reactHost',
          // 关联远程应用,格式为「远程应用标识@远程应用地址/remoteEntry.js」
          remotes: {
            nxRemote: 'nxRemote@http://localhost:4201/remoteEntry.js',
          },
          // 共享依赖需与远程端版本一致
          shared: {
            react: { singleton: true, requiredVersion: '^18.2.0' },
            'react-dom': { singleton: true, requiredVersion: '^18.2.0' },
          },
        }),
      ],
    },
    configure: (webpackConfig) => {
      // 修改入口为bootstrap文件,确保模块联邦加载完成后再渲染
      webpackConfig.entry = './src/bootstrap';
      return webpackConfig;
    },
  },
};

3. 调整项目入口

修改package.json的启动脚本:

"scripts": {
  "start": "craco start",
  // 其他脚本...
}

创建src/bootstrap.tsx作为入口文件:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

4. 引入并使用远程组件

在src/App.tsx中通过懒加载引入远程组件:

import React, { lazy, Suspense } from 'react';

// 按照远程端exposes的键名引入
const RemoteButton = lazy(() => import('nxRemote/Button'));
const RemoteCard = lazy(() => import('nxRemote/Card'));

function App() {
  return (
    <div className="App">
      <h1>非Nx React宿主应用</h1>
      <Suspense fallback={<div>加载远程组件中...</div>}>
        <RemoteButton label="来自Nx远程的按钮" />
        <RemoteCard title="Nx远程卡片内容" />
      </Suspense>
    </div>
  );
}

export default App;

5. 启动宿主应用

npm start

三、常见问题排查

  • 依赖版本冲突:确保两端React、ReactDOM版本完全匹配,shared配置中的requiredVersion需准确对应
  • publicPath错误:远程应用的publicPath必须是可直接访问的完整URL,不能使用相对路径
  • Nx配置覆盖:检查Nx默认Webpack配置是否与自定义配置冲突,确保composePlugins正确合并插件
  • 组件导出问题:远程组件需使用默认导出,或确保宿主端import路径与远程端exposes的键名完全匹配

内容的提问来源于stack exchange,提问作者Phucq.ins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:57:32