Descripción General
Este proyecto utiliza la librería @ngx-env/builder para manejar variables de entorno de manera segura y eficiente en aplicaciones Angular. Este enfoque permite inyectar variables de entorno durante el proceso de build, manteniendo la seguridad y flexibilidad necesarias para diferentes entornos.
Arquitectura del Sistema
1. Dependencias Principales
El proyecto utiliza las siguientes dependencias clave:
para instalar npm i @ngx-env/builder
{ "dependencies": { "@ngx-env/builder": "^20.1.1" } } 2. Configuración del Builder
En angular.json, el proyecto está configurado para usar el builder personalizado de @ngx-env:
{ "architect": { "build": { "builder": "@ngx-env/builder:application", "options": { "browser": "src/main.ts", "tsConfig": "tsconfig.app.json" } }, "serve": { "builder": "@ngx-env/builder:dev-server" } } } Proceso de Configuración Paso a Paso
Paso 1: Definir Variables de Entorno
1.1 Crear archivo .env
Puedes crear un archivo .env en la raíz del proyecto:
# .env NG_APP_ANGULAR_VALUE=Mi valor de desarrollo NG_APP_API_URL=https://api-dev.ejemplo.com NG_APP_VERSION=1.0.0 Paso 2: Definir Tipos TypeScript
En src/env.d.ts, define las interfaces para tus variables de entorno:
declare interface Env { readonly NODE_ENV: string; readonly NG_APP_ANGULAR_VALUE: string; readonly NG_APP_API_URL: string; readonly NG_APP_VERSION: string; [key: string]: any; } // Usar _NGX_ENV_ (personalizable) declare const _NGX_ENV_: Env; Paso 3: Configurar Archivos de Entorno
3.1 Archivo de Desarrollo (src/environment/environment.ts)
export const environment = { production: false, mensaje: _NGX_ENV_.NG_APP_ANGULAR_VALUE, apiUrl: _NGX_ENV_.NG_APP_API_URL, version: _NGX_ENV_.NG_APP_VERSION, }; 3.2 Archivo de Producción (src/environment/environment.prod.ts)
export const environment = { production: true, mensaje: _NGX_ENV_.NG_APP_ANGULAR_VALUE, apiUrl: _NGX_ENV_.NG_APP_API_URL, version: _NGX_ENV_.NG_APP_VERSION, }; Paso 4: Usar Variables en el Código
Tutorial para el paso 4 tambien util
4.1 Importar el entorno
import { environment } from './environment/environment'; export class MiComponente { constructor() { console.log('Mensaje:', environment.mensaje); console.log('API URL:', environment.apiUrl); console.log('Versión:', environment.version); } } Convenciones de Nomenclatura
Variables de Entorno
- Prefijo obligatorio: Todas las variables deben comenzar con
NG_APP_ - Ejemplos válidos:
NG_APP_API_URLNG_APP_VERSIONNG_APP_DEBUG_MODE
Variables del Sistema
-
NODE_ENV: Se configura automáticamente -
NG_APP_*: Variables personalizadas de la aplicación
Comandos de Build y Desarrollo
my-angular-app └── src └── environments ├── environment.ts ├── environment.development.ts ├── environment.pilot.ts └── environment.production.ts Ahora tendras que modificar el angular.json
"configurations": { "production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true }, "development": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.development.ts" } ], "optimization": false, "sourceMap": false, "extractCss": true, "namedChunks": false } }, "pilot": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.staging.ts" } ], "optimization": true, "outputHashing": "all", "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true }, "development": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.development.ts" } ], "optimization": false, "sourceMap": false, "extractCss": true, "namedChunks": false } } En el mismo archivo angular.json tendras que modificar el serve
"serve": { "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { "buildTarget": "my-angular-app:build:production" }, "development": { "buildTarget": "my-angular-app:build:development" }, "pilot": { "buildTarget": "my-angular-app:build:pilot" }, }, "defaultConfiguration": "development" }, Luego tendras que agregar los comandos personalizados package.json
{ "name": "my-angular-app", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", "start:dev": "ng serve --configuration=development", "start:pilot": "ng serve --configuration=pilot", "start:prod": "ng serve --configuration=production", "build:dev": "ng build --configuration=development", "build:pilot": "ng build --configuration=pilot", "build:prod": "ng build --configuration=production" }, "private": true, "dependencies": { ... }, "devDependencies": { ... } } ⚠️ Limitaciones Importantes
Variables Secretas - NO RECOMENDADO
Este enfoque NO es seguro para variables secretas por las siguientes razones:
1. Exposición en el Cliente
- Las variables se inyectan en tiempo de build
- Se incluyen en el bundle JavaScript final
- Son visibles para cualquier usuario que inspeccione el código
2. Acceso Público
// ❌ NUNCA hagas esto con secretos export const environment = { apiKey: _NGX_ENV_.NG_APP_SECRET_KEY, // ¡VISIBLE EN EL CLIENTE! }; 3. Alternativas Seguras para Secretos
Para variables secretas, usa:
- Backend Proxy: El frontend solicita datos al backend, que maneja los secretos
- API Keys Públicas: Solo para APIs que requieren keys públicas
- Autenticación JWT: Tokens temporales generados por el backend
- Variables de Servidor: Configurar en el servidor web (nginx, Apache)
Ejemplo de Implementación Segura:
// ❌ Incorrecto - secreto en el frontend const secretKey = _NGX_ENV_.NG_APP_SECRET_KEY; // ✅ Correcto - solicitar al backend this.http.get('/api/data').subscribe(data => { // El backend maneja los secretos }); Casos de Uso Apropiados
✅ Variables Seguras para el Cliente
- URLs de APIs públicas
- Configuraciones de UI
- Versiones de aplicación
- Flags de características
- Configuraciones de entorno (dev/staging/prod)
❌ Variables que NO deben usarse
- API keys secretas
- Tokens de autenticación
- Credenciales de base de datos
- Claves de encriptación
- Cualquier información sensible
Mejores Prácticas
- Prefijo consistente: Siempre usa
NG_APP_ - Tipado fuerte: Define interfaces en
env.d.ts - Valores por defecto: Proporciona fallbacks cuando sea posible
- Documentación: Documenta todas las variables requeridas
- Validación: Valida variables críticas en tiempo de ejecución
Ejemplo Completo
Estructura de archivos:
src/ ├── env.d.ts ├── environment/ │ ├── environment.ts │ └── environment.prod.ts └── app/ └── mi-componente.ts Configuración completa:
// env.d.ts declare interface Env { readonly NG_APP_API_URL: string; readonly NG_APP_VERSION: string; readonly NG_APP_DEBUG: string; } declare const _NGX_ENV_: Env; // environment.ts export const environment = { production: false, apiUrl: _NGX_ENV_.NG_APP_API_URL || 'http://localhost:3000', version: _NGX_ENV_.NG_APP_VERSION || '1.0.0', debug: _NGX_ENV_.NG_APP_DEBUG === 'true', }; Este enfoque proporciona una solución robusta y segura para manejar variables de entorno en aplicaciones Angular, manteniendo la separación entre configuraciones públicas y secretos sensibles.
Top comments (0)