When built with optimization compileModuleAndAllComponentsSync returns an empty list of component factories
See original GitHub issue🐞 bug report
Affected Package
Is this a regression?
This seems to be the behavoir since at least 9.0.1.
Description
Calling the Compiler.compileModuleAndAllComponentsSync
method is supposed to return the component factories in addition to the module factory. However, when built with --prod, that list is empty.
Looking over the compiled code, it looks like the declarations
are completely removed from the module. Setting ‘optimization’ to false in angular.json solves the problem, but that means the code is no longer built for production.
🔬 Minimal Reproduction
The problem can be observed with this minimal repo: https://github.com/AndreiVajnaII/lazy-load-ng-modules
Just npm install
and ng serve
. Clicking on either “Load module 1” or “Load module 2” will call the
compileModuleAndAllComponentsSync
on a lazy loaded module and display a list of components it declares. However, if started with ng serve --prod
, the list will be empty.
🔥 Exception or Error
No error is given, the list of component factories is just empty
🌍 Your Environment
Angular Version:
Angular CLI: 9.0.7
Node: 10.14.1
OS: win32 x64
Angular: 9.0.7
... cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/build-angular 0.900.7
@angular-devkit/build-optimizer 0.900.7
@angular-devkit/build-webpack 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7
@ngtools/webpack 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (4 by maintainers)
As others have mentioned, with optimizations on the part of the NgModule definition which refers to components/etc. is removed. This allows components to be tree-shaken (since otherwise they would never be removed as modules would contain references to every component).
If you have a use case where you want to load a module and enumerate some components from it, I suggest making a custom multi-provider token and having the module register each component type via the multi-provider (sort of like how the
ROUTES
token works in the router). You can then load the module, create an injector from it, inject the token, and get a list of components that way. This won’t be affected by the optimizer as you’re writing your own references to the components, not relying on the module definition.This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.