javascript - Angular 6+ 应用程序的运行时配置
问题描述
在 Angular 应用程序运行时加载环境特定配置的推荐最佳实践是什么?Angular 文档提到了 APP_INITIALIZER 的使用,但是对于使用 .forRoot() 约定的导入模块的运行时配置等加载过程来说,这还不够早。
在我的用例中,我有一个通过核心模块构建和导入的身份验证服务,该核心模块由 App 模块导入。我正在使用的身份验证库(angular-oauth2-oidc库)允许在导入模块时配置访问令牌的自动附加(请参阅此段)。由于我正在使用的构建环境中存在限制,仅允许我生成一个通用构建包以部署到所有环境,因此我无法通过使用不同的 environment.ts 文件来动态设置值。
最初的想法是使用 index.html 页面上的 fetch API 将包含配置的 JSON 文件加载到全局变量中,但由于调用是异步的,因此在导入核心模块发生。
解决方案
这是我的配置设置的一部分,目的是让我的应用程序通过构建管道并花了我几天的时间。我最终找到了一个使用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);
};
推荐阅读
- r - `aliases` 不适用于 knitr `opts_knit$set` 中的 `root.dir`?
- reactjs - React.isValidElement() 无法检测无状态组件
- php - 我收到一个错误,但我不知道为什么?
- node.js - 如何更新 Homebridge 插件的特征值?
- reactjs - 如何检查本地存储中的令牌而不会在 react.js 中崩溃
- java - 从 GCS 存储桶中读取大型 avro 文件会导致内存不足异常
- linux - /bin/bash 给了我 docker 容器内的错误
- c# - 将 int 或 string 作为泛型类型传递并在可空和不可空属性中使用的接口
- c++ - c ++中文件输入输出中的long long v / s int
- c - 如何检查二维字符串数组是否包含超过 1 个单词?