Expose declarations property in NgModuleRef

This issue has been tracked since 2022-09-08.

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

What we are trying to reach:
render component dynamically by importing the angular module file and pick the component type from the module declarations without the need to import the component directly.

We are using dynamic rendering for components in our app. Now as compileModuleAndAllComponentsSync is deprecated there is no angular way get a component type from an angular module file, which is needed to create a component dynamically using createComponent.

We are aware that we can directly import an angular component but this does not match our application architecture. Cause we are bundling the lazy module in each module in a file and with the direct import of a component we get a bundle component per file.

Now we have a work around to access the declarations property of an NgModule by accessing the emod property, but it is probably not the appropriate way to do that.

As Angular offers different ways to render components, it would be great to consider this scenario and offer a way to dynamically import components from module file.

Proposed solution

Angular should expose the declarations property in the NgModuleRef which is already loaded into emod property

Alternatives considered

accessing the emod property on the imported module to allow access to the module componets types

JoostK wrote this answer on 2022-09-08

This is unfortunately not possible due to how NgModule.declarations are optimized away in production builds, in order for unused components, directives and pipes to be tree-shaken from the bundle. This is an important size optimization and providing APIs to access this information would prevent Angular from using this optimization.

The recommended approach is to declare a static field on the NgModule class that is equal to declarations, if you depend on this information at runtime.

MehyarSawas wrote this answer on 2022-09-08

But I still can access the declarations through emod property. How this does not affect the optimization?

In this case we need to go through 80 modules and re-declare over 1000 components. At least more convenient alternative would be good.

JoostK wrote this answer on 2022-09-08

But I still can access the declarations through emod property. How this does not affect the optimization?

That means you're not targeting an optimized build; that property will be empty in production builds with optimizations enabled.

MehyarSawas wrote this answer on 2022-09-08

Yes, we are using custom optimization for the dynamic module rendering. But still this should be an option as long as it is possible customize angular build and the way components are rendered.

So the goal we are trying to reach is to use dynamic rendering but build production with only 1 file per module and not per component. Any suggestion?

JoostK wrote this answer on 2022-09-08

In this case we need to go through 80 modules and re-declare over 1000 components. At least more convenient alternative would be good.

You can reference a shared list of declarations:

const DECLARATIONS = [/* ... */];

@NgModule({
  declarations: DECLARATIONS,
})
export class MyModule {
  static Declarations = DECLARATIONS;
}
MehyarSawas wrote this answer on 2022-09-10

Thanks for your suggestion

More Details About Repo
Owner Name angular
Repo Name angular
Full Name angular/angular
Language TypeScript
Created Date 2014-09-18
Updated Date 2022-10-05
Star Count 84147
Watcher Count 3063
Fork Count 22247
Issue Count 1201

YOU MAY BE INTERESTED

Issue Title Created Date Updated Date