1

I've been able to create a monorepo project with several micro frontends without any issues, but I'm struggling to add a micro frontend from a different repo.

Shell:

webpack.config.js

 new ModuleFederationPlugin({
      library: { type: "module" },
        
      remotes: {
          "mfe1": "mfe1@http://localhost:3000/remoteEntry.js", //mfe from same repo as shell
          "mfe2": "mfe2@http://localhost:2000/remoteEntry.js", //mfe from same repo as shell
          "mfe-repo": "mfe-repo@http://localhost:4200/remoteEntry.js", //mfe from different repo as shell
      },

sidebar.component.html

<a class="" routerLink="/dandylion/dandylion-overview" routerLinkActive="linkactive" routerLinkActiveOptions="{ exact: false }">
 <span>Dandylion</span>
    </a>
    <a class="home" routerLink="/snafu/snafu-overview" routerLinkActive="linkactive" routerLinkActiveOptions="{ exact: false }">
      <span>Snafu</span>
    </a>
 <a routerLink="/mfe-repo" routerLinkActive="linkactive" routerLinkActiveOptions="{ exact: false }">
      <span>MFE Repo</span>
    </a> 

app.routes.ts

 {
      path: 'dandylion',
      loadChildren: () => loadRemoteModule({
          type: 'module',
          remoteEntry: 'http://localhost:3000/remoteEntry.js',
          exposedModule: './Module'
        })
        .then(m => m.DandylionModule) 
    },
    {
      path: 'snafu',
      loadChildren: () => loadRemoteModule({
          type: 'module',
          remoteEntry: 'http://localhost:2000/remoteEntry.js',
          exposedModule: './Module'
        })
        .then(m => m.SnafuModule) 
    },
 {
      path: 'mfe-repo',
      loadChildren: () => loadRemoteModule({
          type: 'module',
          remoteEntry: 'http://localhost:4200/remoteEntry.js',
          exposedModule: './Module'
        })
        .then(m => m.AppModule) 
    },

MFE Repo:

webpack.config.js

module.exports = {
  output: {
    uniqueName: "mfe-repo",
    publicPath: "http://localhost:4200/"
  },
  optimization: {
    runtimeChunk: false
  },   
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  experiments: {
    outputModule: true
  },
  plugins: [
    new ModuleFederationPlugin({
        library: { type: "module" },
        name: "mfe-repo",
        filename: "remoteEntry.js",
        exposes: {
            './Module': './src/app/app.module.ts',
        },        
    }),
  ],
};

app.routes.ts

import { Routes } from '@angular/router';
import { AppComponent } from './app.component';

export const APP_ROUTES: Routes = [
    { path: 'mfe-repo', component: AppComponent, pathMatch: 'full'},
];

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { APP_ROUTES } from './app.routes';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(APP_ROUTES),

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

I'm stuck at this for the last 2 days, so if anyone can give a outside check, it would be greatly appreciated. Thanks in advance! Happy coding

4
  • I am also stuck with the above scenario, trying to add module federation to a multi repo angular code base and its not working..is there any luck in your side ? Commented May 23, 2022 at 15:07
  • 1
    answered @Prats :) hope it helps! Commented May 25, 2022 at 9:29
  • LuisPLSP, @Prats, when you guys say it is not working, what is not working? How does it manifest itself? Commented Jan 21, 2024 at 11:10
  • I have added module federation to multi repo approach. Unfortunately I am stuck on how to share the state between these separate repos (shell, mfe1, mfe2). 1. Not planned to migrate to Nx Monorepo approach 2. Not planned to publish a NPM package to sharing module Any help or suggestion is appreciated. Commented Feb 6, 2024 at 19:54

2 Answers 2

3

We'll, as usual, the problem was a simple code change on the remote/mfe:

Instead of defining the RouterModule as 'forRoot', the correct way to set it was 'forChild'. As easy as that!

MFE Repo:

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { APP_ROUTES } from './app.routes';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forChild(APP_ROUTES), // fix is here

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Sign up to request clarification or add additional context in comments.

3 Comments

Do you have reference available for above changes ?
For others reference github.com/Hulk914/moduleFederation project works fine for multi repo using angular-architects module federation
The answer you gave looks strange. I'm facing the same issue and will try what you gave. But if it works how can you explain it works with forRoot in monorepo?
0

For me works like that: microfrontend1: create new module not access app module

webpack.config -> from microfrontend1 module.exports -> exposes

'./Module': './projects/mfe1/src/app/flights/flights.module.ts'

mf.manifest.json you should you have something like that

"frame":"http://localhost:4201/remoteEntry.js"

Shell routing you must have

{
path: 'frame',
loadChildren: () =>
  loadRemoteModule({
    remoteName: 'frame',
    type:"manifest",
    exposedModule: './Module',
  })
    .then((m) => m.FlightsModule), !=> m.AppModule
},

I how to help this answer. :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.