Angular 微前端:模块联邦
模块联邦允许不同的 JavaScript 应用在运行时动态加载代码,无需将所有代码打包到同一个文件中。这意味着你可以将一个巨大的 Angular 单体应用拆分为多个独立开发、独立部署的小型应用。本指南将手把手教你使用 Angular 和 Module Federation 实现微前端架构。
准备工作
在开始之前,请确保本地开发环境已经准备就绪。
- 打开 终端或命令行工具。
- 检查 Node.js 版本,确保版本号在
v14或以上。输入 命令:node -v - 安装 Angular CLI(如果尚未安装)。输入 命令:
npm install -g @angular/cli
创建远程应用
远程应用是提供功能模块的一方,它将被宿主应用加载。
-
创建 一个新的 Angular 工程。输入 命令:
ng new mfe1 --routing --style=scss选择
No当询问是否添加 Server-Side Rendering (SSR) 时(为了简化配置)。 -
进入 项目目录:
cd mfe1 -
安装
@angular-architects/module-federation插件。这是目前配置 Angular 模块联邦最快捷的工具。输入 命令:ng add @angular-architects/module-federation --project mfe1 --port 4201系统会提示你配置类型,输入
remote并按下回车。 -
创建 一个待导出的组件。输入 命令:
ng generate component components/ticket -
打开
projects/mfe1/src/app/components/ticket/ticket.component.html文件。替换 其中的内容为以下代码,以便识别:<p style="border: 2px solid blue; padding: 10px;"> mfe1 Ticket Component Works! </p> -
配置 该组件为导出模块。打开
projects/mfe1/src/app/ticket.module.ts(如果没有该文件,请创建它)。写入 以下内容:import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TicketComponent } from './components/ticket/ticket.component'; @NgModule({ declarations: [ TicketComponent ], imports: [ CommonModule ], exports: [ TicketComponent ] }) export class TicketModule { } -
修改 模块联邦配置文件。打开
projects/mfe1/webpack.config.js。找到remotes配置项。确认 配置如下(插件通常已自动生成,但需核对):const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); module.exports = { // ... 其他配置 plugins: [ new ModuleFederationPlugin({ name: "mfe1", filename: "remoteEntry.js", exposes: { "./TicketModule": "./projects/mfe1/src/app/ticket.module.ts", }, shared: { "@angular/core": { singleton: true, strictVersion: true }, "@angular/common": { singleton: true, strictVersion: true }, "@angular/router": { singleton: true, strictVersion: true }, }, }), ], };
创建宿主应用
宿主应用是加载并展示远程应用的主程序。
-
回到 上级目录。创建 另一个 Angular 工程:
cd .. ng new shell --routing --style=scss同样选择
No针对 SSR。 -
进入 宿主项目目录:
cd shell -
安装 模块联邦插件。输入 命令:
ng add @angular-architects/module-federation --project shell --port 4200输入
host并按下回车。 -
修改 联邦配置以指向远程应用。打开
projects/shell/webpack.config.js。找到remotes部分。修改 配置如下:const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); module.exports = { // ... 其他配置 plugins: [ new ModuleFederationPlugin({ name: "shell", remotes: { mfe1: "http://localhost:4201/remoteEntry.js", }, shared: { "@angular/core": { singleton: true, strictVersion: true }, "@angular/common": { singleton: true, strictVersion: true }, "@angular/router": { singleton: true, strictVersion: true }, }, }), ], };
路由与加载配置
在宿主应用中配置路由,使其能够动态加载远程模块。
-
打开
projects/shell/src/app/app.routes.ts。清空 默认内容并写入 以下代码:import { Routes } from '@angular/router'; const routes: Routes = [ { path: 'tickets', loadChildren: () => import('mfe1/TicketModule').then(m => m.TicketModule) } ]; export default routes; -
修改 主应用组件模板以添加导航链接。打开
projects/shell/src/app/app.component.html。替换 内容为:<div style="text-align: center; margin-top: 50px;"> <h1>Shell Application</h1> <nav> <a routerLink="/tickets" style="margin: 10px; display: inline-block;">Load MFE1 Tickets</a> </nav> <router-outlet></router-outlet> </div> -
为了让 TypeScript 能够识别
mfe1/TicketModule这种导入语法,需要配置类型声明。打开projects/shell/src/decl.d.ts(如果不存在,请在src目录下创建此文件)。添加 以下内容:declare module 'mfe1/TicketModule';
运行与验证
现在,启动两个应用并验证微前端架构是否正常工作。
-
打开 两个独立的终端窗口。
-
在第一个终端中,进入 远程应用目录并启动 服务:
cd /path/to/mfe1 ng serve服务将运行在
http://localhost:4201/。等待编译完成,看到remoteEntry.js生成。 -
在第二个终端中,进入 宿主应用目录并启动 服务:
cd /path/to/shell ng serve服务将运行在
http://localhost:4200/。 -
打开 浏览器,访问
http://localhost:4200/。 -
点击 页面上的 "Load MFE1 Tickets" 链接。
-
检查 页面内容。你应该能看到带有蓝色边框的文字 "mfe1 Ticket Component Works!"。
架构原理图解
以下流程图描述了宿主应用如何通过 Module Federation 加载远程应用模块的过程:
常见问题处理
本地开发跨域错误 (CORS)
如果在宿主应用控制台看到跨域报错,通常是因为浏览器安全策略限制。
- 打开
projects/shell/angular.json。 - 找到
serve->options配置项。 - 添加 或 修改
headers配置:"headers": { "Access-Control-Allow-Origin": "*" }注意:这只是本地开发的一种快速解决方案,生产环境应在反向代理层(如 Nginx)处理。
共享依赖版本冲突
如果远程应用和宿主应用使用了不同版本的 Angular 或 RxJS,可能会导致运行时错误。
- 打开
webpack.config.js。 - 检查
shared配置。 - 设置
strictVersion: true可以确保版本严格一致,但可能会阻止加载。如果遇到问题,尝试改为strictVersion: false或设置requiredVersion: "auto"以允许较小的版本差异。
端口占用
确保 4200 和 4201 端口未被其他程序占用。如需更改端口,请修改 angular.json 中的 serve.options.port 或在启动命令中添加 --port 参数,并同步更新 webpack.config.js 中的 remotes URL 地址。

暂无评论,快来抢沙发吧!