Angular微前端路由加载报错:Cannot read properties of undefined (reading 'ɵmod')
Angular微前端路由加载报错:Cannot read properties of undefined (reading 'ɵmod')
问题场景
基于Angular构建微前端,使用以下路由配置代码:
import { loadRemoteModule } from './federation-utils'; import { Routes } from '@angular/router'; import { APP_ROUTES } from '../app.routes'; import { Microfrontend } from '../core/services/microfrontends/microfrontend.types'; export function buildRoutes(options: Microfrontend[]): Routes { const lazyRoutes: Routes = options.map((o) => ({ path: o.routePath, loadChildren: () => loadRemoteModule(o).then((m) => m[o.ngModuleName]), canActivate: o.canActivate, pathMatch: 'full' })); return [ ...APP_ROUTES, ...lazyRoutes ]; }
运行时触发错误:
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'ɵmod')
微前端配置(options)
[ { "remoteEntry": "http://localhost:4204/remoteEntry.js", "remoteName": "dashboard", "exposedModule": "DashboardModule", "displayName": "Dashboard", "routePath": "", "ngModuleName": "DashboardModule", "canActivate": [ null ] }, { "remoteEntry": "http://localhost:4202/remoteEntry.js", "remoteName": "table", "exposedModule": "TablePageModule", "displayName": "Table", "routePath": "table", "ngModuleName": "TablePageModule" }, { "remoteEntry": "http://localhost:4201/remoteEntry.js", "remoteName": "register", "exposedModule": "RegisterPageModule", "displayName": "Register", "routePath": "signup", "ngModuleName": "RegisterPageModule", "canActivate": [ null ] }, { "remoteEntry": "http://localhost:4203/remoteEntry.js", "remoteName": "staticPage", "exposedModule": "StaticPageModule", "displayName": "Static page", "routePath": "static", "ngModuleName": "StaticPageModule" } ]
控制台输出截图



解决方案
1. 适配ModuleWithProviders返回值
从控制台截图可见,远程模块返回的是ModuleWithProviders类型,而非直接的NgModule类。调整loadChildren回调,提取实际模块:
loadChildren: () => loadRemoteModule(o).then((m) => { const targetModule = m[o.ngModuleName]; // 若为ModuleWithProviders则取module属性,否则直接返回模块 return targetModule.module || targetModule; }),
2. 修正远程模块的导出方式
确保远程模块直接导出NgModule类,避免默认导出或嵌套导出:
// 远程模块示例(DashboardModule) import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; @NgModule({ imports: [CommonModule], declarations: [] }) export class DashboardModule { } // 直接导出类,不要用export default
3. 检查模块联邦的exposes配置
远程应用的webpack配置中,exposes的键需以相对路径格式定义,确保主应用能正确加载:
// 远程应用webpack.config.js const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); module.exports = { plugins: [ new ModuleFederationPlugin({ name: 'dashboard', filename: 'remoteEntry.js', exposes: { './DashboardModule': './src/app/dashboard/dashboard.module.ts', // 用相对路径作为键 }, // 其他配置... }), ], };
同时同步修改options中的exposedModule值为./DashboardModule。
4. 清理无效的路由守卫配置
移除canActivate数组中的null值,避免路由初始化失败:
// 修改前 "canActivate": [null] // 修改后:保留空数组或删除该字段(无需守卫时) "canActivate": []
5. 统一Angular版本
主应用与所有微前端应用的@angular/core、@angular/router等核心包版本必须完全一致,版本不匹配会导致模块内部标识(如ɵmod)无法被识别。
内容的提问来源于stack exchange,提问作者user3653474
相关产品推荐
相关产品推荐

