Angular9 入口组件
从分类上说,入口组件是 Angular 命令式加载的任意组件(也就是说你没有在模板中引用过它), 你可以在 NgModule
中引导它,或把它包含在路由定义中来指定入口组件。
对比一下这两种组件类型:有一类组件被包含在模板中,它们是声明式加载的;另一类组件你会命令式加载它,这就是入口组件。
入口组件有两种主要的类型:
- 引导用的根组件。
- 在路由定义中指定的组件。
引导用的入口组件
下面这个例子中指定了一个引导用组件 AppComponent
,位于基本的 "app.module.ts" 中:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent] // bootstrapped entry component
})
可引导组件是一个入口组件,Angular 会在引导过程中把它加载到 DOM 中。 其它入口组件是在其它时机动态加载的,比如用路由器。
Angular 会动态加载根组件 AppComponent
,是因为它的类型作为参数传给了 @NgModule.bootstrap
函数。
组件也可以在该模块的
ngDoBootstrap()
方法中进行命令式引导。@NgModule.bootstrap
属性告诉编译器,这里是一个入口组件,它应该生成代码,来使用这个组件引导该应用。
引导用的组件必须是入口组件,因为引导过程是命令式的,所以它需要一个入口组件。
路由到的入口组件
入口组件的第二种类型出现在路由定义中,就像这样:
const routes: Routes = [
{
path: '',
component: CustomerListComponent
}
];
路由定义使用组件类型引用了一个组件:component: CustomerListComponent
。
所有路由组件都必须是入口组件。这需要你把同一个组件添加到两个地方(路由中和 entryComponents
中),但编译器足够聪明,可以识别出这里是一个路由定义,因此它会自动把这些路由组件添加到 entryComponents
中。
entryComponents 数组
虽然 @NgModule
装饰器具有一个 entryComponents
数组,但大多数情况下你不用显式设置入口组件,因为 Angular 会自动把 @NgModule.bootstrap
中的组件以及路由定义中的组件添加到入口组件中。 虽然这两种机制足够自动添加大多数入口组件,但如果你要用其它方式根据类型来命令式的引导或动态加载某个组件,你就必须把它们显式添加到 entryComponents
中了。
entryComponents 和编译器
对于生产环境的应用,你总是希望加载尽可能小的代码。 这些代码应该只包含你实际使用到的类,并且排除那些从未用到的组件。因此,Angular 编译器只会为那些可以从 entryComponents
中直接或间接访问到的组件生成代码。 这意味着,仅仅往 @NgModule.declarations
中添加更多引用,并不能表达出它们在最终的代码包中是必要的。
实际上,很多库声明和导出的组件都是你从未用过的。 比如,Material Design 库会导出其中的所有组件,因为它不知道你会用哪一个。然而,显然你也不打算全都用上。 对于那些你没有引用过的,摇树优化工具就会把这些组件从最终的代码包中摘出去。
如果一个组件既不是入口组件也没有在模板中使用过,摇树优化工具就会把它扔出去。 所以,最好只添加那些真正的入口组件,以便让应用尽可能保持精简。
更多建议: