Angular 2和Team City Production / Environment Variables

时间:2017-02-06 21:26:56

标签: angular environment-variables teamcity environment octopus-deploy

我们有一个新的Angular应用程序正在为文件夹构建AOT。一切都运行正常,但我们正在尝试使用TeamCity / Octopus Deploy将其配置为五步构建过程,其中每个步骤将使用一些不同的变量用于端点(API调用等)我试图计算将这个传递给没有在后端运行的AOT应用程序的最佳方法。

我知道可用于触发不同配置的--environment标志,但我们的目标是让一个构建遍历所有环境。我对如何根据它所处的环境在应用程序中传递变量感到茫然。

我目前的想法是在config.js文件夹中保留一个assets文件,以便应用可以在应用的其余部分之前加载它并在窗口上设置一些变量,但是这会留下我的无法将TS文件导入需要这些变量的文件的问题。

如何以更直观的方式将此信息传递到应用程序?如果没有单独的构建,这是不可能的吗?

1 个答案:

答案 0 :(得分:2)

我会建立你的config.js想法。配置应作为应用程序启动的一部分加载,而不是构建的一部分。您需要创建一个在应用程序启动时加载config.js的服务,使用APP_INITIALIZER提供程序并将其传递给创建服务的工厂。这是一个例子:

app.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core';

@NgModule({
    imports: [
        ....
    ],
    declarations: [
        ....
    ],
    providers: [
        {
            provide: APP_INITIALIZER,
            useFactory: configServiceFactory,
            deps: [ConfigService, Http, AppConfig],
            multi: true
        },
        AppConfig,
        ConfigService
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

配置服务:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

import { AppConfig } from '../../app.config';

@Injectable()
export class ConfigService {
    private _config: AppConfig;

    constructor(private http: Http, private config: AppConfig) {
    }

    public Load(): Promise<AppConfig> {
        return new Promise((resolve) => {
            this.http.get('./config.json').map(res => res.json())
            .subscribe((config: AppConfig) => {
                this.copyConfiguration(config, new AppConfig()).then((data: AppConfig) => {
                    this._config = data;
                    resolve(this._config);
                });
            }, (error: any) => {
                this._config = new AppConfig();
                resolve(this._config);
            });
        });
    }

    public GetApiUrl(endPoint: any): string {
        return `${this._config.ApiUrls.BaseUrl}/${this._config.ApiUrls[ endPoint ]}`;
    }

    public GetApiEndPoint(endPoint: any): string {
        return this._config.ApiUrls[ endPoint ];
    }

    public Get(key: any): any {
        return this._config[ key ];
    }

    private copyConfiguration(source: Object, destination: Object): any {
        return new Promise(function(resolve) {
            Object.keys(source).forEach(function(key) {
                destination[ key ] = source[ key ];
                resolve(destination);
            });
        });
    }
}

export function configServiceFactory(config: ConfigService) {
    return () => config.Load();
}