Angular 6+应用程序的运行时配置

时间:2018-08-21 05:08:12

标签: javascript angular deployment angular-cli web-deployment

在Angular应用程序运行时加载特定于环境的配置的推荐最佳实践是什么? Angular文档提到了APP_INITIALIZER的使用,但是对于诸如使用.forRoot()约定的导入模块的运行时配置之类的事情,在加载过程中还不够早。

在我的用例中,我具有通过Core模块构建和导入的身份验证服务,该模块由App模块导入。我正在使用的身份验证库(angular-oauth2-oidc库)允许在导入模块时配置访问令牌的自动附加(请参见this segment)。由于我正在使用的构建环境中存在一些限制,因此我只能生成一个通用的构建程序包以部署到所有环境中,因此我无法使用不同的environment.ts文件来动态设置值。

一个最初的想法是使用index.html页面上的fetch API将包含配置的JSON文件加载到全局变量上,但是由于该调用是异步的,因此有可能在以下情况下无法完全加载配置:导入Core模块。

1 个答案:

答案 0 :(得分:2)

这是我的配置设置的一部分,该设置使我的应用程序通过构建管道并花费了我几天的时间。我最终找到了一个使用APP_INITIALIZER加载REST服务并为我的App构建AppConfigService的解决方案。我正在使用相同的angular-oauth2-oidc库。

我针对此问题的解决方案不是在其forRoot()方法中设置OAuthModule。在通过APP_INITIALIZER进行的任何配置可用之前都会调用此方法-将其应用于forRoot()方法的配置对象时会产生不确定的值。

但是我们在http标头中需要一个令牌。因此,我使用了http拦截器来附加令牌,如here所述。诀窍是在工厂中设置OAuthModuleConfig。显然,这是在应用程序初始化后调用的。

配置模块

@NgModule({
  imports: [
    // no config here
    OAuthModule.forRoot(),
  ],
  providers: [
   {
    provide: HTTP_INTERCEPTORS,
    useFactory: authenticationInterceptorFactory,
    deps: [OAuthStorage, AuthenticationErrorHandler, OAuthModuleConfig],
    multi: true
   }
 ]
})

拦截器工厂

const authenticationInterceptorFactory = (oAuthService: OAuthStorage, authenticationErrorHandler: AuthenticationErrorHandler, oAuthModuleConfig: OAuthModuleConfig) => {
const config = {
 resourceServer: {
  allowedUrls: [
   // Include config settings here instead
   AppConfigService.settings.apiURL,
   AppConfigService.settings.anotherApiURL,
  ]
  sendAccessToken: true
 },
}
return new AuthenticationInterceptor(oAuthService, authenticationErrorHandler, config);
};