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

Angular微前端:如何通过Webpack Module Federation在App2模态框中调用App1组件

在Webpack Module Federation微前端架构中,Angular跨应用在模态框加载组件的实现方法

一、配置App1(远程应用,暴露目标组件)

首先要让App1把需要共享的组件暴露出来,通过Module Federation的配置实现:

  1. 修改App1的webpack.config.js(如果用@angular-architects/module-federation搭建的项目,该文件在项目根目录),在ModuleFederationPlugin中添加exposes字段,指定要暴露的组件路径:
// App1 webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
const { AngularFederationPlugin } = require('@angular-architects/module-federation');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'App1',
      filename: 'remoteEntry.js', // 固定的远程入口文件名
      exposes: {
        // 键是给宿主应用调用的别名,值是组件的相对路径
        './TargetComponent': './src/app/target/target.component.ts',
      },
      shared: {
        // 共享Angular核心依赖,确保单例和版本一致
        '@angular/core': { singleton: true, strictVersion: true },
        '@angular/common': { singleton: true, strictVersion: true },
        '@angular/router': { singleton: true, strictVersion: true },
        // 其他需要跨应用共享的依赖(比如RxJS等)
      }
    }),
    new AngularFederationPlugin()
  ]
};
  1. 确保要暴露的组件(比如TargetComponent)是独立可复用的:模板、样式自包含,避免依赖App1独有的全局服务或样式;如果有依赖,要么把依赖加入shared配置,要么在App2中提供对应的服务实例。

二、配置App2(宿主应用,加载远程组件)

接下来在App2中配置远程应用的地址,实现组件的动态加载:

  1. 修改App2的webpack.config.js,在ModuleFederationPlugin中添加remotes字段,指向App1的remoteEntry.js地址:
// App2 webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
const { AngularFederationPlugin } = require('@angular-architects/module-federation');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'App2',
      remotes: {
        // 格式:[远程应用别名]@[remoteEntry.js的访问地址]
        App1: 'App1@http://localhost:4200/remoteEntry.js', // 开发环境地址
      },
      shared: {
        // 和App1保持一致的共享依赖配置,避免版本冲突
        '@angular/core': { singleton: true, strictVersion: true },
        '@angular/common': { singleton: true, strictVersion: true },
        '@angular/router': { singleton: true, strictVersion: true },
      }
    }),
    new AngularFederationPlugin()
  ]
};

生产环境部署时,把地址改成App1实际的部署域名(比如https://your-app1-domain.com/remoteEntry.js)。

  1. 在App2中创建一个远程组件的包装组件,用来异步加载App1的组件:
// App2/src/app/remote-wrapper/remote-wrapper.component.ts
import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';

@Component({
  selector: 'app-remote-wrapper',
  template: '<div #container></div>' // 用来渲染远程组件的容器
})
export class RemoteWrapperComponent implements OnInit {
  @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;

  constructor(private cfr: ComponentFactoryResolver) {}

  async ngOnInit() {
    // 动态导入App1暴露的组件
    const remoteComponentModule = await import('App1/TargetComponent');
    const componentFactory = this.cfr.resolveComponentFactory(remoteComponentModule.TargetComponent);
    // 在容器中创建组件实例
    const componentRef = this.container.createComponent(componentFactory);
    
    // 如果需要给远程组件传参或监听事件,在这里处理
    // componentRef.instance.inputProperty = 'xxx';
    // componentRef.instance.outputEvent.subscribe(() => { /* 处理逻辑 */ });
  }
}

记得在App2的模块中声明这个包装组件。


三、在App2的模态框中使用远程组件

假设App2用Angular Material的MatDialog作为模态框组件,步骤如下:

  1. 在需要触发模态框的组件中,注入MatDialog,并打开包装组件作为模态框内容:
// App2/src/app/trigger-component/trigger-component.component.ts
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { RemoteWrapperComponent } from '../remote-wrapper/remote-wrapper.component';

@Component({
  selector: 'app-trigger-component',
  template: '<button (click)="openRemoteModal()">打开App1组件模态框</button>'
})
export class TriggerComponent {
  constructor(private dialog: MatDialog) {}

  openRemoteModal() {
    this.dialog.open(RemoteWrapperComponent, {
      width: '600px',
      height: '400px',
      // 其他模态框配置(比如数据传递等)
    });
  }
}
  1. 确保App2的模块中导入了MatDialogModule和相关的Angular Material模块。

四、关键注意事项

  • 依赖版本一致性:App1和App2的共享依赖(比如Angular核心包)版本必须一致,否则会出现运行时错误。
  • 开发环境启动顺序:要先启动App1,再启动App2,确保App2能正常获取到App1的remoteEntry.js。
  • 组件通信:如果远程组件需要和App2交互,通过包装组件中转输入输出属性;复杂通信可以用共享的状态管理库(比如NgRx)或者自定义事件总线。
  • 生产部署:确保App1的remoteEntry.js地址配置正确,并且两个应用的CORS配置允许跨域访问(如果部署在不同域名下)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:54:19