DEV Community

Ruben
Ruben

Posted on

How to load an MFE module from a shell app (Using Angular + Webpack + Module Federation)?

Hi everyone, I have question for you. Do you know how load an MFE (micro front end) remote app, as a module from a shell app? when I try to do so there is an infinite loop. and the module from the MFE does not show. Any tips or ideas on how to accomplish this issue? (Using Angular + Webpack + Module Federation)

// webpack.config.js--SHELL APP const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const path = require("path"); module.exports = { output: { uniqueName: "portalWebApp", publicPath: "auto", scriptType: "text/javascript", }, optimization: { runtimeChunk: false, }, resolve: { alias: {}, }, module: { rules: [{ test: /\.html$/, use: ["html-loader"], }, ], }, experiments: { outputModule: true, }, plugins: [ new ModuleFederationPlugin({ // For remotes (please Add this 5 Line) name: "portalWebApp", filename: "remoteEntry.js", remotes: { astrPortFolioMasterWebApp: "astrPortFolioMasterWebApp@http://localhost:3002/remoteEntry.js", mfe1: "mfe1@http://localhost:4001/remoteEntry.js", }, shared: { "@angular/core": { singleton: true, strictVersion: true, eager: true }, "@angular/common/": { singleton: true, strictVersion: true, eager: true, }, "@angular/router": { singleton: true, strictVersion: true, eager: true, } // react: { singleton: true, eager: true }, // "react-dom": { singleton: true, eager: true }, }, }), ], }; // webpack.config.js--SHELL APP--END // SHELL APP - Route import { loadRemoteModule } from '@angular-architects/module-federation'; import { WebComponentWrapper, WebComponentWrapperOptions } from '@angular-architects/module-federation-tools'; import { Routes } from '@angular/router'; import { MsalGuard } from '@azure/msal-angular'; // import { MsalGuard } from '@azure/msal-angular'; // import { UserNotAllowedComponent } from './layout/user-not-allowed/user-not-allowed.component'; // import { ServerErrorComponent } from './layout/server-error/server-error.component'; export const routes: Routes = [{ path: '', pathMatch: 'full', loadChildren: () => import('./content-providers/content-provider.module').then( (m) => m.ContentProviderModule ), canActivate: [MsalGuard], }, { path: 'mfe1', loadChildren: () => { return loadRemoteModule({ type: 'module', remoteEntry: 'http://localhost:4001/remoteEntry.js', exposedModule: './OrderModule', }) .then((m) => m.OrderModule) .catch((e) => console.log(e)); }, }, { path: 'astrPortFolioMasterWebApp', loadChildren: () => { return loadRemoteModule({ type: 'module', remoteEntry: 'http://localhost:3002/remoteEntry.js', exposedModule: './astrPortFolioMasterWebAppModule', }) .then((m) => m.astrPortFolioMasterWebAppModule) .catch((e) => console.log(e)); }, }, { path: 'angular1', component: WebComponentWrapper, data: { remoteEntry: 'https://nice-grass-018f7d910.azurestaticapps.net/remoteEntry.js', remoteName: 'angular1', exposedModule: './web-components', elementName: 'angular1-element', } as WebComponentWrapperOptions, }, { path: 'react1', component: WebComponentWrapper, data: { remoteEntry: 'https://witty-wave-0a695f710.azurestaticapps.net/remoteEntry.js', remoteName: 'react', exposedModule: './web-components', elementName: 'react-element', } as WebComponentWrapperOptions, }, { path: 'vue', component: WebComponentWrapper, data: { remoteEntry: 'https://mango-field-0d0778c10.azurestaticapps.net/remoteEntry.js', remoteName: 'vue', exposedModule: './web-components', elementName: 'vue-element', } as WebComponentWrapperOptions, }, ]; // SHELL APP - Route // webpack.config.js--MFE / REMOTE APP const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); const { shareAll, SharedMappings } = require("@angular-architects/module-federation/webpack"); const Path = require("path"); const sharedMappings = new SharedMappings(); sharedMappings.register( Path.join(__dirname, 'tsconfig.json'), [] ) module.exports = { output: { uniqueName: "astrPortFolioMasterWebApp", publicPath: "auto", scriptType: "text/javascript", }, optimization: { runtimeChunk: false }, resolve: { alias: { ...sharedMappings.getAliases(), } }, experiments: { outputModule: true }, plugins: [ new ModuleFederationPlugin({ // For remotes (please Add this 5 Line) name: "astrPortFolioMasterWebApp", filename: "remoteEntry.js", exposes: { './astrPortFolioMasterWebAppModule': './src/app/layout/layout.module.ts', }, shared: { "@angular/core": { singleton: true, strictVersion: true, eager: true }, "@angular/common/": { singleton: true, strictVersion: true, eager: true }, "@angular/router": { singleton: true, strictVersion: true, eager: true }, } }), sharedMappings.getPlugin() ] }; // webpack.config.js--MFE / REMOTE APP - END // MFE - Remote - Route import { Routes } from '@angular/router'; import { MsalGuard } from '@azure/msal-angular'; import { UserNotAllowedComponent } from './layout/user-not-allowed/user-not-allowed.component'; import { ServerErrorComponent } from './layout/server-error/server-error.component'; export const routes: Routes = [ // { // path: '', // pathMatch: 'full', // redirectTo: 'portfolio' // }, { path: 'portfolio', loadChildren: () => import('./layout/layout.module').then((m) => m.MainLayoutModule), canActivate: [MsalGuard] }, { path: 'usernotallowed', component: UserNotAllowedComponent, }, { path: '**', component: ServerErrorComponent, }, ]; // MFE - Remote - Route - END 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)