Node.js y ExpressTesting y ProducciónLección 17 de 20
Variables de Entorno y Config
Las variables de entorno separan la configuración sensible del código fuente. Tu código de base de datos, claves de API y secretos JWT no deben estar hardcodeados ni subirse a GitHub. El archivo .env guarda estos valores localmente y dotenv los carga en process.env al iniciar la app. Siempre agrega .env a .gitignore.
En producción (Heroku, Railway, Render, AWS) las variables de entorno se configuran directamente en el panel de la plataforma, no con archivos .env. Esto garantiza que los secretos nunca estén en el repositorio. Un archivo .env.example con los nombres de las variables (sin valores) sirve como documentación para el equipo.
// npm install dotenv zod
// .env (NUNCA commitear)
// DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
// JWT_SECRET=mi-super-secreto-largo-y-aleatorio
// PORT=3000
// NODE_ENV=development
// src/config/env.js — carga y valida variables de entorno
const { z } = require('zod');
// Cargar .env solo en desarrollo (en producción ya están en el proceso)
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config();
}
// Schema de validación de env vars
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url('DATABASE_URL debe ser una URL válida'),
JWT_SECRET: z.string().min(32, 'JWT_SECRET debe tener al menos 32 caracteres'),
JWT_REFRESH_SECRET: z.string().min(32),
CORS_ORIGIN: z.string().default('http://localhost:3000'),
MAX_FILE_SIZE_MB: z.coerce.number().default(5),
});
// Validar al inicio — si falta algo, el app no arranca
const resultado = envSchema.safeParse(process.env);
if (!resultado.success) {
console.error('❌ Variables de entorno inválidas:');
resultado.error.issues.forEach(issue => {
console.error(` ${issue.path.join('.')}:${issue.message}`);
});
process.exit(1); // no arrancar con config rota
}
const env = resultado.data;
// Config por ambiente
const config = {
isProd: env.NODE_ENV === 'production',
isDev: env.NODE_ENV === 'development',
port: env.PORT,
db: { url: env.DATABASE_URL },
jwt: { secret: env.JWT_SECRET, refreshSecret: env.JWT_REFRESH_SECRET },
cors: { origin: env.CORS_ORIGIN },
upload: { maxSizeMB: env.MAX_FILE_SIZE_MB },
};
module.exports = config;
ConsejoValida las variables de entorno al INICIAR la app, no cuando las usas. Si falta JWT_SECRET, es mejor que la app no arranque que descubrirlo cuando alguien intente hacer login en producción.
Practica esta lección
Resuelve los ejercicios del curso de Node.js y Express en la app, gratis y con corrección automática.
Empezar a practicar