Acessar variables ​​de ambiente na construção de produção Angular 4

Eu quero implantar uma compilation de produção de aplicativo angular com uma URL configurável para o usuário testá-lo. Eu uso o environment.ts mas depois da construção da produção, eu não sei como configurar as variables.

Qual abordagem precisa ser feita?

Você está usando o Angular-CLI? Deve ser fácil então. Você tem algo parecido com isto:

src/ app/ environment/ environment.ts environment.prod.ts 

Basta colocar url diferente em environment.prod.ts e sua build de prod recebe um segundo url. Por exemplo, digamos que o seu environment.ts assim:

 { "production": false, "apiUrl": "http://localhost:8080" } 

Coloque isso em environment.prod.ts :

 { "production": true, "apiUrl": "https://example.com/api" } 

Você pode configurar mais ambientes, verifique essa seção de .angular-cli.json e angular-cli repo.

Edit: Como por seu comentário, você quer mais.

Sim, mas isso ainda não é configurável após a compilation, não é? Como não sei qual URL o usuário deseja usar, quero configurá-lo externamente após implantar a compilation.

Vamos continuar esse cenário ainda mais. Vamos ter um cliente backend:

 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 { const url= `${this.backendUrl}/${endpoint}`; return this.httpClient.get(url, params); } } 

Simplificado, mas funciona. Por padrão, você define seu próprio URL. Mas seus componentes podem definir o URL rapidamente e obter outras coisas desse URL.

Agora, o próximo passo seria oferecer quais backends você possui. Esta pode ser uma matriz pré-configurada, ou você pode deixar o cliente entrar na url livremente (simplesmente checkbox de input). Você pode ter um componente que faz isso e configura esse serviço aqui. Você provavelmente também deve ter um serviço separado para o seu back-end “adequado”, onde, por exemplo, a sua autenticação está. Mas tudo isso realmente depende do seu cenário.

O arquivo * .ts do ambiente contém configurações de tempo de construção, que você não pode alterar após a construção. Se você precisar alterar sua configuração após a compilation, precisará colocá-los em um local diferente e recuperá-los dinamicamente quando o aplicativo for iniciado

O que você pode fazer é:

Etapa 1 : coloque seus arquivos de configuração do json em src / assets / config / [envName] .json.

Nota: tem que ser formato json, não formato ts

Etapa 2 : Adicionar um novo serviço de configuração

 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 (eg to ajust parameters for https,...) APP_CONFIG = Object.assign(t, envResponse); resolve(true); }); }); } } 

Passo # 3 : No seu módulo principal, adicione isto antes de declarar o módulo

 /** * Exported function so that it works with AOT * @param {AppConfigService} configService * @returns {Function} */ export function loadConfigService(configService: AppConfigService): Function { return () => { return configService.load() }; } 

Etapa # 4 : Modifique os provedores de módulo para adicionar este provedores: […

  AppConfigService, { provide: APP_INITIALIZER, useFactory: loadConfigService , deps: [AppConfigService], multi: true }, ], 

Passo 5 : No seu código, em vez de usar o ambiente.configXXX, use este

 import {APP_CONFIG} from "../services/app-config.service"; //… return APP_CONFIG.configXXX; 

Este é um exemplo simplificado, você realmente precisará fazer algumas alterações se você usar angular universal, pois você precisa ter URLs absolutos ao fazer uma chamada http

  • Coloque suas configurações em um arquivo ts, na pasta assets
  • assim como você está buscando environment.ts, busque esse arquivo e use suas configurações
  • O conteúdo da pasta de resources não é minimizado, portanto, eles também podem ser configurados na compilation de produção