Запретить AOT исключать компонент из компиляции

#angular #typescript #angular-dynamic-components

Вопрос:

Я работал над приложением Angular с большим количеством динамических компонентов, а также написал аннотацию для регистрации таких динамических компонентов.

Давайте посмотрим код:

  1. Аннотация. (Я упростил это для лучшего понимания).
 import { Type, Component } from '@angular/core';

export const componentsMap: { [key: string]: Type<Component> } = {};

export const DynamicComponent = (componentId: string) => {
  return (component: Component) => {
    componentsMap[componentId] = component;
    return component;
  };
};
 
  1. Динамический компонент
 import { Component } from '@angular/core';
import { DynamicComponent } from './dynamic-component.decorator';

@Component({
  selector: 'dynamic-test',
  template: `<h1>I'm alive!</h1>`
})
@DynamicComponent('dynamicComponent')
export class DynamicTestComponent {}
 

Затем, используя распознаватель фабрики компонентов, компонент создается и вводится в ng-контейнер (я пропущу эту часть, так как с ней нет проблем).

Это прекрасно работает, если приложение скомпилировано в JIT. Если приложение скомпилировано в AOT, компонент не будет включен в скомпилированные файлы js. Как я понимаю, это происходит потому, что AOT не видит никаких применений в приложении (только объявление в модуле) и исключает его из компиляции. Отключение компиляции AOT не является вариантом, так как размер конечного приложения будет слишком большим.

Единственный способ, которым мне сказали, чтобы это сработало, — это сделать это:

 @NgModule({
    declarations: [DynamicTestComponent],
    imports: [CommonModule]
})
export class TestModule {
    static declaration = [DynamicTestComponent]
}
 

Это решение лучше, чем отключение AOT, но я искал что-то более интуитивное решение.

Знаете ли вы, что еще можно сделать, чтобы компонент не был исключен во время компиляции AOT?

p.s. Я создал пример с приведенным выше кодом на StackBlitz, так что вы можете его скачать. https://stackblitz.com/edit/angular-ivy-souyuz Вы можете запустить его локально, ng serve --configuration production чтобы воспроизвести проблему.