Tengo curiosidad por saber cuál es la forma más moderna, a partir de abril de 2017, de crear una aplicación Angular 2 para implementar con configuración externa.
Siguiendo la filosofía Build Once Deploy Anywhere, me gustaría descubrir cómo empaquetar mi aplicación Angular 2 como una imagen de Docker que puedo colocar en cualquier servidor y configurar desde afuera.
He hecho esto bastante simple con la mayoría de los otros componentes de esta aplicación, incluido un backend Spring Boot, pero la mejor manera de hacer esto con Angular 2 es difícil de precisar ya que el marco evolucionó tan masivamente entre las versiones beta que mucha información es fuera de plazo.
Tengo Angular 2.4.9 con NPM para la administración de paquetes que se ejecuta en un contenedor Node Docker como una aplicación JIT con un entorno específico integrado en la imagen en el momento de la compilación. Me gustaría obtener las ventajas de tamaño y velocidad de la compilación de AoT, así como la eventual minimización y otras mejoras en el tamaño de descarga, pero AoT hornea el contenido de un archivo environment.ts directamente en main.bundle.js, por lo que no hay forma de cámbialo después de ng build
El proyecto Angular2-webpack-starter parece muy desactualizado y es mutuamente excluyente con Angular-CLI de todos modos, pero aquí tiene este método que parece configurar archivos config/webpack.ENV.js que se refieren a las variables de entorno del sistema operativo. Siento que las variables de entorno son demasiado complicadas para muchas aplicaciones, pero es mejor que nada. Pero, ¿cómo puedo aplicar esto en términos de Angular-CLI, o hay una mejor manera?
Según tengo entendido, Angular-CLI abstrae el paquete web demasiado para acceder directamente al paquete web y las configuraciones del complemento para seguir este enfoque. Pero, ¿podría simplemente hacer referencia a process.env en mi environment.ts y Bob es tu tío o es más complicado que eso?
¿Necesito abrir main.bundle.js y reescribir los bits entre var environment = {
y //# sourceMappingURL=environment.js.map
? Eso parece innecesariamente raro para algo tan popular como Angular.
Si realmente debe compilar una vez e implementar el mismo artefacto de compilación varias veces, entonces una solución (aunque en mi opinión es un truco) es colocar su configuración externa dentro de la carpeta 'activos' y luego hacer una llamada ajax desde environment.ts a leer los valores:
src/entornos/entorno.ts:
export const environment = new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); xhr.open('GET', './assets/environment.json'); xhr.onload = function () { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject("Cannot load configuration..."); } }; xhr.send(); });
src/activos/entorno.json:
{ "production": false, "some_api_url": "https://dev_url" }
También debe posponer el arranque del módulo hasta que se complete la llamada ajax:
src/principal.ts:
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment as environmentPromise } from './environments/environment'; environmentPromise.then(environment => { if (environment["production"]) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule); });
Ejemplo de trabajo aquí: https://github.com/mehradoo/angular-external-cfg/commit/0dd6122a0d8ff100c23458807cc379e9e24cc439