module-federation / module-federation-examples

Implementation examples of module federation , by the creators of module federation
https://module-federation.io/
MIT License
5.56k stars 1.74k forks source link

[solved] How to expose multiple modules from same remote. #717

Closed ronaldohoch closed 3 years ago

ronaldohoch commented 3 years ago

Hello! Thank you a lot for this!

So... I'm using the angular11-microfrontends to test somethings, and, i'm trying to expose two modules from same micro front-ends, but, can't made it work :s, I tryed this:

module.exports = {
    output: {
      uniqueName: "mdmf-profile"
    },
    optimization: {
      // Only needed to bypass a temporary bug
      runtimeChunk: false
    },
    plugins: [
      new ModuleFederationPlugin({
        name: "profile",
        library: { type: "var", name: "profile" },
        filename: "remoteEntry.js",
        exposes: {
          ProfileModule: "./projects/mdmf-profile/src/app/profile/profile.module.ts",
          SignupModule: "./projects/mdmf-profile/src/app/signup/signup.module.ts"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },

          ...sharedMappings.getDescriptors()
        }
      })
      sharedMappings.getPlugin(),
    ],
  };

This

module.exports = {
    output: {
      uniqueName: "mdmf-profile"
    },
    optimization: {
      // Only needed to bypass a temporary bug
      runtimeChunk: false
    },
    plugins: [
      new ModuleFederationPlugin({
        name: "profile",
        library: { type: "var", name: "profile" },
        filename: "remoteEntry.js",
        exposes: {
          ProfileModule: "./projects/mdmf-profile/src/app/profile/profile.module.ts"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },
          ...sharedMappings.getDescriptors()
        }
      }),
      new ModuleFederationPlugin({
        name: "signup",
        library: { type: "var", name: "signup" },
        filename: "remoteEntry.js",
        exposes: {
          SignupModule: "./projects/mdmf-profile/src/app/signup/signup.module.ts"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },
          ...sharedMappings.getDescriptors()
        }
      }),
      sharedMappings.getPlugin(),
    ],
  };

and this

module.exports = {
    output: {
      uniqueName: "mdmf-profile"
    },
    optimization: {
      // Only needed to bypass a temporary bug
      runtimeChunk: false
    },
    plugins: [
      new ModuleFederationPlugin([{
        name: "profile",
        library: { type: "var", name: "profile" },
        filename: "remoteEntry.js",
        exposes: {
          ProfileModule: "./projects/mdmf-profile/src/app/profile/profile.module.ts"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },
          ...sharedMappings.getDescriptors()
        }
      },
      {
        name: "signup",
        library: { type: "var", name: "signup" },
        filename: "remoteEntry.js",
        exposes: {
          SignupModule: "./projects/mdmf-profile/src/app/signup/signup.module.ts"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },

          ...sharedMappings.getDescriptors()
        }
      }]),
      sharedMappings.getPlugin(),
    ],
  };

No one worked '-' Actually, I don't know even if it's possible.

The host webpack.config: https://github.com/module-federation/module-federation-examples/blob/master/angular11-microfrontends/projects/mdmf-shell/webpack.config.js

Can you help?

daskyrk commented 3 years ago

@ronaldohoch what's the error you got? I create multiple ModuleFederationPlugin instances with multiple exposes, it worked. Maybe this demo react-module-federation can help you :)

ronaldohoch commented 3 years ago

This error: image

In this line: image

Throw when i access the SignupModule

@daskyrk Are you using Angular? Can you provide some code?

ronaldohoch commented 3 years ago

Never mind! Solved my problem...

In the example i've tried, the Angular11-microfrontends, there is a service file that initialize the remotes (Don't know why) https://github.com/module-federation/module-federation-examples/blob/master/angular11-microfrontends/projects/mdmf-shell/src/app/microfrontends/microfrontend.service.ts

The specific part:

  loadConfig(): Microfrontend[] {
    return [
      {
        // For Loading
        remoteEntry: "http://localhost:4201/remoteEntry.js",
        remoteName: "profile",
        exposedModule: "ProfileModule",

        // For Routing, enabling us to ngFor over the microfrontends and dynamically create links for the routes
        displayName: "Profile",
        routePath: "profile",
        ngModuleName: "ProfileModule",
      },
    ];
  }

My error was copy the "profile" object and change the remoteName, but the remote name keeps equals to profile, because the module i exports was in profile.

So, the final was:

  loadConfig(): Microfrontend[] {
    return [
      {
        // For Loading
        remoteEntry: `${environment.remoteEntry.profile}/remoteEntry.js`,
        remoteName: "profile",
        exposedModule: "ProfileModule",

        // For Routing, enabling us to ngFor over the microfrontends and dynamically create links for the routes
        displayName: "Profile",
        routePath: "profile",
        ngModuleName: "ProfileModule",
      },
      {
        // For Loading
        remoteEntry: `${environment.remoteEntry.profile}/remoteEntry.js`,
        remoteName: "profile",
        exposedModule: "SignupModule",

        // For Routing, enabling us to ngFor over the microfrontends and dynamically create links for the routes
        displayName: "Signup",
        routePath: "signup",
        ngModuleName: "SignupModule",
      },
      {
        // For Loading
        remoteEntry: `${environment.remoteEntry.list}/remoteEntry.js`,
        remoteName: "list",
        exposedModule: "ListModule",

        // For Routing, enabling us to ngFor over the microfrontends and dynamically create links for the routes
        displayName: "List",
        routePath: "list",
        ngModuleName: "ListModule",
      },
    ];
  }
sedeeman commented 8 months ago

@ronaldohoch Hi Can you please share the working source link, Seems like the link you have shared is not available right now.

https://github.com/module-federation/module-federation-examples/blob/master/angular11-microfrontends/projects/mdmf-shell/src/app/microfrontends/microfrontend.service.ts

Screenshot 2024-01-30 at 9 14 15 PM
ronaldohoch commented 8 months ago

Hi @sedeeman, they changed the folder name, maybe is this file: https://github.com/module-federation/module-federation-examples/blob/master/angular11-microfrontends-ngxs/projects/mdmf-shell/src/app/microfrontends/microfrontend.service.ts

Or this:

https://github.com/module-federation/module-federation-examples/blob/master/angular11-microfrontends-ngrx/projects/mdmf-shell/src/app/microfrontends/microfrontend.service.ts