angular api typescript variables production-environment

Acceder a las variables de entorno en la compilación de producción Angular 4



api typescript (4)

¿Realmente necesitamos APP_INITIALIZER para cargar variables de entorno dinámicas

Bueno, a menos que necesitemos alguna llamada asíncrona para obtenerlos. De lo contrario, sugeriría esto:

env.js

(function (window) { window._env = window._env || {}; window._env.url= ''http://api-url.com''; }());

index.html

<head> <script src="env.js"></script> </head> <body> <app-root></app-root> </body>

Finalmente agrégalo en angular.json

"assets": [ "any/env.js",

Ahora puedes leer la ventana usando un servicio en tu aplicación

Quiero implementar una compilación de producción de una aplicación angular con una API configurable para que el usuario la pruebe. Uso el environment.ts pero después de la compilación de producción, no sé cómo configurar las variables.

¿Qué enfoque hay que hacer?


¿Estás usando Angular-CLI? Debería ser fácil, entonces. Tienes algo como esto:

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

Simplemente ponga una url diferente en environment.prod.ts y su compilación prod obtendrá una segunda url. Por ejemplo, digamos que su environment.ts ve así:

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

Ponga esto en environment.prod.ts :

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

Puede configurar más entornos, verifique esa sección de .angular-cli.json y angular-cli repo.

Editar: según tu comentario, quieres más.

Sí, pero aún así esto no es configurable después de la compilación, ¿no? Como no sé qué url quiere usar el usuario, por lo tanto, quiero que sea configurable desde el exterior después de implementar la compilación.

Continuemos este escenario aún más. Tengamos un cliente de 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<any> { const url= `${this.backendUrl}/${endpoint}`; return this.httpClient.get(url, params); } }

Simplificado, pero funciona. Por defecto, configura su propia URL. Pero sus componentes pueden configurar la url sobre la marcha y obtener otras cosas de esa url.

Ahora, el siguiente paso sería ofrecer los backends que tiene. Esto puede ser una matriz preconfigurada, o puede dejar que el cliente ingrese la url libremente (simplemente cuadro de entrada). Puede tener un componente que haga eso y configure este servicio aquí. Probablemente también debería tener un servicio separado para su backend "adecuado", donde, por ejemplo, se encuentra su autenticación. Pero todo esto realmente depende de su escenario.


El archivo de entorno * .ts contiene configuraciones de tiempo de compilación, que no puede cambiar después de la compilación. Si necesita cambiar su configuración después de la compilación, debe colocarlos en un lugar diferente y recuperarlos dinámicamente cuando se inicia la aplicación

Lo que puedes hacer es:

Paso # 1 : coloque sus archivos de configuración json en src / assets / config / [envName] .json.

Nota: tiene que ser formato json, no formato ts

Paso # 2 : agrega un nuevo servicio de configuración

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); }); }); } }

Paso # 3 : en su módulo principal, agregue esto antes de declarar el 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() }; }

Paso # 4 : Modifique los proveedores de módulos para agregar estos proveedores: [...

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

Paso 5 : en su código, en lugar de usar environment.configXXX, use esto

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

Este es un ejemplo simplificado, en realidad necesitará hacer algunos cambios si usa angular universal ya que necesita tener URL absolutas al hacer una llamada http


  • Ponga sus configuraciones en un archivo ts, en la carpeta de activos
  • al igual que estás obteniendo environment.ts, busca ese archivo y usa sus configuraciones
  • El contenido de la carpeta de activos no se minimiza, por lo que también se pueden configurar en la compilación de producción