Angular Ivy 忽略 entryComponents 设置
Angular Ivy ignoring entryComponents setting
我有一个自定义组件装饰器,用于将 link 组件 "names",以便使用 JSON 对象将 link 组件放入层次结构中。
@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
}
装饰器所做的是自动将组件注册到 Map 中,类似于以下内容:
{
"name1": MyComponent
}
我有一个配置,几乎是一个动态路由配置,作为 JSON 对象 外部 存储到应用程序代码。
[
{
link: '/myroute',
component: 'name1'
}
]
在动态主机组件中,我使用如下代码来实例化规定的组件:
// ... 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
数组中,但现在 Ivy 似乎只是忽略了它,所以我没有明显的选择来确保组件不会从构建中删除。
@NgModule({
declarations: [
AppComponent,
MyComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
// ...some other stuff
],
entryComponents: [MyComponent],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
我怎样才能完成我以前用 EntryComponents 做的同样的事情,或者让它再次工作?也就是说,确保包含 MyComponent
?理想的解决方案是 不 包含全局列表:拥有装饰器的全部意义在于我不需要维护另一个组件列表,但我会接受所有可行的替代方案。
谢谢!
好吧,我以一种非常丑陋的方式解决了这个问题。
AFAICT,Ivy 让 tsc
和 Webpack 在 tree shake 期间掉落 类 时发挥它们的魔力(不确定细节,这只是我制作的一般图片)。
因此,为了 "emulate" entryComponents,我们必须在某处包含一个 "usage" 组件。我不想在模块外引用这个组件,所以我用 entryComponents
"emulation" 解决了这个问题。
很简单:
@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 {}
我真的希望有更好的方法。
我认为 EntryComponents 有它的用例份额,就像我的一样。
我有一个自定义组件装饰器,用于将 link 组件 "names",以便使用 JSON 对象将 link 组件放入层次结构中。
@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
}
装饰器所做的是自动将组件注册到 Map 中,类似于以下内容:
{
"name1": MyComponent
}
我有一个配置,几乎是一个动态路由配置,作为 JSON 对象 外部 存储到应用程序代码。
[
{
link: '/myroute',
component: 'name1'
}
]
在动态主机组件中,我使用如下代码来实例化规定的组件:
// ... 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
数组中,但现在 Ivy 似乎只是忽略了它,所以我没有明显的选择来确保组件不会从构建中删除。
@NgModule({
declarations: [
AppComponent,
MyComponent
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
// ...some other stuff
],
entryComponents: [MyComponent],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
我怎样才能完成我以前用 EntryComponents 做的同样的事情,或者让它再次工作?也就是说,确保包含 MyComponent
?理想的解决方案是 不 包含全局列表:拥有装饰器的全部意义在于我不需要维护另一个组件列表,但我会接受所有可行的替代方案。
谢谢!
好吧,我以一种非常丑陋的方式解决了这个问题。
AFAICT,Ivy 让 tsc
和 Webpack 在 tree shake 期间掉落 类 时发挥它们的魔力(不确定细节,这只是我制作的一般图片)。
因此,为了 "emulate" entryComponents,我们必须在某处包含一个 "usage" 组件。我不想在模块外引用这个组件,所以我用 entryComponents
"emulation" 解决了这个问题。
很简单:
@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 {}
我真的希望有更好的方法。
我认为 EntryComponents 有它的用例份额,就像我的一样。