Laden von umgebungsabhängigen Konfigurationsdateien

Wer vor dem eigentlichen Laden der Angular-Anwendung Werte basierend auf der aktuellen Umgebung („development“, „production“, …) laden möchte, kann das u.a. mit der in diesem Git-Beitrag zur Verfügung gestellten Config-Klasse relativ einfach tun.


Das Prinzip dabei: Aus einer json-Datei wird die aktuelle Umgebung ausgelesen um dann mit dieser Information entsprechende Umgebungsabhängige Werte global zur Verfügung zu stellen.

Dazu müssen folgende Dateien angelegt werden:
Im root-Ordner (wo auch die index.html-Datei angesiedelt ist):
env.json (enthält die aktuelle Umgebung)
config.development.json (enthält alle Werte für die Dev-Umgebung)
config.production.json (enthält alle Werte für die Prod-Umgebung)

Im app-Ordner
app.config.ts

Falls man die Angular-Anwendung mit der angular-cli bauen möchte, müssen die json-Dateien entsprechend in der angular-cli.json-Datei unter „assets“ separat hinzugefügt werden.

Um die Konfiguration global zur Verfügung zu stellen, müssen die entsprechenden Provider in app.modules.ts hinzugefügt werden:

providers: [
      AppConfig,
      { provide: APP_INITIALIZER, useFactory: (config: AppConfig) => () => config.load(), deps: [AppConfig], multi: true }
  ],

Inhalte der Dateien:
env.json:

{
  "env":"production"
}

config.development.json:

{
  "host":"http://localhost"
}

config.production.json:

{
  "host":"http://yourdomain.com"
}

app.config.ts

/**
 * This is the place to do the reading of env and config files.
 */
import { Inject, Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class AppConfig {
    private config: Object = null;
    private env: Object = null;

    constructor(private http: Http) {}

    /**
     * Use to get the data found in the config file
     */
    public getConfig(key: any) {
        return this.config[key];
    }

    /**
     * Use to get the data found in the environment file
     */
    public getEnv(key: any) {
        return this.env[key];
    }

    /**
     * This method:
     *   a) Loads "env.json" to get the current working environment (e.g.: 'production', 'development')
     *   b) Loads "config.[env].json" to get all env's variables (e.g.: 'config.development.json')
     */
    public load() {
        return new Promise((resolve, reject) => {
            this.http.get('env.json').map( res => res.json() ).catch((error: any):any => {
                console.log('Configuration file "env.json" could not be read');
                resolve(true);
                return Observable.throw(error.json().error || 'Server error');
            }).subscribe( (envResponse) => {
                this.env = envResponse;
                let request:any = null;

                switch (envResponse.env) {
                    case 'production': {
                        request = this.http.get('config.' + envResponse.env + '.json');
                    } break;

                    case 'development': {
                        request = this.http.get('config.' + envResponse.env + '.json');
                    } break;

                    case 'default': {
                        console.error('Environment file is not set or invalid');
                        resolve(true);
                    } break;
                }

                if (request) {
                    request
                        .map( res => res.json() )
                        .catch((error: any) => {
                            console.error('Error reading ' + envResponse.env + ' configuration file');
                            resolve(error);
                            return Observable.throw(error.json().error || 'Server error');
                        })
                        .subscribe((responseData) => {
                            this.config = responseData;
                            resolve(true);
                        });
                } else {
                    console.error('Env config file "env.json" is not valid');
                    resolve(true);
                }
            });

        });
    }
}

Um in einer Komponente auf den jeweils gewünschten Wert zugreifen zu können, muss die Config-Klasse (per DI) entsprechend geladen werden:

export class AppComponent {
  host: string = '';

  constructor(private config: AppConfig) {
    this.host = config.getConfig('host');
  }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.