angular - 如何外部化 Angular 7 应用程序的属性值?
问题描述
我有一个 Angular 7 应用程序,其中的app.module.ts
文件如下所示。请注意,在此示例中,有 2 个模块,每个模块都有 1 个键,其值需要外部化。externalized
我的意思是应该在运行时从环境中获取值。
@NgModule({
declarations: [ ... ],
imports: [
SomeModule.forRoot({ apiKey1: "needs to be externalized" }),
AnotherModule.forRoot({ apiKey2: "needs to also be externalized" })
],
providers: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }
我所做的是构建这个应用程序(例如ng build
,然后使用 Docker 将其容器化)。在部署时,该DevOps
人希望按如下方式运行 docker 容器。
docker run -e API_KEY_1='somekey' -e API_KEY_2='anotherkey' -p 80:80 my-container:production
请注意,API_KEY_1
应该映射到apiKey1
并且API_KEY_2
应该映射到apiKey2
。
是否有任何规范的方法可以将 Angular 应用程序的值外部化?
我考虑过编写一个帮助脚本来对文件进行字符串替换,但我认为这种方法不是很规范(因为转译的 Angular 应用程序文件被混淆和缩小了)。该脚本将在容器启动时运行,读取环境变量(键和值),然后查看文件以将旧值替换为环境中的值。
最终,Angular 应用程序将与 Kubernetes 进行编排。我想知道是否有任何东西可以帮助或影响如何以最佳实践方式将价值观外化。
任何帮助表示赞赏。
解决方案
您可以在自定义入口点中使用替换。
FROM nginx
RUN apt-get update && apt-get -y install gettext-base nginx-extras
ADD docker-entrypoint.sh /
ADD settings.json.template /
COPY dist /usr/share/nginx/html
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
像docker-entrypoint.sh
这样:
#!/bin/bash
envsubst < "settings.json.template" > "settings.json"
cp settings.json /usr/share/nginx/html/assets/
# Launch nginx
exec "$@"
还有一个settings.json.template
:
{
"apiKey2": "$API_KEY_2",
"apiKey1": "$API_KEY_1"
}
然后在您的来源上添加一个文件
settings-loader.ts
export const settingsLoader = new Promise<any>((resolve, reject) => {
const xmlhttp = new XMLHttpRequest();
const method = 'GET';
const url = './assets/settings.json';
xmlhttp.open(method, url, true);
xmlhttp.onload = function() {
if (xmlhttp.status === 200) {
const _environment = JSON.parse(xmlhttp.responseText);
resolve(_environment);
} else {
resolve();
}
};
xmlhttp.send();
});
在你的main.ts
:
import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app/app.module';
import {environment} from './environments/environment';
import {settingsLoader} from 'settings-loader';
settingsLoader.then((settings) => {
if (settings != null) {
environment.settings = Object.assign(environment.settings, settings);
}
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
});
然后你应该可以访问你的代码
import {environment} from '../environments/environment';
console.log(environment.settings.apiKey1);
推荐阅读
- java - Spring Boot Common JPA 存储库类
- javascript - 自定义钩子的状态不会在所有组件中更新?
- microprofile - 如何将 Microprofile 健康检查绑定到应用程序的上下文根?
- git - Blender 的外部 fbx 文件未添加到 Unreal 项目的 git 存储库中
- node.js - ConflictException:此域名在无服务器 AWS 中已存在基本路径
- python - djnago View - 如何从视图中获取计数查询?
- c# - TrendMicro API 简单上传示例文件名不出现
- postgresql - 如何使用识别为序列在 PostgreSQL 13 中获取 MyBatis 插入主键值
- xml - 需要xml-apis 1.4.01的开发代码
- video-streaming - rtsp链接有延迟,无法获取http链接