1

I am using a custom attribute solution and a dynamic component creation in order to create components dynamically. The component is decorated with a custom attribute and then looked up in a dictionary at runtime. Such components have to be referenced in the module with entryComponents. This is working fine in dev mode but as soon as I try production, it no longer works.

There are no errors/warning in the build process either. Things just stop working. There is a @deprecated comment for entryComponents telling that it is no longer necessary but apparently not wrong to use.

Even if I move the entryComponents into the app.module.ts, the prod mode still fails. How can I make this work? I am happy to use other methods as long as I can reference components by name at runtime.

I have created a demo that reproduces the problem along with a git repository. Please note that merely doing enableProdMode() in StackBlitz will not demonstrate the issue. You have to do the "--prod" which I am not sure StackBlitz can do.

When running the app with ng serve all is fine but trying the production mode with ng serve --prod makes the app behave differently.

stirgun
  • 13
  • 3
  • Please elaborate the issue which are facing. Behave differently is a very generic term. – Vimal Patel Dec 08 '20 at 16:27
  • There is an unexpected and different behavior between dev and prod build. I explained the difference. Apparently `entryComponents` works in the dev build but gets completely ignored in the prod build. – stirgun Dec 08 '20 at 17:44

2 Answers2

0

I'm assuming you are using Angular 9+. As the error says entryComponents is deprecated since Angular 9 and implementation of Ivy, so you can safely remove it. Also you can read more about it here and here

Kerim092
  • 1,367
  • 1
  • 12
  • 32
0

I found a solution.
Like you, I have a dynamic component with a custom decorator.

Even though the component is imported in the Module and referenced in declarations the decorator is not executed. The reason, if I understand correctly, is tree-shaking.

The solution is simple:

// my.module.ts
import { MyDynamicComponent } from './my-dynamic.component.ts';

const dynamicComponents = [MyDynamicComponent];
@NgModule({
    declarations: [...dynamicComponents],
    imports: [CommonModule]
})
export class MyModule {}

If you are having this problem within a library compiled with ng-packager, the solution above is not enough, you also have to "use" the variable somehow.

For example:

// my.module.ts
import { MyDynamicComponent } from './my-dynamic.component.ts';

const dynamicComponents = [MyDynamicComponent];
@NgModule({
    declarations: [...dynamicComponents],
    imports: [CommonModule]
})
export class MyModule {
    constructor() {
        (window as any).dynamicComponents = dynamicComponents;
    }
}
Sebastian Perez
  • 456
  • 4
  • 12