Proxy Facades
此性能在 3.2 版本引入。
代理外观是一种灵便的机制,能够从可提早加载的功能模块中形象出性能,这种性能抽线,能够对应用程序的任何局部实现,例如组件、服务、指令等。
在提早加载的配置中,Facade 被定义为一个十分薄的层,它只是一个带有一些元数据的空类,并且这个 Facade 动静地创立了一个 Facade 实现的代理。
下图是一个例子:
一旦代码的任何局部拜访代理外观的任何办法或属性,必要的性能就会在暗地里加载和初始化,并将调用代理到理论实现。
依据设计,代理外观对于提早加载和急迫加载场景是齐全通明的。对于预加载场景,当代码动态链接时,理论实现覆盖了代理提供程序,并且无需任何代理层即可间接拜访。
feature module
功能模块容许您将外围业务逻辑与组件一起封装,并在申请任何组件或须要某些逻辑时立刻加载它们。代理外观利用功能模块配置来理解哪个性能蕴含外观的实现。每当拜访性能的属性或调用办法时,都会在后盾加载和初始化性能。
Defining Proxy Facades
本节介绍如何在根入口点中定义代理。
如前所述,代理外观是一个十分薄的层,由一个 JavaScript 类和一些元数据组成,这些元数据应该在根注入器中可用。而后能够在应用程序的任何事后加载或提早加载局部中应用这个轻量级注入器。
上面是一个 UserAccountFacade 代理定义的例子,它有一个 get 办法并由 USER_ACCOUNT_CORE_FEATURE 实现:
@Injectable({
providedIn: 'root',
useFactory: () =>
facadeFactory({
facade: UserAccountFacade,
feature: USER_ACCOUNT_CORE_FEATURE,
methods: ['get'],
}),
})
export abstract class UserAccountFacade {abstract get(): Observable<User | undefined>;
}
上文所示这种轻量级的 Facade 模块是急迫加载包的一部分(通常是根入口点,在默认 Spartacus 库的状况下),而其具体实现(UserAccountService),是在提早加载的块中提供的。提早加载的块通常实现在库的 core 文件夹下。
上面是一个实现的例子:
@Injectable()
export class UserAccountService implements UserAccountFacade {
// ...
get(): Observable<User | undefined> {// ...}
}
如何在懒加载的 chunk 里为该 facade 提供实现:
export const facadeProviders: Provider[] = [
UserAccountService,
{
provide: UserAccountFacade,
useExisting: UserAccountService,
},
];
为不便起见,外观同时作为 UserAccountFacade 和 UserAccountService 提供。这使得笼罩更容易一些(只有 UserAccountService 实现必须被笼罩),并不便急迫加载场景,其中 UserAccountFacade 提供者将笼罩默认的外观代理提供者。
实现细节
FacadeFactory 创立一个简略的外观代理类,该类基于办法和属性的配置。
所有办法都必须返回 Observable 对象,否则会被疏忽。
拜访任何属性(必须是 Observable)或调用任何办法都会触发加载由外观代理援用的功能模块。加载特色后,特色模块注入器用于注入外观实现,该实现在特色模块外部提供,与外观代理具备雷同的令牌。而后调用实现中的相应属性或办法并将其移交给调用者。
也能够应用 async 标记设置为 true 来创立外观工厂。这种门面会在功能模块初始化后短暂提早对门面实现的调用,这容许异步门面初始化。当门面应用异步初始化的 NgRx 存储时,这是举荐的设置。
Default Approach in Spartacus
在 Spartacus 中,外观代理默认定义在根入口点中,这意味着它们动态链接到主包。因而,以最小的开销,任何组件或服务都能够注入其轻量级代理令牌,而无需晓得 Facade 是否是任何提早加载或事后加载性能的一部分。
通常,facade 定义援用 feature_name_CORE 特色,而默认状况下,特色提供在 feature_name 特色下,并且 feature_name_CORE 用作 feature_name 的别名。通过这种设计,外观代理在默认配置中工作,其中外围、occ 和组件模块被捆绑到一个提早加载模块中。另一方面,很容易拆分这个模块,只加载外围局部(没有组件)来实现细粒度的提早加载。这能够通过为 feature_name_CORE 性能定义配置和提早导入来实现。
后续我会通过一些具体的例子来阐明。
更多 Jerry 的原创文章,尽在:” 汪子熙 ”: