Angular CLI 设置
本指南介绍了如何将模块联邦(Module Federation)与 Angular CLI 集成。使用 @angular-architects/module-federation 插件来协助完成这一集成。
前置要求
- Angular CLI: 需要版本 10 或更高。
- 插件安装: 安装 @angular-architects/module-federation插件。
安装
你需要在构建阶段配置 Angular CLI 以使用模块联邦。
为了充分发挥模块联邦的潜力,需要一个自定义构建器。
@angular-architects/module-federation 包提供了这个自定义构建器。
使用 ng add 命令将它整合到你的项目中:
ng add @angular-architects/module-federation --project shell --port 4200 --type host
ng add @angular-architects/module-federation --project mfe1 --port 4201 --type remote
在版本 14.3 中引入的 --type 参数确保只生成必要的配置。
Shell (消费者)配置
Shell(消费者)对于模块联邦(Module Federation)集成至关重要。
本节配置了支持通过路由来懒加载 FlightModule 的 Shell。
路由配置
首先定义应用程序的路由,使用虚拟路径指定懒加载的 FlightModule:
export const APP_ROUTES: Routes = [
  {
    path: '',
    component: HomeComponent,
    pathMatch: 'full'
  },
  {
    path: 'flights',
    loadChildren: () => import('mfe1/Module').then(m => m.FlightsModule)
  },
];
在这个配置中,路径 'mfe1/Module' 是一个虚拟表示,表明它在 Shell 应用程序中并不实际存在。相反,它是对另一个独立项目中的模块的引用。
类型提示
为虚拟路径创建一个类型定义:
// decl.d.ts
declare module 'mfe1/Module';
这有助于 TypeScript 编译器理解虚拟路径。
Webpack 配置
配置 Webpack 将所有前缀为 mfe1 的路径解析为一个远程项目。这是在 webpack.config.js 文件中完成的:
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
   remotes: {
     "mfe1": "http://localhost:4201/remoteEntry.js",
   },
   shared: {
     ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
   },
});
在开发中,直接硬编码远程入口的 URL 就足够了。然而,对于生产环境,需要采用动态方法。动态远程的概念在专门的文档页面“动态远程”中进一步探讨。
- shared属性指定了 Shell 和微前端(们)之间要共享的 npm 包。使用- shareAll辅助方法,可以共享- package.json中列出的所有依赖。这虽然便于快速设置,但可能导致共享依赖过多,这可能会对优化造成影响。
- singleton: true和- strictVersion: true的组合设置指示,如果 Shell 和微前端(们)之间存在版本不匹配,Webpack 将抛出运行时错误。将- strictVersion更改为- false将改为运行时警告。
- requiredVersion: 'auto'选项,由- @angular-architects/module-federation插件提供,可以自动从- package.json确定版本,有助于防止与版本相关的问题。
配置生产者
生产者,也称为模块联邦中的远程模块,其结构类似于标准的 Angular 应用。它在 AppModule 中有特定的路由,并且有一个用于航班相关任务的 FlightsModule。本节解释了如何将 FlightsModule 平滑地加载到 Shell(宿主)中。
路由定义
在 AppModule 内部建立基本路由:
export const APP_ROUTES: Routes = [
     { path: '', component: HomeComponent, pathMatch: 'full'}
 ];
这个简单的路由设置在应用程序被访问时导航到 HomeComponent。
创建模块
创建一个 FlightsModule 来处理与航班相关的操作:
@NgModule({
   imports: [
     CommonModule,
     RouterModule.forChild(FLIGHTS_ROUTES)
   ],
   declarations: [
     FlightsSearchComponent
   ]
 })
 export class FlightsModule { }
该模块包含一条路由,指向如下定义的 FlightsSearchComponent:
export const FLIGHTS_ROUTES: Routes = [
     {
       path: 'flights-search',
       component: FlightsSearchComponent
     }
 ];
配置生产者
为了将 FlightsModule 加载到 Shell 中,通过 Remote 的 Webpack 配置来公开它:
const { shareAll, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
   name: 'mfe1',
   exposes: {
     './Module': './projects/mfe1/src/app/flights/flights.module.ts',
   },
   shared: {
     ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
   },
});
在这种配置中:
- name属性将微前端标识为- mfe1。
- exposes属性意味着- FlightsModule在公共名称- Module下的暴露,允许 Shell 进行引用。
- shared属性列出了将与 Shell 共享的库,使用- shareAll方法共享- package.json中找到的所有依赖。- singleton: true和- strictVersion: true属性确保使用共享库的单一版本,并且在版本不兼容的情况下触发运行时错误。
启动应用
设置好 Shell(宿主)和 Micro-frontend(远程),就可以启动项目测试效果。
要启动 Shell 和 Micro-frontend,请使用以下命令:
ng serve shell -o
ng serve mfe1 -o
在 Shell 中导航到 Flights 部分,以查看微前端被动态加载。
TIP
该插件在 ng-add 和 init schematics 过程中安装了一个 npm 脚本 run:all,允许同时提供所有应用程序的服务:
npm run run:all
# or
npm run run:all shell mfe1
优化依赖共享
使用 shareAll 的初始设置简单且实用,但可能导致创建过大的共享包。
为了更有效地管理共享依赖项,请考虑从 shareAll 切换到使用 share 辅助函数。这样可以更细致地控制哪些依赖项被共享:
// Replace shareAll with share:
const { share, withModuleFederationPlugin } = require('@angular-architects/module-federation/webpack');
module.exports = withModuleFederationPlugin({
    // Specify the packages to share:
    shared: share({
        "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
    })
});
在这种配置中,share 辅助函数允许显式共享选定的包,从而实现更优化的包共享,并有可能减少加载时间。