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

Angular如何异步声明组件并像常规组件一样在模板中使用

解决方案:结合Angular Elements与Webpack模块联邦实现运行时组件直接引用

针对你的需求——无需静态声明、直接在模板中使用异步加载的组件,同时结合微前端模块联邦实现免npm更新,最优方案是Angular Elements + Webpack模块联邦,具体步骤如下:


1. 将公共库改造为远程MFE(模块联邦)

1.1 把目标组件转为Angular自定义元素

在公共库的组件模块中,使用Angular官方API将FooComponent包装为标准自定义元素,这样浏览器可以原生识别组件选择器:

// 公共库/src/app/foo/foo.module.ts
import { NgModule, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { FooComponent } from './foo.component';

@NgModule({
  declarations: [FooComponent],
  imports: [BrowserModule],
  entryComponents: [FooComponent] // AOT编译需要配置该项
})
export class FooModule {
  constructor(private injector: Injector) {
    // 注册自定义元素,与模板中使用的选择器一致
    const FooElement = createCustomElement(FooComponent, { injector });
    customElements.define('foo-component', FooElement);
  }

  ngDoBootstrap() {} // 无需启动根组件,仅注册自定义元素
}

1.2 配置Webpack模块联邦

在公共库的Webpack配置文件(或angular.json的自定义Webpack配置)中添加模块联邦插件,暴露组件模块:

// 公共库/webpack.config.js
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'fooRemote',
      filename: 'remoteEntry.js',
      exposes: {
        './FooModule': './src/app/foo/foo.module.ts',
      },
      // 共享Angular核心依赖,避免重复加载与版本冲突
      shared: {
        '@angular/core': { singleton: true, strictVersion: true },
        '@angular/common': { singleton: true, strictVersion: true },
        '@angular/platform-browser': { singleton: true, strictVersion: true }
      }
    }),
  ],
};

2. 配置宿主Angular应用

2.1 加载远程MFE入口文件

在宿主应用的index.html中添加远程MFE的入口脚本(也可在代码中动态加载):

<!-- 宿主应用/src/index.html -->
<script src="http://你的远程MFE部署地址/remoteEntry.js"></script>

2.2 启用自定义元素支持并动态加载远程模块

修改宿主应用的app.module.ts,添加自定义元素支持,并在初始化时动态导入远程模块:

// 宿主应用/src/app/app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA] // 允许模板使用未静态声明的自定义元素
})
export class AppModule {
  constructor() {
    this.loadRemoteComponent();
  }

  async loadRemoteComponent() {
    // 动态导入远程模块,触发自定义元素的注册逻辑
    await import('fooRemote/FooModule');
  }
}

2.3 直接在模板中使用组件

现在可以像静态声明的组件一样,直接在app.component.html中引用:

<!-- 宿主应用/src/app/app.component.html -->
<foo-component></foo-component>

核心原理说明

  • Angular Elements:将Angular组件转为W3C标准的自定义元素,让浏览器原生识别组件选择器,无需Angular编译时静态声明。
  • Webpack模块联邦:实现运行时动态加载远程模块,公共库更新后,宿主应用无需执行npm install,直接拉取最新版本代码。
  • 共享依赖配置:确保Angular核心包只加载一次,避免版本冲突与冗余打包。

内容的提问来源于stack exchange,提问作者Duc Trung Mai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:20:27