Why shared library is duplicated in Angular Webpack-5 Module Federation project?

Viewed 1085

I'm trying to implement Webpack-5 module federation to existing large real world app. I'm trying to demonstrate plugins like in angular-plugin-architecture-with-module-federation. I added SharedService to shared-library to simulate communication between the app and plugins in the linked example application above. There's only 1 instance and everything works in the example without a problem.

However in my existing app this doesn't work because there's 2 instances of the service. 1st instance is created in the app and 2nd instance is created when plugin is loaded into it. I verify this by writing in console in constructor and there's 2 lines. Moreover this can be seen by adding breakpoint to source. After the plugin is loaded there's 2 source files for shared.service.ts in the broser's Developer tools->Sources:

enter image description here

The app uses the first source file in the screen capture above. The plugin uses the file from dist. How to configure so that both use same instance of library and thus same service? Below is some more information:

projects/plugins/webpack.config.js

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  output: {
    publicPath: 'http://localhost:4201/',
    uniqueName: 'plugins'
  },
  optimization: {
    // fix a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
      name: 'plugins',
      library: { type: 'var', name: 'plugins' },
      filename: 'remoteEntry.js',
      exposes: {
        './Plugin1': './projects/plugins/src/app/plugin1/plugin1.component.ts',
        './PropertyPlugin': './projects/plugins/src/app/property-plugin/property-plugin.component.ts',
        './Plugin2': './projects/plugins/src/app/plugin2/plugin2.component.ts'
      },
      shared: {
        '@angular/core': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/common': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/forms': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/router': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        rxjs: {
          singleton: true,
          eager: true,
          requiredVersion: "6.5.5",
        },
        shared: {
          singleton: true,
          eager: true,
          requiredVersion: '0.0.1',
          import: 'dist/shared'
        }
      }
    })
  ]
};

src/webpack.config.js

const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');

module.exports = {
  output: {
    publicPath: 'http://localhost:4200/',
    uniqueName: 'app'
  },
  optimization: {
    // fix a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        '@angular/core': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/common': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/forms': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        '@angular/router': {
          singleton: true,
          eager: true,
          requiredVersion: '11.0.0',
        },
        rxjs: {
          singleton: true,
          eager: true,
          requiredVersion: "6.5.5",
        },
        shared: {
          singleton: true,
          eager: true,
          requiredVersion: '0.0.1',
          import: 'dist/shared'
        }
      }
    })
  ]
};

The workspace looks like the one in the example workspace:

- projects
  - shared
    - src 
      - lib
        ...
    - package.json
      ...   
      
  - plugins
    - src
      - app
        ... plugin app is here
    - webpack.config.js
- src
  - app
  
  ... the main app is here
  
  -webpack.config.js          
-angular.json
-package.json

With the exception that I had to copy package.json to projects/plugins because of another issue. I'm totally stuck with this and been trying everything to make it work without success.

0 Answers
Related