ユーザーがテストできるように構成可能なAPIURLを使用してangularアプリの本番ビルドをデプロイしたい。environment.tsを使用しているが、本番ビルド後、その方法がわからない変数を構成します。
どのようなアプローチを行う必要がありますか?
Angular-CLIを使用していますか?それなら、それは簡単なはずです。あなたはこのようなものを持っています:
src/
app/
environment/
environment.ts
environment.prod.ts
environment.prod.ts
に別のURLを入力するだけで、製品ビルドは2番目のURLを取得します。例えば。 environment.ts
が次のようになっているとしましょう。
{
"production": false,
"apiUrl": "http://localhost:8080"
}
これをenvironment.prod.ts
に入れてください:
{
"production": true,
"apiUrl": "https://example.com/api"
}
より多くの環境をセットアップできます。.angular-cli.json
のそのセクションとangular-cliリポジトリを確認してください。
編集:あなたのコメントによると、あなたはもっと欲しいです。
はい、それでもビルド後は設定できませんね。ユーザーが使用するURLがわからないため、ビルドをデプロイした後、外部から構成できるようにします。
このシナリオをさらに続けましょう。バックエンドクライアントを作成しましょう。
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { apiUrl } from '../environment/environment.ts';
@Injectable()
export class BackendService {
backendUrl: string = apiUrl;
constructor(private httpClient: HttpClient) {}
get(endpoint: string, params: any): Observable<any> {
const url= `${this.backendUrl}/${endpoint}`;
return this.httpClient.get(url, params);
}
}
簡略化されていますが、機能します。デフォルトでは、独自のURLを設定します。ただし、コンポーネントはその場でURLを設定し、そのURLから他のものを取得できます。
さて、次のステップは、あなたが持っているバックエンドを提供することです。これは事前構成された配列にすることも、クライアントにURLを自由に入力させることもできます(単に入力ボックス)。これを行うコンポーネントを作成し、ここでこのサービスを構成できます。おそらく、「適切な」バックエンド用に別のサービスを用意する必要があります。あなたの認証は嘘です。しかし、これはすべて実際にはシナリオによって異なります。
Environment * .tsファイルにはビルド時の構成が含まれており、ビルド後に変更することはできません。ビルド後に構成を変更する必要がある場合は、それらを別の場所に配置し、アプリケーションの起動時に動的に取得する必要があります
あなたができることは:
ステップ#1:json構成ファイルをsrc/assets/config/[envName] .jsonの下に置きます。
注:ts形式ではなくjson形式である必要があります
ステップ#2:新しい構成サービスを追加します
import {Inject, Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Observable} from 'rxjs/Rx';
import {environment} from "../../environments/environment";
/**
* Declaration of config class
*/
export class AppConfig
{
//Your properties here
readonly production: boolean;
readonly name: string;
readonly apiBaseUrl: string;
}
/**
* Global variable containing actual config to use. Initialised via ajax call
*/
export let APP_CONFIG: AppConfig;
/**
* Service in charge of dynamically initialising configuration
*/
@Injectable()
export class AppConfigService
{
constructor(private http: HttpClient)
{
}
public load()
{
return new Promise((resolve, reject) => {
let confName = environment.name + '.json';
this.http.get('/assets/config/' + confName).map(res => res as any).catch((error: any): any => {
reject(true);
return Observable.throw('Server error');
}).subscribe((envResponse :any) => {
let t = new AppConfig();
//Modify envResponse here if needed (e.g. to ajust parameters for https,...)
APP_CONFIG = Object.assign(t, envResponse);
resolve(true);
});
});
}
}
ステップ#:メインモジュールで、モジュールを宣言する前にこれを追加します
/**
* Exported function so that it works with AOT
* @param {AppConfigService} configService
* @returns {Function}
*/
export function loadConfigService(configService: AppConfigService): Function
{
return () => { return configService.load() };
}
ステップ#4:モジュールプロバイダーを変更して、このプロバイダーを追加します:[…
AppConfigService,
{ provide: APP_INITIALIZER, useFactory: loadConfigService , deps: [AppConfigService], multi: true },
],
ステップ5:コードでは、environment.configXXXを使用する代わりに、これを使用します
import {APP_CONFIG} from "../services/app-config.service";
//…
return APP_CONFIG.configXXX;
これは単純化された例です。http呼び出しを行うときに絶対URLが必要なため、angular Universal)を使用する場合は、実際にいくつかの変更を加える必要があります。