בחלק הראשון ראינו איך להתקין ובחלק הזה נראה איך לבצע משיכה של מודול לתוך הפרויקט הראשי (SHELL)
נתחיל עם MFE1
בתוך ספרית APP ניצור ספריה PAGES ובתוכה נריץ את הפקודה הבאה:
ng g m main
הפקודה הזו תיצור ספריה נוספת בשם MAIN ובתוכה מודול באותו השם.
נכנס לספריה ונריץ את הפקודות הבאות:
ng g c lazy-header ng g c lazy-content ng g c lazy-footer
שימו לב ששלושת הרכיבים נרשמים במודול main.
נעבור לקובץ HTML של הרכיב lazy-content ונשנה אותו שיראה כך:
<app-lazy-header></app-lazy-header> <p>lazy-content works!</p> <app-lazy-footer></app-lazy-footer>
כל מה שהוספנו זה את רכיב lazy-header ו-lazy-footer.
בספרית main ניצור קובץ נוסף שיבצע ראוטינג לרכיב lazy-content והוא יראה כך:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LazyContentComponent } from './lazy-content/lazy-content.component';
const routes: Routes = [
{ path: '', component: LazyContentComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class MainRoutingModule { }נעדכן את main.module
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LazyHeaderComponent } from './lazy-header/lazy-header.component';
import { LazyContentComponent } from './lazy-content/lazy-content.component';
import { LazyFooterComponent } from './lazy-footer/lazy-footer.component';
import { MainRoutingModule } from './main-routing.module';
@NgModule({
declarations: [
LazyHeaderComponent,
LazyContentComponent,
LazyFooterComponent
],
imports: [
CommonModule,
MainRoutingModule
]
})
export class MainModule { }
ולבסוף נעדכן גם את הראוט הראשי
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: 'lazy', loadChildren: () => import('./pages/main/main.module').then(m => {
return m.MainModule;
})
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
אחרי ששמרנו את כל הקבצים נריץ את הפרויקט (אם הוא לא רץ כבר) – ng s.
נגלוש ב-URL לכתובת הזו : localhost:3000/lazy ונראה שאכן הגיעו שלושת הרכיבים שלנו.
lazy-header works! lazy-content works! lazy-footer works!
כל מה שנשאר לנו זה לחשוף את המודול שלנו:
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, 'tsconfig.json'),
[/* mapped paths to share */]);
module.exports = {
output: {
uniqueName: "mfe1",
publicPath: "auto"
},
optimization: {
runtimeChunk: false
},
resolve: {
alias: {
...sharedMappings.getAliases(),
}
},
experiments: {
outputModule: true
},
plugins: [
new ModuleFederationPlugin({
library: { type: "module" },
// For remotes (please adjust)
name: "mfe1",
filename: "mfe1.js",
exposes: {
'./MainModule':path.resolve(__dirname, 'src/app/pages/main/main.module.ts')
},
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' },
...sharedMappings.getDescriptors()
})
}),
sharedMappings.getPlugin()
],
};
חשוב מאוד!! כל שינוי שאתם עושים בקובץ הנ"ל יש לעצור את השרת (CTRL+C) ולהפעיל מחדש (ng s).
סיימנו בצד של MFE1 ועכשיו נטפל ב-SHELL
SHELL
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
const routes: Routes = [
{
path: 'lazy', loadChildren: () => import('mfe1/MainModule').then(m => {
return m.MainModule;
})
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }שימו לב שכאשר ננסה לצרוך את mfe1/MainModule תעלה לנו שגיאה ש-TS לא מכיר את המודול הזה, ולכן כדי להגיד ל-TS שיש דבר כזה ניצור קובץ בתוך ספרית APP בשם MFE.d.ts .
זה קובץ הצהרה שהתפקיד שלו בסה"כ להרגיע את ה-TS 😉.
declare module 'mfe1/MainModule';
הדבר האחרון שנשאר לנו לעדכן הוא בפרויקט SHELL את הקובץ הבא:
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;
const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
path.join(__dirname, 'tsconfig.json'),
[/* mapped paths to share */]);
module.exports = {
output: {
uniqueName: "shell",
publicPath: "auto"
},
optimization: {
runtimeChunk: false
},
resolve: {
alias: {
...sharedMappings.getAliases(),
}
},
experiments: {
outputModule: true
},
plugins: [
new ModuleFederationPlugin({
library: { type: "module" },
// For hosts (please adjust)
remotes: {
"mfe1": "http://localhost:3000/mfe1.js",
},
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' },
...sharedMappings.getDescriptors()
})
}),
sharedMappings.getPlugin()
],
};
שורה 33: זו השורה שתמשוך את הסקריפט שחושף את הרכיבים ב-MFE1.
לא לשכוח לעצור את הקומפיילר ולהפעיל אותו מחדש.
אם נגלוש ל: http://localhost:5000/lazy נקבל דף עם שלושת הרכיבים שלנו.
lazy-header works! lazy-content works! lazy-footer works!
רק שעכשיו אנחנו נמצאים בכלל ב-SHELL ולא ב-MFE1….. מדהים 🧙♂️.
בחלק הבא נראה איך לקחת רכיבים ב-MFE ולהכניס אותם לדף שנמצא ב-SHELL ללא ראוטינג 😁





