module-federation / module-federation-examples

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

Can't retrieve exported components from ɵmod when using production mode #1228

Closed nohanna closed 3 years ago

nohanna commented 3 years ago

Describe the Bug

Note: I already posted on stackoverflow, but got no answer and on the angular-cli repo but they can't really help me since customized Webpack configurations and/or usage of Webpack specific features are not officially supported by the Angular CLI, so I guess everyone should have the issue.

I'm using Angular with Webpack 5 Module Federation for micro-frontends. I have 2 apps (let's call them app1 and app2) and my main app, app1, is federating components of app2.

In app2, my exposed components are exported by my main module, so when I try to federate some component, I can get it from the export section of my module. Everything works fine in dev mode, I can get my exposed module, retrieve my exported components and then use the component factory resolver to create it where I want in app1.

But when I build in production (I used ng serve --prod to reproduce the prod environment and test it) my exported components are gone but not the imports and providers. This is the module I get:

MyApp2Module: class e
  ɵfac: ƒ (t)
  ɵinj:
    imports: Array(1)
      0: (12) [ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ]
      length: 1
      [[Prototype]]: Array(0)
    providers: [ƒ]
    [[Prototype]]: Object
  ɵmod:
    bootstrap: []
    declarations: []
    exports: []
    id: null
    imports: []
    schemas: null
    transitiveCompileScopes: null
    type: class e
    [[Prototype]]: Object

As you can see, in ɵmod, I have no exported components and no declarations and I expected to see my components here. I guess it is due to AOT compilation and the optimization since it is working in dev mode. Is AOT removing everything in ɵmod on purpose or it is because my components are tree-shaked since they are not directly used by my app2? I tried to use sideEffects but it is not working. Is there another way to tell the compiler to not remove those components?

Minimal Reproduction

I created a reproduction here. Just use:

If you go to http://localhost:4200 and click in the navbar on "second app" you will see that the sidebar added 3 links which are loaded from second-app.

Now if you do the same in production mode:

Open the devtools, if you go to http://localhost:4200 and click in the navbar on "second app" you will see the object and the error.

Expected Behavior

I expect my exported components to be present in the exports array of ɵmod, just like in development mode.

Error


ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'ɵcmp')
TypeError: Cannot read properties of undefined (reading 'ɵcmp')
    at ye (main.js:1)
    at Qg.resolveComponentFactory (main.js:1)
    at main.js:1
    at c.invoke (polyfills.js:1)
    at Object.onInvoke (main.js:1)
    at c.invoke (polyfills.js:1)
    at u.run (polyfills.js:1)
    at polyfills.js:1
    at c.invokeTask (polyfills.js:1)
    at Object.onInvokeTask (main.js:1)
    at k (polyfills.js:1)
    at polyfills.js:1
    at c.invokeTask (polyfills.js:1)
    at Object.onInvokeTask (main.js:1)
    at c.invokeTask (polyfills.js:1)
    at u.runTask (polyfills.js:1)
    at _ (polyfills.js:1)

Environment


Angular CLI: 11.2.14
Node: 16.9.1
OS: linux x64

Angular: 11.2.14
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular/core                   11.2.14
@angular-devkit/architect       0.1102.14
@angular-devkit/build-angular   0.1102.14
@angular-devkit/core            11.2.14
@angular-devkit/schematics      11.2.14
@schematics/angular             11.2.14
@schematics/update              0.1102.14
@angular-builders/custom-webpack 11.1.1
ng-packagr                      11.2.4
rxjs                            6.6.7
typescript                      4.1.6
nohanna commented 3 years ago

Fixed it by using a static field in my module as suggested here.