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

基于Module Federation的Angular微前端:远程模块并排展示及路由需求

解决方案:Angular Module Federation 微前端并排展示与独立路由实现

一、实现远程模块并排展示

要在壳应用中横向并排展示Mfe1和Mfe2的模块,核心是通过布局容器承载动态加载的远程组件:

  1. 确认壳应用的远程模块配置
    确保壳应用的webpack.config.js已正确注册远程模块:
// shell webpack.config.js
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'shell',
      remotes: {
        mfe1: 'mfe1@http://localhost:3001/remoteEntry.js',
        mfe2: 'mfe2@http://localhost:3002/remoteEntry.js'
      }
    })
  ]
};
  1. 用Flex布局搭建并排容器
    在壳应用的宿主组件模板(如app.component.html)中创建弹性布局容器,为每个微前端预留占位:
<!-- app.component.html -->
<div class="mfe-grid">
  <div class="mfe-card">
    <ng-template #mfe1Host></ng-template>
  </div>
  <div class="mfe-card">
    <ng-template #mfe2Host></ng-template>
  </div>
</div>

配套CSS实现并排布局:

.mfe-grid {
  display: flex;
  gap: 24px;
  padding: 24px;
  flex-wrap: wrap;
}
.mfe-card {
  flex: 1;
  min-width: 400px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
  1. 动态加载远程组件到占位容器
    在宿主组件类中,通过loadRemoteModule将远程组件渲染到对应占位:
// app.component.ts
import { Component, ViewChild, ViewContainerRef, OnInit } from '@angular/core';
import { loadRemoteModule } from '@angular-architects/module-federation';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  @ViewChild('mfe1Host', { read: ViewContainerRef }) mfe1Host!: ViewContainerRef;
  @ViewChild('mfe2Host', { read: ViewContainerRef }) mfe2Host!: ViewContainerRef;

  async ngOnInit() {
    // 加载Mfe1主组件
    const mfe1Module = await loadRemoteModule({
      remoteName: 'mfe1',
      exposedModule: './MainComponent'
    });
    this.mfe1Host.createComponent(mfe1Module.Mfe1MainComponent);

    // 加载Mfe2主组件
    const mfe2Module = await loadRemoteModule({
      remoteName: 'mfe2',
      exposedModule: './MainComponent'
    });
    this.mfe2Host.createComponent(mfe2Module.Mfe2MainComponent);
  }
}

二、实现远程模块的独立路由导航

要让微前端内的列表→详情导航不影响壳应用路由,可通过路由前缀隔离或组件内独立路由实现:

方案1:路由前缀隔离(推荐)

给每个微前端分配专属路由前缀,壳应用仅作为路由分发入口:

  1. 壳应用配置路由占位
    在壳应用的app-routing.module.ts中,为每个微前端配置路由入口,加载远程路由模块:
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { loadRemoteModule } from '@angular-architects/module-federation';

const routes: Routes = [
  {
    path: 'mfe1',
    loadChildren: () =>
      loadRemoteModule({
        remoteName: 'mfe1',
        exposedModule: './RoutingModule'
      }).then(m => m.Mfe1RoutingModule)
  },
  {
    path: 'mfe2',
    loadChildren: () =>
      loadRemoteModule({
        remoteName: 'mfe2',
        exposedModule: './RoutingModule'
      }).then(m => m.Mfe2RoutingModule)
  },
  { path: '', redirectTo: '/mfe1', pathMatch: 'full' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
  1. 微前端内部配置子路由
    在Mfe1的mfe1-routing.module.ts中,配置自身的列表、详情路由(无需前缀):
// mfe1-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Mfe1ListComponent } from './list/list.component';
import { Mfe1DetailComponent } from './detail/detail.component';

const routes: Routes = [
  { path: '', component: Mfe1ListComponent },
  { path: 'detail/:id', component: Mfe1DetailComponent }
];

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

此时Mfe1的导航路径为/mfe1/detail/1,Mfe2为/mfe2/detail/2,完全独立于壳应用路由,互不干扰。

方案2:组件内独立路由(无URL变化)

若无需修改URL,可通过组件状态传递实现导航:

// mfe1-list.component.ts
import { Component } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Mfe1DetailComponent } from '../detail/detail.component';

@Component({
  selector: 'app-mfe1-list',
  templateUrl: './list.component.html'
})
export class Mfe1ListComponent {
  constructor(private dialog: MatDialog) {}

  openDetail(id: number) {
    // 通过弹窗展示详情,不修改路由
    this.dialog.open(Mfe1DetailComponent, {
      data: { id },
      width: '600px'
    });
  }
}

关键配置检查

确保微前端的webpack.config.js正确暴露路由模块:

// mfe1 webpack.config.js
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'mfe1',
      filename: 'remoteEntry.js',
      exposes: {
        './MainComponent': './src/app/main/main.component.ts',
        './RoutingModule': './src/app/mfe1-routing.module.ts'
      }
    })
  ]
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:23:17