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

使用Webpack模块联邦加载远程React应用时出现TypeError: fn is not a function

问题原因分析

这个fn is not a function错误核心原因有两点:

  1. 类型不匹配:Angular路由的loadChildren要求加载的是返回Angular模块工厂的函数,但远程导出的是React组件,并非Angular可识别的模块格式,导致Angular无法解析成可执行的初始化函数,触发错误。
  2. Remotes配置格式问题:正确的远程模块配置格式应为[远程应用名称]@[remoteEntry地址],之前加前缀出现解析错误,大概率是远程应用的remoteEntry.js未正确暴露,或是Angular侧的Module Federation配置未正确处理模块解析逻辑。
调试与解决步骤

1. 修正Remotes配置格式

先确保Angular宿主的webpack.config.js中ModuleFederationPlugin的remotes配置正确:

new ModuleFederationPlugin({
  name: 'angularHost',
  remotes: {
    reactApp: 'reactApp@http://localhost:4203/remoteEntry.js'
  },
  // 其他shared等配置
})

同时验证远程React项目的配置正确性:

// React项目webpack.config.js
new ModuleFederationPlugin({
  name: 'reactApp',
  filename: 'remoteEntry.js',
  exposes: {
    './ReactApp': './src/App.tsx'
  },
  // shared配置
})

检查http://localhost:4203/remoteEntry.js是否能在浏览器正常访问,确认返回合法JS内容。

2. 改用Angular封装组件加载React应用

loadChildren是专为Angular模块设计的,加载React组件需要通过动态导入+Angular组件封装的方式实现:

步骤1:创建React封装组件

在Angular项目中新建组件,用于渲染React组件:

// react-wrapper.component.ts
import { Component, OnInit, ElementRef, OnDestroy } from '@angular/core';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ReactApp } from 'reactApp/ReactApp';

@Component({
  selector: 'app-react-wrapper',
  template: '<div #reactRoot></div>'
})
export class ReactWrapperComponent implements OnInit, OnDestroy {
  private root: ReactDOM.Root | null = null;

  constructor(private el: ElementRef) {}

  ngOnInit(): void {
    const container = this.el.nativeElement.querySelector('#reactRoot');
    this.root = ReactDOM.createRoot(container);
    this.root.render(React.createElement(ReactApp));
  }

  ngOnDestroy(): void {
    this.root?.unmount();
  }
}

步骤2:配置Angular路由

使用loadComponent实现懒加载,替代loadChildren:

// app-routing.module.ts
const routes: Routes = [
  // 其他路由
  {
    path: 'react-app',
    loadComponent: () => import('./react-wrapper/react-wrapper.component').then(m => m.ReactWrapperComponent)
  }
];

步骤3:修正模块声明文件

确保decl.d.ts正确声明远程模块类型:

// decl.d.ts
declare module 'reactApp/ReactApp' {
  import type { ComponentType } from 'react';
  const ReactApp: ComponentType;
  export default ReactApp;
}

3. 调试远程模块加载过程

如果问题仍存在,通过以下方式排查:

  • 在浏览器开发者工具Sources面板中,找到remoteEntry.js设置断点,查看远程模块暴露的内容是否符合预期
  • 在封装组件中添加日志,确认远程模块导入结果:
// 在react-wrapper.component.ts的ngOnInit中添加
import('reactApp/ReactApp').then(module => {
  console.log('远程模块内容:', module);
  // 确认module.default是合法的React组件
});
  • 检查shared依赖版本一致性,确保React、ReactDOM等依赖在两个项目中版本匹配,且shared配置正确:
// 两端项目的shared配置示例
shared: {
  react: { singleton: true, requiredVersion: '^18.2.0' },
  'react-dom': { singleton: true, requiredVersion: '^18.2.0' }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:16:29