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

Webpack Module Federation插件:Angular宿主无法渲染React远程微前端

微前端React远程应用无法渲染问题排查思路

问题背景

使用Webpack的ModuleFederationPlugin构建微前端系统,包含1个Angular宿主应用、1个Angular远程应用、1个React远程应用。Angular宿主可正常渲染Angular远程应用,但React远程应用无法显示,具体现象:

  • 页面已生成<react-element></react-element>标签,但内容为空
  • 导航至/reactMFE路径时,浏览器Source标签可见React应用的remoteEntry.js及其他文件已下载
  • React应用单独启动可正常运行

相关配置

Angular宿主应用路由配置

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {HomeComponent} from './core/home/home.component';
import {WebComponentWrapper, WebComponentWrapperOptions} from '@angular-architects/module-federation-tools';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full'
  },
  {
    path: 'ngMFE',
    loadChildren: () => import('mf1/Module').then(m => m.HeroesModule)
  },
  {
    path: 'reactMFE',
    component: WebComponentWrapper,
    data: {
      type: 'script',
      remoteEntry: 'http://localhost:3000/remoteEntry.js',
      remoteName: 'mf2',
      exposedModule: './AppModule',
      elementName: 'react-element',
    } as WebComponentWrapperOptions,
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

React应用Webpack配置

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const { ModuleFederationPlugin } = require('webpack').container;
const deps = require('./package.json').dependencies;

module.exports = (env, argv) => {
    const mode = 'development';
    console.log({ mode });
    return {
        performance: {
            hints: false
        },
        entry: `./src/index.ts`,
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'mf2/mf2Module.js'
        },
        devServer: {
            port: 3000,
            open: false,
        },
        devtool: 'inline-source-map',
        mode,
        resolve: {
            extensions: ['.ts', '.tsx', '.js'],
        },
        module: {
            rules: [
                {
                    test: /\.(js|jsx|tsx|ts)$/,
                    loader: 'ts-loader',
                    exclude: /node_modules/,
                }
            ],
        },
        plugins: [
            new ModuleFederationPlugin({
                name: 'mf2',
                filename: 'remoteEntry.js',
                exposes: {
                    './AppModule': './src/App',
                },
                shared: {
                    ...deps,
                    react: { singleton: true, eager: true, requiredVersion: deps.react },
                    'react-dom': {
                        singleton: true,
                        eager: true,
                        requiredVersion: deps["react-dom"],
                    },
                },
            }),
            new HtmlWebpackPlugin({
                template: `./public/index.html`,
            }),
        ]
    };
};

解决思路

1. 确保React组件已封装为Web Component

Angular的WebComponentWrapper仅支持渲染标准Web Component,普通React组件无法直接被识别。需将React组件转换为自定义元素:

  • 安装转换工具:npm install @r2wc/react-to-web-component
  • 修改src/App.tsx,封装并注册自定义元素:
import React from 'react';
import r2wc from '@r2wc/react-to-web-component';

const App = () => {
  return <div>React MFE Content</div>;
};

// 将React组件转为Web Component,若有props可在此定义类型
const ReactElement = r2wc(App, {});

// 注册自定义元素,名称需与宿主配置的elementName完全一致
customElements.define('react-element', ReactElement);

export default App;

2. 调整React应用入口逻辑

单独运行时的渲染逻辑会与微前端模式冲突,需区分环境加载不同逻辑:

  • 创建src/bootstrap.tsx,存放单独运行时的渲染代码:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  • 修改src/index.ts,根据环境判断加载逻辑:
// 判断是否作为微前端远程模块加载
if (!window['__webpack_init_sharing__']) {
  // 单独运行时执行渲染逻辑
  import('./bootstrap');
} else {
  // 作为远程模块时,仅注册Web Component,由宿主负责渲染
  import('./App');
}

3. 检查共享依赖一致性

确保Angular宿主与React远程应用的React、ReactDOM版本完全一致,且宿主也配置了对应共享依赖(若未配置,需在宿主的ModuleFederationPlugin中添加):

// 宿主应用ModuleFederation配置示例
shared: {
  react: { singleton: true, eager: true, requiredVersion: 'x.x.x' },
  'react-dom': { singleton: true, eager: true, requiredVersion: 'x.x.x' },
}

4. 排查浏览器控制台错误

打开浏览器开发者工具Console标签,重点查看以下类型错误:

  • 自定义元素未定义(Uncaught ReferenceError: CustomElement is not defined)
  • React初始化失败(如版本冲突、重复加载)
  • DOM节点找不到(Target container is not a DOM element)

5. 确认远程模块导出路径

检查React应用ModuleFederationPlugin的exposes配置,确保./AppModule指向的文件确实导出了已封装的Web Component,且与宿主路由配置的exposedModule完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 14:18:00