Dynamic Loading NgModule Support
See original GitHub issueRight now, there’s only one official Angular CLI way to dynamically load NgModule; through the router configuration and the discovery process for lazy routes.
This discussion is not about dynamic loading of TypeScript files, which works properly already, using the import()
keyword. This is exclusively when splitting code at the NgModule boundary, which isn’t currently supported.
This has as a consequence that people have to use a fake route if they want to split at the NgModule boundary; e.g. AIO here. Although this work, it’s a bad pattern that users shouldn’t have to do.
The current suggested design is:
- Allow users to add entries to the lazy route from the configuration to emulate the ROUTES provider, then
- Use
NgModuleFactoryLoader
(see example in AIO here) to load the module, which supports both JIT and AOT.
Alternative design was to add refactoring/support of import()
keyword, with some annotation support to tell if we should rename to import on AOT. This would require changes in the Angular Compiler which would only make this compatible with Angular 6, while the solution above is fully compatible with Angular 5.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:74
- Comments:26 (2 by maintainers)
Top GitHub Comments
With Ivy, we will be able to use
import('module-name')
for lazy-loading and rendering feature components without the router involved.Jason Aden talks about it and shows a demo here: Angular Ivy by example | Jason Aden | AngularConnect 2018 (timestamped)
But Ivy will probably not be production-ready before Angular 9.x according to @IgorMinar.
Since Angular 8 we support using dynamic imports (
import()
syntax) in the routerloadChildren
split point and have deprecated the string syntax. We also automatically updated CLI projects usingng update
. You can see the deprecation here: https://angular.io/guide/deprecations#loadchildren-string-syntax.In non-Ivy projects, it ends up working the same as before. Internally we rewrite the
import('./something.module.ts')
toimport('something.module.ngfactory.js')
to make it work. This rewrite only happens inloadChildren
properties. You can read more about it here: https://github.com/angular/angular-cli/blob/0d70565f9d80f1d765622eb8c8b2c3c701723599/packages/ngtools/webpack/src/transformers/import_factory.ts#L16-L55.In Ivy projects however
.ngfactory.js
files do not exist. If you useimport()
on a Ivy project and that project was compiled with AOT, the NgModule will contain everything you need to dynamically load it outside the Angular router.In Angular version 9 Ivy will become the default compiler. Using Ivy together with the
import()
syntax enables dynamically loading NgModules without any special tooling.