Giter VIP home page Giter VIP logo

module-federation-plugin's People

Contributors

alvaroramirezcastillo avatar billy-briggs-dev avatar coly010 avatar eric-horodyski avatar florianrappl avatar ftischler avatar gregonnet avatar harikatakam avatar jigfox avatar jogelin avatar loaderb0t avatar manfredsteyer avatar marco-gallinari avatar mikezks avatar slawekkolodziej avatar wszydlak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

module-federation-plugin's Issues

support for angular universal

Is it possible to add angular universal support? I would not mind helping, if someone with more ModuleFederation experience would support me. I have some experience with angular universal but almost no experience with ModuleFederation.

The Angular Webpack loader requires the AngularWebpackPlugin.

Hello!

I have 2 questions:

After read the section: Sharing Libs of a Monorepo, i put my lib in the webpack configuration file, see:

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.base.json'),[
    "@dinamize/ui"
  ]);

module.exports = {
  output: {
    uniqueName: "appShell"
  },
  optimization: {
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
        remotes: {
          "emktConfig": "emktConfig@http://localhost:4201/remoteEntry.js"
        },
        shared: {
          "@angular/core": { singleton: true, strictVersion: true }, 
          "@angular/common": { singleton: true, strictVersion: true }, 
          "@angular/router": { singleton: true, strictVersion: true },
          "rxjs":{singleton:true, strictVersion: true},
          "rxjs/operators":{singleton:true, strictVersion: true},
          "rxjs/Observable":{singleton:true, strictVersion: true},
          ...sharedMappings.getDescriptors()
        }        
    }),
    sharedMappings.getPlugin(),
  ],
};

This throw me this error:

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
./libs/ui/src/lib/web/style/theme.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
    at processResult (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:576:19)
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:669:5
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:399:11
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:251:18
    at context.callback (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:9)
The complete error log:
PS C:\Users\ronal\Documents\projetos\dinamize\MFE> ng serve app-shell
Your global Angular CLI version (11.2.8) is greater than your local version (11.0.7). The local Angular CLI version is used.

To disable this warning use "ng config -g cli.warnings.versionMismatch false".

> nx run app-shell:serve
⠋ Generating browser application bundles (phase: building)...(node:8140) [DEP_WEBPACK_CHUNK_INTEGRATE] DeprecationWarning: Chunk.integrate: Use new ChunkGraph API
(Use `node --trace-deprecation ...` to show where the warning was created)
⠧ Generating browser application bundles (phase: sealing)...
Initial Chunk Files                                                                                     | Names     |    Size
main.js                                                                                                 | main      | 0 bytes
polyfills.js                                                                                            | polyfills | 0 bytes
styles.js                                                                                               | styles    | 0 bytes

Lazy Chunk Files                                                                                        | Names     |    Size
apps_app-shell_src_bootstrap_ts.js                                                                      | -         | 0 bytes
default-libs_ui_src_index_ts.js                                                                         | -         | 0 bytes
default-node_modules_angular_common_fesm2015_common_js.js                                               | -         | 0 bytes
default-node_modules_rxjs__esm2015_internal_AsyncSubject_js-node_modules_rxjs__esm2015_intern-0da67e.js | -         | 0 bytes
node_modules_angular_core_fesm2015_core_js.js                                                           | -         | 0 bytes
node_modules_angular_router_fesm2015_router_js.js                                                       | -         | 0 bytes
node_modules_rxjs__esm2015_index_js.js                                                                  | -         | 0 bytes
node_modules_rxjs__esm2015_operators_index_js.js                                                        | -         | 0 bytes

4 unchanged chunks

Build at: 2021-04-14T16:45:11.970Z - Hash: 89d2f6e83e048eb513e9 - Time: 11698ms

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./apps/app-shell/src/styles.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
    at processResult (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:576:19)
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:669:5
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:399:11
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:251:18
    at context.callback (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:9)

./libs/ui/src/lib/web/style/theme.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
    at processResult (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:576:19)
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:669:5
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:399:11
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:251:18
    at context.callback (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:9)



** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **

✔ Browser application bundle generation complete.
(node:8140) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET_INDEXER] DeprecationWarning: chunk.files was changed from Array to Set (indexing Array is deprecated)
⠸ Generating browser application bundles (phase: sealing)...
15 unchanged chunks

Build at: 2021-04-14T16:45:14.827Z - Hash: 89d2f6e83e048eb513e9 - Time: 2119ms

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./libs/ui/src/index.ts - Error: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)

./apps/app-shell/src/styles.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
    at processResult (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:576:19)
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:669:5
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:399:11
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:251:18
    at context.callback (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:9)

./libs/ui/src/lib/web/style/theme.scss - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: The Angular Webpack loader requires the AngularWebpackPlugin.
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:18)
    at processResult (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:576:19)
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\webpack\lib\NormalModule.js:669:5
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:399:11
    at C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:251:18
    at context.callback (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
    at Object.angularWebpackLoader (C:\Users\ronal\Documents\projetos\dinamize\MFE\node_modules\@ngtools\webpack\src\ivy\loader.js:28:9)


✔ Browser application bundle generation complete.

What is the best way to change the remote url to test and production url

remotes: {
  "emktConfig": "emktConfig@http://localhost:4201/remoteEntry.js"
}

HMR is not working

When enabling HMR and serving the app with ng s --hmr, application will not be served and it hangs.
image

Reproduction :
1- Create an Angular project.
2- Add Module Federation to the app.
3- Serve the app with --hmr argument.
4- As you can see, application will not start.

Angular : 11.0.5
ngx-build-plus 10.1.1
@angular-architects/module-federation 1.2.2

Bug with styles/css

Hello, you mention in your documentation the bug in the experimental CLI/webpack5 which does not allow bundling styles in the federated modules. Is there an ETA on when this will be resolved? This is a pretty big hurdle for any enterprise solution.

Error when load remote. Cannot read property 'init' of undefined

I've followed some tutorials and all fall in the same issue.:
The remoteName doesn't exist in window, so, it doesn't load and throw me an error, see bellow:

image

image

image

Files:

//app.module
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { RouterModule } from '@angular/router';
import { loadRemoteModule } from '@angular-architects/module-federation';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      {
        path: 'domains',
        loadChildren: () =>
          loadRemoteModule({
            remoteEntry: 'http://localhost:4201/remoteEntry.js',
            remoteName: 'emkt-config',
            exposedModule: './Domains',
          }).then((m) => m.DomainsModule),
      },
    ], { initialNavigation: 'enabled' }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
//shell's webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.base.json'),[]);

module.exports = {
  output: {
    uniqueName: "app-shell"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({    
        // For hosts (please adjust)
        remotes: {
          "emkt-config": "emkt-config@http://localhost:4200/remoteEntry.js",
        },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true }, 
          "@angular/common": { singleton: true, strictVersion: true }, 
          "@angular/router": { singleton: true, strictVersion: true },

          ...sharedMappings.getDescriptors()
        }
        
    }),
    sharedMappings.getPlugin(),
  ],
};
// emkt-config's webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.base.json'),
  [
    // "@dinamize-nx-workspace/ui"
  ]
);

module.exports = {
  output: {
    uniqueName: "emkt-config"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
        name: "emkt-config",
        filename: "remoteEntry.js",
        exposes: {
          './Domains': './apps/emkt-config/src/app/domains/domains.module.ts',
          './Content': './apps/emkt-config/src/app/content/content.module.ts',
          './Send': './apps/emkt-config/src/app/send/send.module.ts',
          './ConfigForms': './apps/emkt-config/src/app/config-forms/config-forms.module.ts',
          './Integrations': './apps/emkt-config/src/app/integrations/integrations.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(),
  ],
};

add License for tools and runtime npm packages

Hi,

My Company requires all our packages to have a License on NPM otherwise our proxy quarantines them.

Is it possible to add a License for:

@angular-architects/module-federation-runtime

and

@angular-architects/module-federation-tools

Many thanks :)

Invalid configuration object

An unhandled exception occurred: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.

  • configuration.output has an unknown property 'uniqueName'. These properties are valid:
    object { auxiliaryComment?, chunkCallbackName?, chunkFilename?, chunkLoadTimeout?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolLineToLine?, devtoolModuleFilenameTemplate?, devtoolNamespace?, filename?, futureEmitAssets?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateFunction?, hotUpdateMainFilename?, jsonpFunction?, jsonpScriptType?, library?, libraryExport?, libraryTarget?, path?, pathinfo?, publicPath?, sourceMapFilename?, sourcePrefix?, strictModuleExceptionHandling?, umdNamedDefine?, webassemblyModuleFilename? }
    -> Options affecting the output of the compilation. output options tell webpack how to write the compiled files to disk.
    See "C:\Users\Hugo Barboza\AppData\Local\Temp\ng-F3Qn1m\angular-errors.log" for further details.

Javascript error when loading the remote entry upfront

Hello,
I am trying to improve the library sharing between shell and microfronts using the feature to load the remote entry upfront:

https://www.angulararchitects.io/aktuelles/dynamic-module-federation-with-angular/ -> Improvement for Dynamic Module Federation

I am attaching screenshots of the code and the error:

zone-evergreen.js:1063 Unhandled Promise rejection: Cannot read property 'init' of undefined ; Zone: ; Task: HTMLScriptElement.addEventListener:load ; Value: TypeError: Cannot read property 'init' of undefined
at dynamic-federation.js:28
at Generator.next ()
at tslib.es6.js:74
at new ZoneAwarePromise (zone-evergreen.js:1387)
at Module.__awaiter (tslib.es6.js:70)
at initRemote (dynamic-federation.js:17)
at HTMLScriptElement.script.onload [as __zone_symbol__ON_PROPERTYload] (dynamic-federation.js:44)
at HTMLScriptElement.wrapFn (zone-evergreen.js:763)
at ZoneDelegate.invokeTask (zone-evergreen.js:406)
at Zone.runTask (zone-evergreen.js:178) TypeError: Cannot read property 'init' of undefined
at http://localhost:3000/vendor.js:52:25
at Generator.next ()
at http://localhost:3000/vendor.js:195:71
at new ZoneAwarePromise (http://localhost:3000/polyfills.js:1397:29)
at Module.__awaiter (http://localhost:3000/vendor.js:191:12)
at initRemote (http://localhost:3000/vendor.js:41:20)
at HTMLScriptElement.script.onload [as __zone_symbol__ON_PROPERTYload] (http://localhost:3000/vendor.js:68:13)
at HTMLScriptElement.wrapFn (http://localhost:3000/polyfills.js:773:39)
at ZoneDelegate.invokeTask (http://localhost:3000/polyfills.js:416:31)
at Zone.runTask (http://localhost:3000/polyfills.js:188:47)

Captura de pantalla de 2021-05-07 09-26-49
Captura de pantalla de 2021-05-07 09-35-26

Angular CLI Hangs up while running ng serve

CLI HANGS UP TO 21% WHILE RUNNING NG SERVE OR YARN START

@manfredsteyer I tried using the @angular-architects/module-federation plugin by following the steps mentioned for using this library in a newly created Angular 11 project. However, the execution of the ng serve or yarn start halts up at 21% with the below mentioned message.

Screenshot 2020-10-19 at 3 08 00 PM

Could you please help me out if I am missing something here.

Project Not Working after upgrading to ng 11.1.4 and module federation 1.2.3

I add an old project (PRJ1) which was working. This project is in Angular 11.0.7 and module federation 1.2.2

I create a new project (PRJ2) with the last version of Angular (11.1.4) and module federation 1.2.3.
This project doesn't start and doesn't build.

I have updated PRJ1 to 11.1.4 and have the same problem.
I downgraded PRJ2 to 11.0.7 and it works !!! (i have used the working package.json from PRJ1).

package.json files that is working :
package.working.json.txt

package.json files that is not working :
package.notworking.json.txt

does not work with --minimal setup

if you create your application with the flag "minimal":

ng g app shell --minimal --routing

and try to apply:

ng add @angular-architects/module-federation --project shell --port 5000

you will get an error:

expected node projects/shell/architect/test in angular.json

not sure whether it's a bug or a feature :)

Angular 12 support

The Angular core team announced that Webpack 5 will be the default in Angular 12. The Yarn requirement is a stumbling block as our build system only supports NPM today.

I started playing around with Angular 12 (v12.0.0-rc-0) and the both the MFE and shell build with NPM but at runtime it fails to load the MFE module in the host. I know it's early, but I'm curious. Will the Angular 12 out of the box support for Webpack 5 enable dropping the Yarn requirement?

I also tested upgrading the module-federation-with-angular-dynamic to Angular 12 and I received the same errors as with Angular 12 and NPM.

Any ideas?

load script:41 GET http://localhost:5000/common.js net::ERR_ABORTED 404 (Not Found) __webpack_require__.l @ load script:41 __webpack_require__.f.j @ jsonp chunk loading:43 (anonymous) @ ensure chunk:6 __webpack_require__.e @ ensure chunk:5 ./Module @ container-entry:6 get @ container-entry:13 (anonymous) @ dynamic-federation.js:11 (anonymous) @ tslib.es6.js:76 ZoneAwarePromise @ zone.js:1340 __awaiter @ tslib.es6.js:72 lookupExposedModule @ dynamic-federation.js:9 (anonymous) @ dynamic-federation.js:57 fulfilled @ tslib.es6.js:73 __webpack_modules__.9140.ZoneDelegate.invoke @ zone.js:400 onInvoke @ core.js:28632 __webpack_modules__.9140.ZoneDelegate.invoke @ zone.js:399 __webpack_modules__.9140.Zone.run @ zone.js:160 (anonymous) @ zone.js:1318 __webpack_modules__.9140.ZoneDelegate.invokeTask @ zone.js:434 onInvokeTask @ core.js:28619 __webpack_modules__.9140.ZoneDelegate.invokeTask @ zone.js:433 __webpack_modules__.9140.Zone.runTask @ zone.js:205 drainMicroTaskQueue @ zone.js:620 __webpack_modules__.9140.ZoneTask.invokeTask @ zone.js:520 invokeTask @ zone.js:1656 globalZoneAwareCallback @ zone.js:1682 load (async) customScheduleGlobal @ zone.js:1808 __webpack_modules__.9140.ZoneDelegate.scheduleTask @ zone.js:421 onScheduleTask @ zone.js:311 __webpack_modules__.9140.ZoneDelegate.scheduleTask @ zone.js:414 __webpack_modules__.9140.Zone.scheduleTask @ zone.js:248 __webpack_modules__.9140.Zone.scheduleEventTask @ zone.js:274 (anonymous) @ zone.js:1965 desc.set @ zone.js:864 (anonymous) @ dynamic-federation.js:43 ZoneAwarePromise @ zone.js:1340 loadRemoteEntry @ dynamic-federation.js:34 (anonymous) @ dynamic-federation.js:55 (anonymous) @ tslib.es6.js:76 ZoneAwarePromise @ zone.js:1340 __awaiter @ tslib.es6.js:72 loadRemoteModule @ dynamic-federation.js:53 loadChildren @ menu-utils.ts:10 loadModuleFactory @ router.js:3687 load @ router.js:3661 (anonymous) @ router.js:2798 _tryNext @ mergeMap.js:44 _next @ mergeMap.js:34 next @ Subscriber.js:49 (anonymous) @ subscribeToArray.js:3 _trySubscribe @ Observable.js:42 subscribe @ Observable.js:28 call @ mergeMap.js:19 subscribe @ Observable.js:23 call @ mergeMap.js:19 subscribe @ Observable.js:23 call @ catchError.js:14 subscribe @ Observable.js:23 innerSubscribe @ innerSubscribe.js:67 _innerSub @ mergeMap.js:57 _tryNext @ mergeMap.js:51 _next @ mergeMap.js:34 next @ Subscriber.js:49 (anonymous) @ subscribeToArray.js:3 _trySubscribe @ Observable.js:42 subscribe @ Observable.js:28 call @ mergeMap.js:19 subscribe @ Observable.js:23 call @ filter.js:13 subscribe @ Observable.js:23 call @ take.js:22 subscribe @ Observable.js:23 call @ throwIfEmpty.js:13 subscribe @ Observable.js:23 call @ catchError.js:14 subscribe @ Observable.js:23 call @ map.js:16 subscribe @ Observable.js:23 innerSubscribe @ innerSubscribe.js:67 _innerSub @ mergeMap.js:57 _tryNext @ mergeMap.js:51 _next @ mergeMap.js:34 next @ Subscriber.js:49 (anonymous) @ subscribeToArray.js:3 _trySubscribe @ Observable.js:42 subscribe @ Observable.js:28 call @ mergeMap.js:19 subscribe @ Observable.js:23 call @ scan.js:18 subscribe @ Observable.js:23 call @ takeLast.js:22 subscribe @ Observable.js:23 call @ throwIfEmpty.js:13 subscribe @ Observable.js:23 call @ map.js:16 subscribe @ Observable.js:23 call @ map.js:16 subscribe @ Observable.js:23 call @ catchError.js:14 subscribe @ Observable.js:23 call @ map.js:16 subscribe @ Observable.js:23 innerSubscribe @ innerSubscribe.js:67 _innerSub @ switchMap.js:44 _next @ switchMap.js:34 next @ Subscriber.js:49 notifyNext @ switchMap.js:66 _next @ innerSubscribe.js:10 next @ Subscriber.js:49 (anonymous) @ subscribeToPromise.js:5 __webpack_modules__.9140.ZoneDelegate.invoke @ zone.js:400 onInvoke @ core.js:28632 __webpack_modules__.9140.ZoneDelegate.invoke @ zone.js:399 __webpack_modules__.9140.Zone.run @ zone.js:160 (anonymous) @ zone.js:1318 __webpack_modules__.9140.ZoneDelegate.invokeTask @ zone.js:434 onInvokeTask @ core.js:28619 __webpack_modules__.9140.ZoneDelegate.invokeTask @ zone.js:433 __webpack_modules__.9140.Zone.runTask @ zone.js:205 drainMicroTaskQueue @ zone.js:620 __webpack_modules__.9140.ZoneTask.invokeTask @ zone.js:520 invokeTask @ zone.js:1656 globalZoneAwareCallback @ zone.js:1682 Show 93 more frames core.js:6456 ERROR Error: Uncaught (in promise): ChunkLoadError: Loading chunk common failed. (error: http://localhost:5000/common.js) ChunkLoadError: Loading chunk common failed. (error: http://localhost:5000/common.js) at Object.__webpack_require__.f.j (jsonp chunk loading:27) at ensure chunk:6 at Array.reduce (<anonymous>) at Function.__webpack_require__.e (ensure chunk:5) at Object../Module (container-entry:6) at Object.get (container-entry:13) at dynamic-federation.js:11 at Generator.next (<anonymous>) at tslib.es6.js:76 at new ZoneAwarePromise (zone.js:1340) at resolvePromise (zone.js:1255) at resolvePromise (zone.js:1209) at zone.js:1321 at ZoneDelegate.__webpack_modules__.9140.ZoneDelegate.invokeTask (zone.js:434) at Object.onInvokeTask (core.js:28619) at ZoneDelegate.__webpack_modules__.9140.ZoneDelegate.invokeTask (zone.js:433) at Zone.__webpack_modules__.9140.Zone.runTask (zone.js:205) at drainMicroTaskQueue (zone.js:620) at ZoneTask.__webpack_modules__.9140.ZoneTask.invokeTask [as invoke] (zone.js:520) at invokeTask (zone.js:1656)

cannot resolve @angular-architects/module-federation due to improper main path

I noticed that when installing the package that I was getting issues with actually requiring in the file. I noticed that the package.json main property is: "main": "src\\index.js", when it should be "main": "src/index.js",

If I pull down this project and run yarn build mf, it generates the correct path.

Screen Shot 2021-02-15 at 10 58 20 AM

Here is the error:

➜  ngx-dashboard-widget-sandbox-example git:(feature/mfe) node   
Welcome to Node.js v14.15.3.
Type ".help" for more information.
> require('@angular-architects/module-federation')
Uncaught:
Error: Cannot find module '/Volumes/Development/ngx-dashboard-widget-sandbox-example/node_modules/@angular-architects/module-federation/src\index.js'. Please verify that the package.json has a valid "main" entry
    at tryPackage (internal/modules/cjs/loader.js:303:19)
    at Function.Module._findPath (internal/modules/cjs/loader.js:516:18)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:867:27)
    at Function.Module._load (internal/modules/cjs/loader.js:725:27)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18) {
  code: 'MODULE_NOT_FOUND',
  path: '/Volumes/Development/ngx-dashboard-widget-sandbox-example/node_modules/@angular-architects/module-federation/package.json',
  requestPath: '@angular-architects/module-federation'
}
> 

Changing the above main property value allows for the module to work.

This also looks to have the same issue on the typings property as well.

How to use loadRemoteEntry in IE 11?

I'm loading microfrontends like so:

shell/main.ts:

import { loadRemoteEntry } from '@angular-architects/module-federation';
import { environment } from './environments/environment';

Promise.all([
  loadRemoteEntry(
    `${environment.microfrontends.mfe.entryPoint}`,
    `${environment.microfrontends.mfe.remoteName}`
  ),
])
  .catch((err) => console.error('Error loading remote entries', err))
  .then(() => import('./bootstrap'))
  .catch((err) => console.error(err));

When loading the app in IE 11, an error is caught (and hidden) that says:
"Object doesn't support property or method 'append'"
The error appears to occur in loadRemoteEntry at line 57 in https://github.com/angular-architects/module-federation-plugin/blob/main/packages/mf/src/utils/dynamic-federation.ts

What can I do to make this work in IE11?

Note: According to https://developer.mozilla.org/en-US/docs/Web/API/Element/append IE does not support Element.append. That does explain the error message but it doesn't help me solve this.

Component loading breaks if HttpClient is referenced in component constructor

Hi, I'm using module federation plugin to create a "dynamic composable application".
Everything is working great, until i create a component inside a remote with a reference to HttpClient in constructor.
I use the loadRemoteModule method to load component from remote.
When i load the remote and create the component, i have experienced the "Static injector error" for HttpClient as follows:

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
NullInjectorError: R3InjectorError(AppModule)[HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
...
at NodeInjectorFactory.TestComponent_Factory [as factory] (test.component.ts:8)

i have created a repo to nail the problem:
https://github.com/davidesenatore/MFTest

I have no clue to resolve the problem.
Many thanks!

Davide

HttpClientModule is not injected into the MatIconRegistry of Angular Material

Hello Manfred, thank you for providing this cool plugin :)

Recently, I tried to add Angular Material to your plugin example and I got stuck registering custom icons into the MatIconRegistry. Although the HttpClientModule is imported into the FlightsModule from the mfe1, the MatIconRegistry cannot access the HttpClient.

When I start both the shell and the mfe1 in the browser, then I can see the following error message in the console:

core.js:4610 ERROR Error: Uncaught (in promise): Error: Could not find HttpClient provider for use with Angular Material icons. Please include the HttpClientModule from @angular/common/http in your app imports.

I added the following things to the project (see commit):

  • Angular Material dependency
  • Service class at mfe1 which calls the matIconRegistry to register custom SVG icons
  • The service is injected directly at the flights module like this:
export class FlightsModule {
  constructor(private iconService: IconService) {
    iconService.registerMyIcons();
  }
}

Custom icons can then be used in the template like this (using the angular.svg icon from the assets):

<mat-icon svgIcon="angular"></mat-icon>

The issue here is, that the method registerMyIcons calls the addSvgIcon method which requires the HttpClient to load the custom SVG icons from the assets folder.

The usage of the HttpClient inside mfe1 is generally possible, but does not getting injected into the MatIconRegistry.


Fork of @manfredsteyer's plugin example with the issue can be found here:

https://github.com/PKief/module-federation-plugin-example/

Error importing external angular library

Hi, i am having issues importing an external angular library.

When i try to import it, the build hangs up. i tried to run first the project and then add de import and the terminal shows me this error:

✔ Browser application bundle generation complete.
⠹ Generating browser application bundles (phase: building)...(node:34635) [DEP_WEBPACK_DEPRECATION_ARRAY_TO_SET] DeprecationWarning: Compilation.modules was changed from Array to Set (using Array method 'find' is deprecated)
⠸ Generating browser application bundles (phase: sealing)...

anyone knows what this error is about? thanks!

Unique name with "-"

When in the webpack configuration we define a name with the character "-" like my-app, we have an error.

The variable should be created after a transformation to camelCase

⠦ Generating ES5 bundles for differential loading...An unhandled exception occurred: /home/vagrant/.../remoteEntry.js: Missing semicolon (1:9)

> 1 | var my-app;my-app =
    |          ^
  2 | /******/ (function() { // webpackBootstrap
  3 | /******/  "use strict";
  4 | /******/  var __webpack_modules__ = ({
See "/tmp/ng-J43sR3/angular-errors.log" for further details.

Angular 11 without Yarn

Is it possible to avoid Yarn and only use NPM with Angular 11 and version 12.0.0-rc.1.0.1 if the plugin? The latest tutorial makes it sound like it's possible to choose between NPM or Yarn but the when installing the plugin it uses Yarn and creates a yarn,lock file.

Loding more the one Mfe at the same time.

So I have a typical shell app for hosting mfe. Setup for dynamically loading components (like widgets). Like in the Plugin example. The only difference is I'm not adding them on click event but from the configuration list. The problem occurs when we ngFor the widgets. It happens so fast that the first widget is not yet rendered or loaded . That other widget one from the same Mfe brakes. is it possible to load multiple mfe at the same remoteEntry.js

remote component - consume statically

This is not a issue rather a question. how to consume a component (available at remote) at design time ( without componentFactoryResolver)

exposes: {
"component": ".//src/app/app.component.ts"
}
while importing
import {component} from "mfe@component"
I am getting build error "cannot find module "mfe1@component"

how to consume remotely exposed component at design time

Module is not loaded with ng cli v11.1.1

After upgrading to @angular/cli to version 11.1.1 this module is not loaded due to the backslash presents in package.json for main and typings

"main": "src\\index.js", "schematics": "./collection.json", "builders": "./builders.json", "dependencies": { "@nrwl/workspace": "^10.3.0", "ngx-build-plus": "^10.0.0", "cross-spawn": "^7.0.3", "json5": "^2.1.3" }, "typings": "src\\index.d.ts", "peerDependencies": {} }

Changing to

"main": "src/index.js", "schematics": "./collection.json", "builders": "./builders.json", "dependencies": { "@nrwl/workspace": "^10.3.0", "ngx-build-plus": "^10.0.0", "cross-spawn": "^7.0.3", "json5": "^2.1.3" }, "typings": "src/index.d.ts", "peerDependencies": {} }

makes the module loadable again.
If agree, I can file a pull request for this fix.

NullInjectorError on re-exported modules in shared library

I have a host app A and a remote app B, both use the same custom shared library C. This library C is in the same monorepo managed by Nx. The module of library C re-exports some common modules (i.e. FormsModule)
During runtime when app B initializes a component with a dependency on such a common module it fails with a NullInjectorError.

This is my webpack config of remote app B

const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.json'),
  ['@lib-c/c']);

module.exports = {
  output: {
    uniqueName: "bsp",
    publicPath: "auto"
  },
  optimization: {
    runtimeChunk: false
  },
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  plugins: [
    new ModuleFederationPlugin({

        // For remotes (please adjust)
        name: "bsp",
        filename: "remoteEntry.js",
        exposes: {
          './Module': './apps/bsp/src/app/bsp.module.ts',
        },

      shared: {
        "@angular/core": {singleton: true, strictVersion: true, requiredVersion: ">=12.0.0" },
        "@angular/common": {singleton: true, strictVersion: true, requiredVersion: ">=12.0.0" },
        "@angular/common/http": {singleton: true, strictVersion: true, requiredVersion: ">=12.0.0" },
        "@angular/router": {singleton: true, strictVersion: true, requiredVersion: ">=12.0.0" },
        "@ngx-translate/core": {singleton: true, strictVersion: true},
        "@angular/forms": {singleton: true, strictVersion: true},

        ...sharedMappings.getDescriptors()
      }

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

Shared module is not available for eager consumption

In my container app, I am trying to share a service. However, I get the error "Shared module is not available for eager consumption" even before main.ts starts.

The shared library is a simple Angular library that is in an npm module. I have it configured in my tsconfig.json as

    "paths": {
      "components-lib": [
        "./node_modules/components-lib"
      ],
      "components-lib/*": [
        "./node_modules/components-lib/*"
      ]

and my webpack config:

sharedMappings.register(
  path.join(__dirname, 'tsconfig.json'),
  ['components-lib']);

The service is actually sharing its instance between the apps. However, it is causing other issues such as preventing tailwind styles from loading.

Any thoughts on how to resolve the error? If you would like to see my sample app exhibiting this issue you can have a look at: https://github.com/scottfwalter/mfe

Is it possible to share the NgRx store from the host application to the remotes?

Little background, I am trying to breakup our monolith UI into separate buildable and deployable pieces. Module federation seems like a perfect use case for this.

Problem is, in our current application, there is a shared application state that a lot of the would be micro-frontends rely on. The micro-frontends also have their own piece of the store for their application specific state.

I use StoreModule.forFeature in the remote apps, but get an error NullInjectorError: No provider for ReducerManager! which is provided when you do StoreModule.forRoot, however, I don't necessarily want to define another root store in the remote app. Is it possible to share the store state with all micro-frontends?

Not sharing angular libraries throws Error: inject() must be called from an injection context

I have a child app wired up through the router:

  {
    path: 'hello',
    loadChildren: () =>
      loadRemoteModule({
        remoteEntry: 'http://localhost:4201/remoteEntry.js',
        remoteName: 'mfe1',
        exposedModule: './HelloModule',
      }).then((m) => m.HelloModule),
  },

If the child app does not the angular libraries in its list of shared libraries it throw the error:

ERROR Error: Uncaught (in promise): Error: inject() must be called from an injection context
injectInjectorOnly@http://localhost:4201/default-src_app_hello_hello_module_ts.js:10890:15
ɵɵinject@http://localhost:4201/default-src_app_hello_hello_module_ts.js:10900:61
RouterModule_Factory@http://localhost:4201/default-src_app_hello_hello_module_ts.js:45267:130
hydrate@http://localhost:5000/node_modules_angular_core___ivy_ngcc___fesm2015_core_js.js:11928:35

The child app works fine on its own but not when consumed through loadRemoteModule. If I add the Angular libraries to the shared webpack config in the shared libraries it will work.

Any reason why I can't have the child app load its own version of the Angular libraries?

Thanks, Scott.

ng serve doesn't serve files

Introduction

At first, I wanted to say on a new project generated by ng cli it worked correctly, and building process builds files:

In my project, I tried searching difference in configurations to serve files after ng serve command but I couldn't find any sensible difference between them.

I haven't tried custom-webpack builder, previously, with other configuration it has served the files, but I don't know can I use it with ModuleFederationPlugin

Description

My application should be like a shell application like regular monorepo app, but one exception, in one routing I want to get outside the script and load it as micro frontend, currently, I load script on init app in index.html file.

after execute ng serve I see

> ng serve

√ Browser application bundle generation complete.
(node:14020) [DEP_WEBPACK_CHUNK_MODULES_ITERABLE] DeprecationWarning: Chunk.modulesIterable: Use new ChunkGraph API
(node:14020) [DEP_WEBPACK_CHUNK_ENTRY_MODULE] DeprecationWarning: Chunk.entryModule: Use new ChunkGraph API

as you can see it's lack of listing generated files.

package.json

{
  "name": "iatfi",
  "version": "1.0.0",
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "**/*.{ts,scss,html}": [
      "prettier --write",
      "git add"
    ]
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "start:3200": "ng serve --port=3200",
    "build:watch": "ng build --watch=true",
    "build:develop-local": "ng build --configuration=local",
    "build:develop": "ng build --configuration=develop",
    "build:uat": "ng build --configuration=uat",
    "build:production": "ng build --configuration=production",
    "build:production-maps": "ng build --configuration=production --sourceMap=true",
    "build:analize": "ng build --configuration=production --statsJson=true",
    "test": "ng test",
    "test:coverage": "ng test --coverage",
    "test:watch": "ng test --watch",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "prettier": "prettier --write **/*.html **/*.scss **/*.ts",
    "prettier-watch": "onchange **/*.ts **/*.scss **/*.html -- prettier --write {{changed}}",
    "analize": "webpack-bundle-analyzer ../main/resources/static/dist/stats-es5.json",
    "analize2015": "webpack-bundle-analyzer ../main/resources/static/dist/stats-es2015.json",
    "postinstall": "ngcc"
  },
  "private": true,
  "resolutions": {
    "webpack": "^5.0.0"
  },
  "dependencies": {
    "@angular-architects/module-federation": "^1.2.2",
    "@angular-builders/custom-webpack": "^10.0.0",
    "@angular-builders/jest": "^10.0.0",
    "@angular-devkit/build-angular": "~0.1100.4",
    "@angular/animations": "^11.0.4",
    "@angular/cli": "^11.0.4",
    "@angular/common": "^11.0.4",
    "@angular/compiler": "^11.0.4",
    "@angular/compiler-cli": "^11.0.4",
    "@angular/core": "^11.0.4",
    "@angular/forms": "^11.0.4",
    "@angular/localize": "^11.0.4",
    "@angular/platform-browser": "^11.0.4",
    "@angular/platform-browser-dynamic": "^11.0.4",
    "@angular/router": "^11.0.4",
    "@ng-bootstrap/ng-bootstrap": "^7.0.0",
    "@ngx-translate/core": "^13.0.0",
    "@ngx-translate/http-loader": "^6.0.0",
    "@types/jest": "^24.9.1",
    "@types/jquery": "^3.3.31",
    "@types/node": "^12.11.1",
    "@webcomponents/webcomponentsjs": "^2.4.3",
    "angular2-multiselect-dropdown": "^4.6.3",
    "bootstrap": "^4.5.2",
    "core-js": "^3.6.4",
    "d3": "^5.15.0",
    "jest": "^26.2.2",
    "jest-preset-angular": "^8.2.1",
    "jquery": "^3.5.1",
    "ngx-cookie-service": "^2.3.0",
    "prettier": "^1.19.1",
    "rxjs": "^6.6.3",
    "tslib": "^2.0.0",
    "tslint-angular": "^3.0.2",
    "typescript": "~4.0.5",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-builders/dev-server": "^7.3.1",
    "@angular-devkit/build-angular": "~0.1100.4",
    "@angular/language-service": "^11.0.4",
    "@types/d3": "^5.7.2",
    "codelyzer": "^6.0.0",
    "husky": "^4.3.6",
    "lint-staged": "^10.5.3",
    "ts-node": "~7.0.0",
    "tslint": "~6.1.0",
    "webpack-bundle-analyzer": "^3.6.0"
  }
}

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "iatfi": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "iatfi",
      "architect": {
        "build": {
          "builder": "ngx-build-plus:browser",
          "options": {
            "outputPath": "../main/resources/static/dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.css",
              "node_modules/angular2-multiselect-dropdown/themes/default.theme.css",
              "src/from-thymelife-styles.scss",
              "src/icons/icons.scss",
              "src/styles.scss"
            ],
            "scripts": [],
            "extraWebpackConfig": "webpack.config.js"
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "media",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": true,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ],
              "extraWebpackConfig": "webpack.prod.config.js"
            },
            "local": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.local.ts"
                }
              ],
              "deployUrl": "/iatfi-app/dist/",
              "optimization": true,
              "outputHashing": "media",
              "sourceMap": true,
              "namedChunks": true,
              "buildOptimizer": false
            },
            "develop": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ],
              "vendorChunk": true,
              "deployUrl": "/iatfi-app/dist/",
              "baseHref": "/iatfi-app",
              "optimization": true,
              "outputHashing": "media",
              "sourceMap": true,
              "namedChunks": true,
              "aot": true,
              "buildOptimizer": false
            },
            "uat": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.uat.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "media",
              "sourceMap": false,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": true,
              "buildOptimizer": true,
              "deployUrl": "/iatfi-app/dist/",
              "baseHref": "/iatfi-app",
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "ngx-build-plus:dev-server",
          "options": {
            "browserTarget": "iatfi:build",
            "extraWebpackConfig": "webpack.config.js",
            "port": 4200
          },
          "configurations": {
            "production": {
              "browserTarget": "iatfi:build:production",
              "extraWebpackConfig": "webpack.prod.config.js"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "iatfi:build"
          }
        },
        "test": {
          "builder": "@angular-builders/jest:run",
          "options": {
            "main": "src/jestSetup.ts",
            "tsConfig": "tsconfig.spec.json"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "iatfi:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "iatfi:serve:production"
            }
          }
        }
      }
    }
  },
  "defaultProject": "iatfi",
  "cli": {
    "analytics": false,
    "packageManager": "yarn"
  }
}

files:
bootstrap.ts, main.ts, webpack.config.js and webpack.prod.config.js are untouched after schematics changed after command ng add @angular-architects/module-federation

No provider for HttpClient

Hello, I am encountering an error when using the HttpClient in a federated module. Here is the error:

ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(QaRulesModule)[QaRulesApiService -> QaRulesApiService -> QaRulesApiService -> HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
NullInjectorError: R3InjectorError(QaRulesModule)[QaRulesApiService -> QaRulesApiService -> QaRulesApiService -> HttpClient -> HttpClient -> HttpClient]:
NullInjectorError: No provider for HttpClient!
at NullInjector.get (core.js:11027)
at R3Injector.get (core.js:11194)
at R3Injector.get (core.js:11194)
at R3Injector.get (core.js:11194)
at injectInjectorOnly (core.js:4706)
at Module.ɵɵinject (core.js:4710)
at Object.QaRulesApiService_Factory [as factory] (qa-rules-api.service.ts:9)
at R3Injector.hydrate (core.js:11363)
at R3Injector.get (core.js:11183)
at NgModuleRef$1.get (core.js:25238)
at resolvePromise (zone-evergreen.js:1213)
at resolvePromise (zone-evergreen.js:1167)
at zone-evergreen.js:1279
at ZoneDelegate.invokeTask (zone-evergreen.js:406)
at Object.onInvokeTask (core.js:28500)
at ZoneDelegate.invokeTask (zone-evergreen.js:405)
at Zone.runTask (zone-evergreen.js:178)
at drainMicroTaskQueue (zone-evergreen.js:582)

I am not writing my code because the usage is pretty basic and common, just injecting HttpClient in a constructor in the federated module I get this error.
The shell imports HttpClientModule in its app.module, and the federated module has it imported too.

UPDATE
I fixed it by doing this:

Captura de pantalla de 2021-05-07 13-09-49

@manfredsteyer, is this a correct use?

Error when consuming shared library on cli monorepo

When using shared library on cli monorepo and register the shared library name with SharedMappings register method.

when serving the app we get the follow warning -
"[DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future"

when we made changes in one of the micro frontend application and saved, we get the follow error -
"Conflict: Multiple assets emit different content to the same filename"

the error prevent from the app to re compile the application and the changes doesn't reflected.

used with version 1.2.0 and angular version 11 cli.

Dynamic loading remote from web-component

Hi,

I'm currently work arround module federation and a microfrontend architecture.

I meet a problem when i want to load remote dynamically. In fact, your plugin (module-federation-plugin) allow us to load module but not web-component like when you expoded the "bootstrap.ts" file. When i try to retrieve the "./web-components" element from the container like this :

const container = window[remoteName];
const factory = await container.get(exposedElement);
const Element = factory();
console.log(Element)

It is empty...

So you have an idea to solve this problem ?

Thanks

Micro Frontend - A platform with a different configuration has been created. Please destroy it first

I am trying to build a POC for Micro Frontend using Angular and Webpack Module Federation. In this, I have created a shell app and another mfe1 app and rendering that mfe1 on a specific route hit and it is working as expected and rendering the app. Now, I am trying to create another app called mfe2 and render it. In this mfe2, I am creating a web component using Angular elements and rendering that in the shell app. When I do that, I am facing the following issue

Error: A platform with a different configuration has been created. Please destroy it first.

image

when the following code is executing

import('mfe2/web-component')
    .then(_ => console.debug(`element loaded!`))
    .catch(err => console.error(`error loading `, err));

I don't understand where the exact issue is. I am adding the required code below.

MFE2:

app.module.ts

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: []
})
export class AppModule {
  constructor(private injector: Injector) {}

  ngDoBootstrap() {
    const ce = createCustomElement(AppComponent, {injector: this.injector});
    customElements.define('mfe2-elem', ce);
  }

}

webpack.config.js

module.exports = {
  output: {
    uniqueName: "mfe2",
    publicPath: "auto"
  },
  optimization: {
    runtimeChunk: false
  },   
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  plugins: [
    new ModuleFederationPlugin({
      
        // For remotes (please adjust)
        name: "mfe2",
        filename: "remoteEntry.js",
        exposes: {
          './web-component': './src/bootstrap.ts',
        },        
        
        // For hosts (please adjust)
        // remotes: {
        //     "mfe1": "mfe1@http://localhost:3000/remoteEntry.js",

        // },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true }, 
          "@angular/common": { singleton: true, strictVersion: true }, 
          "@angular/common/http": { singleton: true, strictVersion: true }, 
          "@angular/router": { singleton: true, strictVersion: true },

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

SHELL:

rendering it in a component:

@Component({
  selector: 'app-mfe2element',
  templateUrl: './mfe2element.component.html',
  styleUrls: ['./mfe2element.component.scss']
})
export class Mfe2elementComponent implements AfterContentInit {

  @ViewChild('vc', { read: ElementRef, static: true })
  vc!: ElementRef;

  constructor() { }

  ngAfterContentInit(): void {
    import('mfe2/web-component')
    .then(_ => console.debug(`element loaded!`))
    .catch(err => console.error(`error loading `, err));

    // await import('mfe1/web-components');
    // const element = document.createElement('mfe1-element');
    // document.body.appendChild(element);

    const element = document.createElement('mfe2-elem');
    this.vc.nativeElement.appendChild(element);

  }

}

webpack.config.js

module.exports = {
  output: {
    uniqueName: "shell"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
        // For remotes (please adjust)
        // name: "shell",
        // filename: "remoteEntry.js",
        // exposes: {
        //     './Component': './/src/app/app.component.ts',
        // },        
        
        // For hosts (please adjust)
        remotes: {
            "mfe1": "mfe1@http://localhost:3000/remoteEntry.js",
            "mfe2": "mfe2@http://localhost:4000/remoteEntry.js",
        },

        shared: {
          "@angular/core": { singleton: true, strictVersion: false }, 
          "@angular/common": { singleton: true, strictVersion: false }, 
          "@angular/router": { singleton: true, strictVersion: false },

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

Please help me solve this issue.

Thanks...

Generating Browser Application Bundles

Testing the plugin and trying to build a mircrofrontend. ng serve seems to be getting hung up at:

Generating browser application bundles (phase: building)...

Verbose flag doesn't seem to give any more information on what it's doing.

Any ideas?

Angular 12 + ChunkLoadError

In my remote I have:

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, 'tsconfig.json'),
  [/* mapped paths to share */]);

module.exports = {
  output: {
    uniqueName: "mfe1"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
        // For remotes (please adjust)
        name: "mfe1",
        filename: "remoteEntry.js",
        exposes: {
            './Module': './src/app/app.module.ts',
            './Module2': './src/app/helloworld/helloworld.module.ts',
        },

        // For hosts (please adjust)
        // remotes: {
        //     "mfe1": "mfe1@http://localhost:3000/remoteEntry.js",

        // },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },

          ...sharedMappings.getDescriptors()
        }

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

and in my host I have

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, 'tsconfig.json'),
  [/* mapped paths to share */]);

module.exports = {
  output: {
    uniqueName: "container-module-federation"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({
        // For hosts (please adjust)
        remotes: {
            "mfe1": "mfe1@http://localhost:4201/remoteEntry.js",
        },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },

          ...sharedMappings.getDescriptors()
        }

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

When I try to load the module via route:

const routes: Routes = [
  { path: 'hello',
  loadChildren: () =>
  loadRemoteModule({
    remoteEntry: 'http://localhost:4201/remoteEntry.js',
    remoteName: 'mfe1',
    exposedModule: './Module2'
  })
  .then(m => m.HelloWorldModule)
}
];

I get the error: Error: Uncaught (in promise): ChunkLoadError: Loading chunk default-src_app_helloworld_helloworld_module_ts failed.

I did notice there are two network requests:

http://localhost:4201/remoteEntry.js (expected)
http://localhost:5000/default-src_app_helloworld_helloworld_module_ts.js (unexpected)

Any ideas on why there would a second network request on my shell app (port 5000)?

singleton shared libs

We are trying to build a shared library project to be loaded once for every microfrontend.

We followed steps from the blog, and used shared mappings to add the index.ts path as a shared module from tsconfig.json.

The microfrontend builds and works fine with the library, but we expected them to be bundled in separate chunks.

Instead, the library code is built inside the microfrontend chunk.

How can we correctly separate the two bundles?

Static resource not loading in Shell from Remote

Hi ,
I am really new to module federation. I have installed this plugin and successfully loaded my Remote(mfe) in Shell.

But I had loaded a static resource in Remote like below , which loads perfectly fine in Remote but failed in Shell.
<img src="assets/sample.jpg">

In Remote it made request with Remote port (4300) http://localhost:4300/assets/sample.jpg and loaded the image successfully but once I loaded this in Shell, request is going for this asset with Shell port(4200).

http://localhost:4200/assets/sample.jpg -- failed.

Is this expected behavior or did I miss something..? I am attaching my Remote and Shell webpack configs

Remote
webpack.config.txt

Shell
webpack.config .txt

I am loading Remote in Shell dynamically

`const routes: Routes = [
{
path: 'flights',
loadChildren: () =>
loadRemoteModule({
remoteEntry: 'http://localhost:4300/remoteEntry.js',
remoteName: 'mfe',
exposedModule: './FlightsModule'
})
.then(m => m.FlightsModule)
}

];`

Support for i18n

Hi, ngx-build-plus has no builder for extract-i18n. Please check the possibility of including @angular-builders/custom-webpack instead of ngx-build-plus. Or an option to choose by the user

Support both es5 and es2015 in remoteEntry.js

Currently, the file name of the remote entry (remoteEntry.js in the examples) is fixed. When building the MFE with browser support requiring both es5 (IE) and es2015 (modern browsers) this leads to most chunk files being generated twice (es5 and es2015) but only one remoteEntry.js file. In my case, this happens to be the es2015 variant, which IE does not understand.

From the yarn build log:

Initial Chunk Files                      | Names            |      Size
polyfills-es5.8708f858c867e6a0dd1e.js    | polyfills-es5    | 196.21 kB
styles-es2015.0a3903fa3827b16066ce.js    | styles           | 192.21 kB
styles-es5.0a3903fa3827b16066ce.js       | styles           | 192.21 kB
polyfills-es2015.7a38b8dd65b103288781.js | polyfills        | 171.44 kB
remoteEntry_mfe.js                       | mfe              |  15.42 kB  // NO es2015
remoteEntry_mfe.js                       | mfe              |  15.38 kB  // NO es5
main-es5.63a2713a22969121bd91.js         | main             |  14.89 kB
main-es2015.63a2713a22969121bd91.js      | main             |  14.87 kB

In order to enable IE support it would be great if there were a way to have both variants of the remoteEntry.js file and allow the shell to pick the right one depending on which browser is being used.

As a workaround I effectively disabled es2015 by only having IE11 in the .browserslistrc file and setting the target to es5 in the tsconfig.

Live Reload Not Working

After executing ng add @angular-architects/module-federation command, live reload not working anymore. Nx based project.

Inf.
os: Ubuntu 20
node: v14.16.1
npm: 7.11.2
yarn: 1.22.5

Render component with dependencies?

How do I go about rendering a remote component that has dependencies to it?
Or depends on initialization in the feature module like initializing a state in Ngxs?

Not working with Angular 12

Hi,

I have upgraded my project to angular 12 and when I run the below command

ng add @angular-architects/module-federation --project shell --port 4200

I am getting "Mf" schema is using the keyword "id" which its support is deprecated. Use "$id" for schema ID.

@manfredsteyer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.