You need to enable JavaScript to run this app. 如何通过Module Federation在Angular中动态加载远程组件并本地使用
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Module Federation在Angular中动态加载远程组件并本地使用

实现方案

步骤1:配置主应用的Module Federation

先在主应用的Module Federation配置中添加远程应用app1的映射,替换为你实际的子应用部署地址:

new ModuleFederationPlugin({
  name: "host",
  remotes: {
    app1: "app1@http://localhost:4201/app1.js",
  },
  shared: {
    "@angular/core": { singleton: true, strictVersion: true },
    "@angular/common": { singleton: true, strictVersion: true },
    "@angular/router": { singleton: true, strictVersion: true },
  }
})

步骤2:修改AppModule配置

导入必要依赖,加载远程组件并注册为自定义元素,同时添加自定义元素识别规则:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { loadRemoteModule } from '@angular-architects/module-federation';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  // 允许Angular识别非本地注册的自定义标签
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { 
  constructor(private injector: Injector) {
    // 应用启动时加载远程Heroes组件,注册为原生自定义元素
    loadRemoteModule({
      remoteEntry: 'http://localhost:4201/app1.js',
      remoteName: 'app1',
      exposedModule: './Heroes'
    }).then(remoteModule => {
      const HeroesElement = createCustomElement(remoteModule.HeroesComponent, {
        injector: this.injector
      });
      // 注册到浏览器自定义元素注册表,标签名和组件selector保持一致
      customElements.define('app-heroes', HeroesElement);
    })
  }
}

步骤3:直接使用组件

配置完成后,即可在主应用任意模板中直接使用<app-heroes></app-heroes>标签,使用体验和本地组件完全一致。


可选方案:封装本地代理组件(无需全局注册)

如果不需要全局使用该组件,可以创建本地代理组件动态加载远程组件,无需注册自定义元素:

// heroes-wrapper.component.ts
import { Component, ViewChild, ViewContainerRef, OnInit } from '@angular/core';
import { loadRemoteModule } from '@angular-architects/module-federation';

@Component({
  selector: 'app-heroes',
  template: `<ng-template #container></ng-template>`
})
export class HeroesWrapperComponent implements OnInit {
  @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;

  async ngOnInit() {
    const remoteModule = await loadRemoteModule({
      remoteEntry: 'http://localhost:4201/app1.js',
      remoteName: 'app1',
      exposedModule: './Heroes'
    });
    this.container.createComponent(remoteModule.HeroesComponent);
  }
}

将该代理组件加入AppModule的declarations数组即可,同样可以直接使用<app-heroes></app-heroes>标签。


注意事项

  • 主应用和远程应用的Angular核心依赖版本尽量保持一致,避免运行时冲突
  • 若远程组件使用了其他Angular指令(如*ngIf、*ngFor等),需要确保依赖的CommonModule等模块在shared配置中被标记为单例,或者远程组件使用standalone配置自行导入依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 01:06:02