可以使用 API 请求在 Angular 应用程序引导期间检索配置来解决此问题。我个人认为,Angular 应该采取这种方法,因为要求开发人员为每个环境构建并不是最好的解决方案。
在 Assets 中使用配置文件:
创建不同的配置文件夹/文件,如下所示
- /assets/configurations/develop/configuration.json
- /assets/configurations/production/configuration.json
使用正确的值填充那些 configuration.json 文件。
{
"production": false,
"api": "https://dev.myapi.domain.com"
}
创建一个表示您配置的接口。
export interface InitConfiguration {
production: boolean;
api: string;
}
更新您的 angular.json(或 workspace.json 或 project.json)文件,以便服务使用正确的文件。此示例使用存储资产并将其拉入的共享库。请确保将 glob 应用于每个环境,下面仅显示 dev。
"targets": {
"build": {
"configurations": {
"dev": {
"assets": [
{
"glob": "**/*",
"input": "./libs/shared/assets/",
"output": "./assets"
},
{
"glob": "configuration.json",
"input": "./libs/shared/assets/configurations/develop",
"output": "./assets/configurations"
}
...
这将把资产移动到服务用于检索json的位置。
创建一个配置服务,利用XMLHttpRequest(无法注入http,因为它需要在angular引导之前运行)。请注意,get请求正在访问assets / configuration / configuration.json文件。
import { Injectable } from '@angular/core';
import { InitConfiguration } from './init-configuration';
@Injectable({ providedIn: 'root' })
export class InitConfigurationService<
T extends InitConfiguration = InitConfiguration
> {
private static _configuration: InitConfiguration | undefined = undefined;
static production = false;
static loadConfig(): Promise<void> {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.addEventListener('load', () => {
if (req.status === 200) {
try {
InitConfigurationService._configuration = JSON.parse(
req.responseText
);
this.production =
InitConfigurationService._configuration?.production || false;
} catch (e) {
reject(e);
}
resolve();
} else {
reject(req.statusText);
}
});
req.open('GET', '/assets/configurations/configuration.json');
req.send();
});
}
getConfiguration(): T {
if (!InitConfigurationService._configuration) {
throw new ReferenceError(
`Attempting to access configuration before it is set.
Possible Solutions:
1. Bootstrap the loadConfig method into your applications main.ts
InitConfigurationService.loadConfig().then(
() => {
return platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
}
)
`
);
}
return InitConfigurationService._configuration as T;
}
get production(): boolean {
return InitConfigurationService.production;
}
get api(): string {
return this.getConfiguration().api || '';
}
}
最后,在调用bootstrapModule之前引导服务以运行loadConfig()。
InitConfigurationService.loadConfig().then(async () => {
if (InitConfigurationService.production) {
enableProdMode();
}
try {
return platformBrowserDynamic().bootstrapModule(AppModule);
} catch (err) {
return console.error(err);
}
});
这些步骤支持使用不同的服务配置提供不同的环境。当您去部署时,您将需要手动移动文件。只需在您的CD中引入类似于此的步骤即可。
copy my-angular-app\assets\configurations\develop\configuration.json my-angular-app\assets\configurations\configuration.json /Y
window.location.origin
,它会根据运行位置的不同而在这三个值之间进行更改。 - Langley