Angular Плющ игнорирует настройку entryComponents - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть собственный декоратор компонентов, используемый для связывания компонентов с «именами», чтобы использовать объект JSON для связывания компонентов в иерархию.

@MyDecorator('name1')
@Component({
  selector: 'my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponent implements OnInit {
  // ... rest of the implementation
}

То, что делает декоратор автоматически зарегистрировать компонент на карте, примерно так:

{
  "name1": MyComponent
}

У меня есть конфигурация, в значительной степени динамическая c конфигурация маршрута, сохраненная как JSON объект внешний к коду приложения.

[
  {
    link: '/myroute',
    component: 'name1'
  }
]

В хост-компоненте Dynami c я использую код, подобный следующему, для создания экземпляра предписанного компонента:

// ... gets the component "name"
const componentName = getConfigForRoute('myroute'); 
// should return MyComponent class, if MyComponent gets included in the app bundle:
const componentType = componentRegistry[componentName];

// componentType is ok with ng serve, and undefined in prod builds!
const cf = this.componentFactoryResolver.resolveComponentFactory(componentType);
// reportOutlet is a ViewContainerRef
this.reportOutlet.createComponent(cf);

Все работает как положено при работе в режиме разработки через ng serve.
Как это часто бывает, с производственной сборкой дела обстоят не так просто: компоненты, отмеченные MyDecorator, не имеют ссылки на код ts, кроме NgModule приложения, поэтому их радостно отбрасывает рьяный компилятор.

Я (как и все остальные) обычно включал их в массив EntryComponents в модуле, но теперь кажется, Айви просто игнорирует это, поэтому у меня нет очевидной возможности убедиться, что компоненты не будут удалены из сборки.


@NgModule({
  declarations: [
    AppComponent,
    MyComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    // ...some other stuff
  ],
  entryComponents: [MyComponent],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Как я могу выполнить sh то же самое, что я делал с EntryComponents или заставить его работать снова? То есть убедитесь, что MyComponent включено? Идеальное решение , а не включает глобальный список: весь смысл наличия декоратора состоит в том, что мне не нужно поддерживать еще один список компонентов, но я бы принял любую жизнеспособную альтернативу.

Спасибо!

1 Ответ

0 голосов
/ 21 апреля 2020

Что ж, я взломал эту проблему очень уродливо.

AFAICT, Ivy позволяет tsc и Webpack выполнять свои Mojo при отбрасывании классов во время встряхивания дерева (не уверен в деталях Это просто общая картина, которую я сделал) Я не хочу иметь ссылки на эти компоненты вне модуля, поэтому я решил проблему с entryComponents "эмуляцией". Это так просто:

@NgModule({
  declarations: [
    AppComponent,
    MyComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    // ...some other stuff
  ],
  entryComponents: [MyComponent],
  providers: [
    {
      provide: '__DEFINITELY_NOT_ENTRY_COMPONENTS__',
      // here I can include a list of components not to be dropped by tree shaking
      useValue: [MyComponent]
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Я действительно sh нашел лучший способ.
Я думаю, что EntryComponents имеет свою долю вариантов использования, как и у меня.

...