首页 > 解决方案 > Angular 6+ 应用程序的运行时配置

问题描述

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

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

最初的想法是使用 index.html 页面上的 fetch API 将包含配置的 JSON 文件加载到全局变量中,但由于调用是异步的,因此在导入核心模块发生。

标签: javascriptangulardeploymentangular-cliweb-deployment

解决方案


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

我对这个问题的解决方案不是在其 forRoot() 方法中设置 OAuthModule。它在任何配置通过APP_INITIALIZER可用之前被调用 - 当应用于给forRoot()方法的配置对象时,这会导致未定义的值。

但是我们需要在 http 标头中添加一个令牌。因此,我使用 http 拦截器来附加令牌,如此处所述。诀窍是在工厂中设置 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);
};

推荐阅读