尝试在 appSettings.json - Angular 和 Typescript 中设置环境变量

Trying to set environment variables in appSettings.json - Angular and Typescript

我基本上是在尝试在 appSettings 中设置 API URL 路径,这样我就可以轻松地在生产环境和开发环境之间来回切换。

这是我的 appSettings.json 文件。 apiURL 是我要设置和获取的变量。

{
 "Logging": {
"LogLevel": {
  "Default": "Information",
  "Microsoft": "Warning",
  "Microsoft.Hosting.Lifetime": "Information"
}
  },
 "AllowedHosts": "*",
 "apiURL": "http://10.241.2.68:8132/api"
}

这是我的页面,它试图访问我在 appSettings.json 中设置的环境变量。

import { Injectable } from '@angular/core';
// import { Defendant } from 'src/app/Models/Defendant';
import { Charge } from 'src/app/Models/Charge';
import { DefendantItem } from '../Models/DefendantItem';
import { Defendant_Charge } from '../Models/Defendant_Charge';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { AppConfiguration } from "read-appsettings-json";  
@Injectable({
providedIn: 'root'
})
export class ChargeService {
//console.log(AppConfiguration.Setting().apiURL);
////////////////////////////////////////////////////////////////////
//  below is where I am trying to reference the environment variable
//  the entire program bombs and displays "GET \" on the page.
ChargeControllerUrl = AppConfiguration.Setting().apiURL + "/Charges";
//ChargeControllerUrl = "http://10.241.2.68:8132/api/Charges";
}

如评论中所述,appsettings.json 不适用于 angular 应用程序。在这里您可以通过 this tutorial 找到使用环境的必要步骤。 这里有一些快速步骤:

import { environment } from './../environments/environment';
...
const baseUrl: string = environment.baseUrl;

其中 environment.ts 可能看起来像

export const environment = {
  production: false,
  baseUrl: "http://localhost:45644/api/",
};

实例here

我建议不要使用 environment.ts,因为这是构建时配置。

您真正要寻找的是在 运行 时间根据环境获取您的 app-settings.json 文件的某种方法。这意味着您可以打包您的代码并在您的环境中推广打包的代码,而无需重新构建。

Angular 有一个叫做 APP_INITIALIZER 的东西,你可以用它来实现这个。

  1. 在 assets/config 文件夹

    中设置您的应用程序-settings.json(应用程序-settings.qa.json、应用程序-settings.prod.json)
  2. 配置 AppConfigService angular 服务。

//app/services/app-config.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class AppConfigService {

  private appConfig: any;
  private http : HttpClient;

  constructor(http: HttpClient) {
    this.http = http;
  }

  loadAppConfig() {
    return this.http.get('/assets/config/app-settings.json')
      .toPromise()
      .then(config => {
        this.appConfig = config;
      });
  }

  get apiBaseUrl() : string {
    return this.appConfig.apiBaseUrl;
  }
}

  1. 使用 APP_INITIALIZER 作为 AppModule 中的注入令牌配置 AppService
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';

import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { AppConfigService } from './services/app-config/app-config.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    {
      provide : APP_INITIALIZER,
      multi : true,
       deps : [AppConfigService],
       useFactory : (appConfigService : AppConfigService) =>  () => appConfigService.loadAppConfig()
    }

  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

现在您可以使用此服务通过依赖注入获取 baseURL

下面是一个示例服务,您的服务可能看起来像这样。注意构造函数和 apiUrl private class variable

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { IempList } from '../interfaces/iemp-get-res';
import { map } from 'rxjs/operators';
import { AppConfigService } from 'src/app/services/app-config/app-config.service';

@Injectable({
  providedIn: 'root'
})
export class EmpService {

  constructor(private httpClient: HttpClient, private appConfigService: AppConfigService) { }

  private apiUrl = this.appConfigService.apiBaseUrl + '/api/employee';

  public getEmp(): Observable<IempList> {
    return this.httpClient.get(this.apiUrl)
      .pipe(map((res: IempList) => res));
  }

  public deletEmp(id): Observable<any> {
    return this.httpClient.delete(this.apiUrl + '/' + id)
      .pipe(map((res: any) => res));
  }

  public createEmp(formData): Observable<any> {
    return this.httpClient.post(this.apiUrl + '/create', formData.data)
      .pipe(map((res: any) => res));
  }

  public editEmp(formData): Observable<any> {
    return this.httpClient.post(this.apiUrl + '/update', formData.empData)
      .pipe(map((res: any) => res));
  }
}

从这里开始,您将需要使用您的部署方法(例如 azure devops 管道)根据您的环境重命名资产文件夹中的适当文件

qa:重命名应用程序-settings.qa.json -> 应用程序-settings.json 产品:重命名 app-settings.prod.json -> app-settings.json

然后您将拥有 运行time 应用程序配置

您应该按照以下步骤操作:

  1. 在项目的根目录中创建一个 .env 文件,并以 NAME=VALUE 的形式在新行中添加特定于环境的变量,如下所示:
API_URL=http://localhost:45644/api/
  1. 使用 dotenv's tools 将环境变量从 .env 文件加载到 process.env 对象

  2. 安装 custom-webpack 作为开发依赖项:

npm install -D @angular-builders/custom-webpack
  1. 修改你的 Angular 配置 - angular.json - 使用新的构建器(custom-webpack)
"projects": {
    "name-of-the-project": {
      //...
      "architect": {
        "build": {
          "builder":"@angular-builders/custom-webpack:browser"_,
          "options": {
            "customWebpackConfig": {
                "path":"custom-webpack.config.js"
            },
            //...
        //...
    } }
  1. 然后,您将在 Angular 工作区的根目录下创建 custom-webpack.config.js 文件并添加以下内容以检索您的环境变量并将它们传递给您的构建器:
const webpack = require('webpack')
    require('dotenv').config()
    module.exports = {
      plugins: [
        new webpack.DefinePlugin({
          $ENV: {
            API_URL: JSON.stringify(process.env.API_URL),
          },
        }),
      ],
    }
  1. 最后,为了在 Angular 中使用您的环境变量,您将添加一些类型,以便您可以在我们的 Angular 应用程序中从上面的 webpack 引用您的 $ENV 变量.
  • 首先,让我们在工作区根目录的 src 目录中创建一个 typing.d.ts 文件,并添加以下内容:
declare var $ENV: Env;
    
    interface Env {
      API_URL: string;
    }
  • 然后,在 environment.ts 中,您需要读取传递给应用程序的环境变量,这样您的 environment.ts 就会像这样:
export const environment = {
  production: true,
  environment: $ENV.API_URL,
};
  1. 以及在组件上使用环境变量:
import { environment } from './../environments/environment';
...
public environment = environment.environment