Angular 8 - Lazy loading yourself - AoT "No NgModule metada"

Viewed 191

I'm working on a Angular project which can load in widgets lazily, as well as loading them in from a UMD bundle.

I am currently facing some issues when building my current project for production with AoT enabled.

The problem

The AoT build does not provide a compiler. Therefore I am providing the JITCompiler to the application.

When compiling a module using the import(path/to/module) in production mode with the JITCompiler, I receive

main.e522a776bacf42032766.js:1 ERROR Error: No NgModule metadata found for 'function(){}'.
    at e.resolve (main.e522a776bacf42032766.js:1)
    at e.getNgModuleMetadata (main.e522a776bacf42032766.js:1)
    at e._loadModules (main.e522a776bacf42032766.js:1)
    at e._compileModuleAndComponents (main.e522a776bacf42032766.js:1)
    at e.compileModuleAsync (main.e522a776bacf42032766.js:1)
    at e.compileModuleAsync (main.e522a776bacf42032766.js:1)
    at t.project (main.e522a776bacf42032766.js:1)
    at t._tryNext (main.e522a776bacf42032766.js:1)
    at t._next (main.e522a776bacf42032766.js:1)
    at t.next (main.e522a776bacf42032766.js:1)

What changed

Listing the properties of the module, there is a difference between ng serve and ng serve --prod: [ngInjectorDef] in development serve as opposed to [] in production.

I was wondering if anyone else faced the issue?

Reproduction/testing yourself

There is a working stackblitz of the minimalistic project here: https://stackblitz.com/edit/angular-mpzmle

To serve to production as a production server, you'll have to:

  • Download the zip
  • Extract the zip
  • Run npm install in the extract directory
  • Adjust tsconfig.json (I cannot adjust it in stackblitz?)
    • Change module: es2015 to esnext
  • run ng serve --prod and serve to localhost:4200

An alternative to this manual labour is following the steps on https://github.com/juristr/manually-lazy-load-ngmodule/issues/1. It's a project implementing a similar concept, plagued by the same problem.

1 Answers

Special thanks to Antur84 on Github for his reply here

The compiler looks for objects with 'loadChildren' properties. If the property is of the syntax import(...).then(m => m.SOME_EXPORT), the url is traced and compiled into the appropriate factories.

So I had to refactor my callback key and the return type of the passed function.

Related