¿Cómo gestiona las variables / constantes de configuración para diferentes entornos?
Este podría ser un ejemplo:
Se puede acceder a mi API de descanso localhost:7080/myapi/
, pero mi amigo que trabaja en el mismo código bajo el control de versión de Git tiene la API implementada en su Tomcat localhost:8099/hisapi/
.
Suponiendo que tenemos algo como esto:
angular
.module('app', ['ngResource'])
.constant('API_END_POINT','<local_end_point>')
.factory('User', function($resource, API_END_POINT) {
return $resource(API_END_POINT + 'user');
});
¿Cómo se inyecta dinámicamente el valor correcto del punto final de la API, según el entorno?
En PHP, generalmente hago este tipo de cosas con un config.username.xml
archivo, fusionando el archivo de configuración básica (config.xml) con el archivo de configuración del entorno local reconocido por el nombre del usuario. ¿Pero no sé cómo administrar este tipo de cosas en JavaScript?
fuente
'ngconstant:development'
en'serve'
- si lo pones en la configuración del reloj bajo'gruntfile'
comotasks: ['ngconstant:development']
- usted no tendrá que reiniciargrunt serve
cuando actualice las variables de desarrollo en el gruntfile.package: grunt.file.readJSON('development.json')
Una solución genial podría ser separar todos los valores específicos del entorno en un módulo angular separado, del que dependen todos los demás módulos:
Luego, los módulos que necesitan esas entradas pueden declarar una dependencia de él:
Ahora puedes pensar en otras cosas interesantes:
El módulo que contiene la configuración se puede separar en configuration.js, que se incluirá en su página.
Cada uno de ustedes puede editar fácilmente este script, siempre que no marque este archivo separado en git. Pero es más fácil no verificar la configuración si está en un archivo separado. Además, puede ramificarlo localmente.
Ahora, si tiene un sistema de compilación, como ANT o Maven, sus pasos adicionales podrían ser implementar algunos marcadores de posición para los valores API_END_POINT, que se reemplazarán durante el tiempo de compilación, con sus valores específicos.
O tiene su
configuration_a.js
yconfiguration_b.js
y decide en el backend qué incluir.fuente
Para los usuarios de Gulp , gulp-ng-constant también es útil combinado con gulp-concat , event-stream e yargs .
En mi carpeta de configuración tengo estos archivos:
Entonces puedes correr
gulp config --env development
y eso creará algo como esto:También tengo esta especificación:
fuente
Para lograr eso, le sugiero que use el complemento de entorno AngularJS: https://www.npmjs.com/package/angular-environment
Aquí hay un ejemplo:
Y luego, puede llamar a las variables desde sus controladores como este:
Espero eso ayude.
fuente
angular-environment
detecta el medio ambiente? es decir, ¿qué necesita hacer en su máquina / servidor web local para que sepa que es dev / prod respectivamente?envServiceProvider.check()
... establecerá automáticamente el entorno apropiado basado en dominios dados". Por lo tanto, creo que detecta el dominio actual y establece el entorno de manera adecuada, ¡es hora de probarlo!Puede usar
lvh.me:9000
para acceder a su aplicación AngularJS (lvh.me
solo apunta a 127.0.0.1) y luego especificar un punto final diferente silvh.me
es el host:Y luego inyecte el servicio de configuración y úselo
Configuration.API
donde necesite acceder a la API:Un poco torpe, pero funciona bien para mí, aunque en una situación ligeramente diferente (los puntos finales de API difieren en producción y desarrollo).
fuente
window.location.host
fue más que suficiente para mí.También podríamos hacer algo como esto.
Y en su
controller/service
, podemos inyectar la dependencia y llamar al método get con propiedad para acceder.$http.get(env.get('apiroot')
devolvería la url en función del entorno del host.fuente
¡Buena pregunta!
Una solución podría ser continuar usando su archivo config.xml y proporcionar información de punto final de API desde el backend a su html generado, como este (ejemplo en php):
Quizás no sea una solución bonita, pero funcionaría.
Otra solución podría ser mantener el
API_END_POINT
valor constante como debería estar en producción, y solo modificar su archivo de hosts para apuntar esa url a su API local.O tal vez una solución que use
localStorage
para anulaciones, como esta:fuente
Muy tarde al hilo, pero una técnica que he usado, pre-angular, es aprovechar JSON y la flexibilidad de JS para hacer referencia dinámica a las claves de recopilación, y usar datos inalienables del entorno (nombre del servidor host, idioma actual del navegador) , etc.) como entradas para discriminar selectivamente / preferir nombres de clave con sufijo dentro de una estructura de datos JSON.
Esto proporciona no solo el contexto del entorno de despliegue (por OP) sino cualquier contexto arbitrario (como el lenguaje) para proporcionar i18n o cualquier otra variación requerida simultáneamente e (idealmente) dentro de un único manifiesto de configuración, sin duplicación, y legible obvio.
EN ACERCA DE 10 LÍNEAS DE VAINILLA JS
Ejemplo demasiado simplificado pero clásico: una URL base de punto final de API en un archivo de propiedades con formato JSON que varía según el entorno donde (natch) el servidor host también variará:
Una clave para la función de discriminación es simplemente el nombre de host del servidor en la solicitud.
Esto, naturalmente, se puede combinar con una clave adicional basada en la configuración de idioma del usuario:
El alcance de la discriminación / preferencia puede limitarse a teclas individuales (como arriba) donde la tecla "base" solo se sobrescribe si hay una tecla coincidente + sufijo para las entradas a la función, o una estructura completa, y esa estructura misma analizado recursivamente para igualar sufijos de discriminación / preferencia:
Por lo tanto, si un usuario visitante del sitio web de producción tiene una configuración de preferencia de idioma ( de ) alemán , la configuración anterior colapsaría para:
¿Cómo es una función de reescritura JSON de preferencia / discriminación mágica? No mucho:
En nuestras implementaciones, que incluyen sitios web angulares y pre-angulares, simplemente arrancamos la configuración muy por delante de otras llamadas de recursos colocando el JSON dentro de un cierre JS autoejecutable, incluida la función prefer (), y alimentamos las propiedades básicas del nombre de host y código de idioma (y acepta cualquier sufijo arbitrario adicional que pueda necesitar):
Un sitio pre-Angular ahora tendría una ventana contraída (sin @ llaves con sufijo) window.app_props para consultar.
Un sitio angular, como un paso de arranque / inicio, simplemente copia el objeto de utilería muerto en $ rootScope y (opcionalmente) lo destruye desde el alcance global / ventana
para ser inyectado posteriormente en los controladores:
o referido desde enlaces en vistas:
Advertencias? El carácter @ no es válido JS / JSON variable / nombre de clave, pero hasta ahora aceptado. Si eso es un factor decisivo, sustituya cualquier convención que desee, como "__" (subrayado doble) siempre y cuando se adhiera a ella.
La técnica podría aplicarse del lado del servidor, portada a Java o C #, pero su eficiencia / compacidad puede variar.
Alternativamente, la función / convención podría ser parte de su script de compilación front-end, de modo que el JSON completo sangriento de todo entorno / lenguaje nunca se transmite por cable.
ACTUALIZAR
Hemos desarrollado el uso de esta técnica para permitir múltiples sufijos a una clave, para evitar ser forzado a usar colecciones (aún puede, tan profundamente como desee), y también para honrar el orden de los sufijos preferidos.
Ejemplo (también vea trabajar jsFiddle ):
1/2 (uso básico) prefiere las teclas '@dev', descarta todas las demás teclas con sufijo
3 prefiere '@dev' sobre '@fr', prefiere '@ dev & fr' sobre todos los demás
4 (igual que 3 pero prefiere '@fr' sobre '@dev')
5 sin sufijos preferidos, elimina TODAS las propiedades con sufijo
Esto se logra al calificar cada propiedad con sufijo y promover el valor de una propiedad con sufijo a la propiedad sin sufijo al iterar sobre las propiedades y encontrar un sufijo con una puntuación más alta.
Algunas eficiencias en esta versión, incluida la eliminación de la dependencia de JSON para copiar en profundidad, y solo recurrir a objetos que sobreviven a la ronda de puntuación en su profundidad:
fuente
Si está utilizando Brunch , el complemento Constangular lo ayuda a administrar variables para diferentes entornos.
fuente
¿Has visto esta pregunta y su respuesta?
Puede establecer un valor globalmente válido para su aplicación como este:
y luego úsalo en tus servicios. Puede mover este código a un archivo config.js y ejecutarlo al cargar la página u otro momento conveniente.
fuente