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

Angular 14 Module Federation单远程不可用致应用整体失效问题

多微前端Angular项目Module Federation v14迁移后远程端点不可用导致应用崩溃问题

我们的多微前端Angular项目基于Manfred Steyer的Module Federation库构建。从v12迁移到v14后出现异常:当某一远程端点不可用时,整个应用直接停止运行并显示空白页面;而在v12版本中,仅该不可用的微前端无法访问,其余功能可正常使用。

Shell应用Webpack配置

const { share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

module.exports = withModuleFederationPlugin({
  name: 'shell',
  filename: 'shell.js',

  sharedMappings: ['frontend/mfe-shared'],

  exposes: {
    './Module': 'apps/shell/src/app/app.module.ts',
  },
  remotes: {
    dashboard: `http://localhost:4201/dashboard.js`,
    offers: `http://localhost:4206/offers.js`,
    clients: `http://localhost:4206/clients.js`,
  },    
  shared: share({
    '@angular/core': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/common': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/common/http': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/router': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    'ngx-webstorage-service': { singleton: true, strictVersion: true },
  }),
});

Dashboard远程应用Webpack配置示例

const { share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');

module.exports = withModuleFederationPlugin({
  name: 'dashboard',
  filename: 'dashboard.js',

  sharedMappings: ['frontend/mfe-shared'],
  exposes: {
    './Module': 'apps/dashboard/src/app/app.module.ts',
  },

  shared: share({
    '@angular/core': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/common': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/common/http': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    '@angular/router': { singleton: true, strictVersion: true, requiredVersion: '14.2.12' },
    'ngx-webstorage-service': { singleton: true, strictVersion: true },
  }),
});

路由配置

const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('dashboard/Module').then(({ AppModule }) => AppModule),
  },
  {
    path: 'client',
    loadChildren: () => import('partner/Module').then(({ AppModule }) => AppModule),
  },
  {
    path: 'offers',
    loadChildren: () => import('iam/Module').then(({ IamModule }) => IamModule),
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', relativeLinkResolution: 'legacy', paramsInheritanceStrategy: 'always' }),
  ],
  exports: [RouterModule],
})
export class AppRoutingModule {}

使用版本

  • Angular 14.2.12
  • @angular-architects/module-federation: 14.3.14

问题原因与修复方案

Module Federation v14默认会在应用初始化阶段尝试加载所有配置的远程模块,一旦某个远程不可用,会直接中断应用初始化流程,导致空白页面。要恢复v12的容错性,需做以下调整:

  1. 动态加载远程模块,避免初始化时预加载
    修改Shell的Webpack配置,将remotes改为动态导入的方式,仅在实际需要时加载对应远程模块:

    remotes: {
      dashboard: () => import('@angular-architects/module-federation/webpack').then(m => m.loadRemote({
        type: 'module',
        remoteEntry: 'http://localhost:4201/dashboard.js',
        exposedModule: './Module',
        remoteName: 'dashboard'
      })),
      offers: () => import('@angular-architects/module-federation/webpack').then(m => m.loadRemote({
        type: 'module',
        remoteEntry: 'http://localhost:4206/offers.js',
        exposedModule: './Module',
        remoteName: 'offers'
      })),
      clients: () => import('@angular-architects/module-federation/webpack').then(m => m.loadRemote({
        type: 'module',
        remoteEntry: 'http://localhost:4206/clients.js',
        exposedModule: './Module',
        remoteName: 'clients'
      })),
    },
    
  2. 为路由加载添加错误捕获
    创建一个备用的错误模块(用于显示微前端不可用的提示),然后在路由的loadChildren中添加catch逻辑,当远程模块加载失败时跳转至该模块:

    // 备用错误模块示例
    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { MfeUnavailableComponent } from './mfe-unavailable/mfe-unavailable.component';
    
    const errorRoutes: Routes = [
      { path: '', component: MfeUnavailableComponent }
    ];
    
    @NgModule({
      imports: [RouterModule.forChild(errorRoutes)],
      exports: [RouterModule]
    })
    export class MfeErrorModule {}
    
    // 修改后的路由配置
    const routes: Routes = [
      {
        path: 'dashboard',
        loadChildren: () => import('dashboard/Module')
          .then(({ AppModule }) => AppModule)
          .catch(() => import('./mfe-error/mfe-error.module').then(m => m.MfeErrorModule)),
      },
      {
        path: 'client',
        loadChildren: () => import('partner/Module')
          .then(({ AppModule }) => AppModule)
          .catch(() => import('./mfe-error/mfe-error.module').then(m => m.MfeErrorModule)),
      },
      {
        path: 'offers',
        loadChildren: () => import('iam/Module')
          .then(({ IamModule }) => IamModule)
          .catch(() => import('./mfe-error/mfe-error.module').then(m => m.MfeErrorModule)),
      }
    ];
    
  3. 常规检查:共享依赖配置
    确认共享依赖的strictVersion和requiredVersion配置符合项目实际情况,避免因依赖版本不匹配引发额外加载问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:20:40