Implementar configuración dinámica con app.config.js

Lectura
15 min~5 min lectura

Concepto clave

La configuración dinámica en Expo es una técnica avanzada que permite adaptar el comportamiento de tu aplicación en tiempo de compilación según variables de entorno, plataforma o canal de distribución. Imagina que estás construyendo una casa modular: en lugar de tener planos fijos, tienes plantillas que se ajustan según el terreno, clima y necesidades del cliente. De manera similar, app.config.js (en lugar de app.json estático) te permite crear una configuración que cambia dinámicamente.

Esto es crucial en entornos profesionales donde necesitas diferentes configuraciones para desarrollo, staging y producción sin duplicar código. Por ejemplo, podrías cambiar las URLs de API, claves de servicios o configuraciones de Firebase automáticamente según el entorno. La configuración dinámica se ejecuta durante el proceso de prebuild de Expo, generando archivos nativos adaptados.

Cómo funciona en la práctica

El proceso comienza reemplazando tu archivo app.json por app.config.js, que exporta una función que retorna un objeto de configuración. Esta función recibe información del contexto de compilación, como el entorno (development/production) y la plataforma (ios/android).

Paso a paso: 1) Crea app.config.js en la raíz de tu proyecto. 2) Define una función que retorne la configuración. 3) Usa variables como process.env.NODE_ENV para diferenciar entornos. 4) Ejecuta expo prebuild para generar los archivos nativos con la configuración aplicada. 5) Los cambios se reflejan en ios/ y android/ generados.

Código en acción

Aquí tienes un ejemplo básico de app.config.js que configura diferentes nombres de app y esquemas según el entorno:

export default ({ config }) => {
  const isProduction = process.env.NODE_ENV === 'production';
  const appName = isProduction ? 'MiAppProd' : 'MiAppDev';
  const scheme = isProduction ? 'miapp-prod' : 'miapp-dev';

  return {
    ...config,
    name: appName,
    slug: 'mi-app',
    scheme: scheme,
    extra: {
      apiUrl: isProduction ? 'https://api.produccion.com' : 'https://api.desarrollo.com',
      enableAnalytics: isProduction,
      env: process.env.NODE_ENV || 'development'
    },
    ios: {
      ...config.ios,
      bundleIdentifier: isProduction ? 'com.empresa.miapp.prod' : 'com.empresa.miapp.dev'
    },
    android: {
      ...config.android,
      package: isProduction ? 'com.empresa.miapp.prod' : 'com.empresa.miapp.dev'
    }
  };
};

Ahora, un ejemplo más avanzado que maneja múltiples canales (EAS) y usa dotenv para variables sensibles:

import 'dotenv/config';

export default ({ config }) => {
  const easBuildProfile = process.env.EAS_BUILD_PROFILE || 'development';
  const isPreview = easBuildProfile === 'preview';
  const isProduction = easBuildProfile === 'production';

  const getApiUrl = () => {
    switch (easBuildProfile) {
      case 'production':
        return process.env.PROD_API_URL;
      case 'preview':
        return process.env.PREVIEW_API_URL;
      default:
        return process.env.DEV_API_URL;
    }
  };

  return {
    ...config,
    name: isProduction ? 'App Final' : isPreview ? 'App Preview' : 'App Dev',
    extra: {
      eas: {
        projectId: process.env.EAS_PROJECT_ID
      },
      apiUrl: getApiUrl(),
      buildProfile: easBuildProfile
    },
    updates: {
      url: process.env.EXPO_UPDATE_URL
    }
  };
};

Errores comunes

  • No manejar fallbacks para variables de entorno: Si una variable no está definida, tu app podría crashear. Siempre provee valores por defecto, por ejemplo: process.env.API_URL || 'https://default.api'.
  • Confundir tiempo de ejecución con tiempo de compilación: La configuración dinámica se aplica solo al prebuild. Para cambios en caliente, usa expo-updates o almacenamiento local.
  • Exponer secretos en el código: Nunca hardcodees claves API en app.config.js. Usa variables de entorno y asegúrate de que .gitignore excluya archivos .env.
  • No probar todas las variantes: Ejecuta prebuild con diferentes entornos (NODE_ENV=production expo prebuild) para verificar que la configuración se genera correctamente.
  • Ignorar la caché de Metro: Después de cambios en app.config.js, ejecuta expo prebuild --clean para evitar configuraciones obsoletas.

Checklist de dominio

  1. He migrado app.json a app.config.js funcional en un proyecto real.
  2. Puedo explicar la diferencia entre configuración estática y dinámica en Expo.
  3. He implementado al menos dos entornos (dev/prod) con variables distintas.
  4. Sé cómo acceder a la configuración extra desde mi código con Constants.expoConfig?.extra.
  5. He usado dotenv para gestionar variables sensibles de forma segura.
  6. Puedo depurar problemas de configuración revisando los archivos generados en ios/ y android/.
  7. He integrado la configuración dinámica con EAS Build para canales automáticos.

Migrar un proyecto Expo a configuración dinámica con múltiples entornos

En este ejercicio, transformarás un proyecto Expo existente para usar app.config.js con soporte para desarrollo, staging y producción.

  1. Comienza con un proyecto Expo que tenga un app.json básico. Si no tienes uno, crea uno con npx create-expo-app mi-proyecto-dinamico.
  2. Renombra app.json a app.config.js. Convierte el contenido JSON a una función que exporte la configuración. Usa el ejemplo del código en acción como referencia.
  3. Define tres entornos usando NODE_ENV: development, staging, production. Configura:
    • Nombre de la app diferente para cada entorno.
    • URL de API distinta (p.ej., dev.api.com, staging.api.com, prod.api.com).
    • Bundle identifier/package único por entorno.
  4. Añade una sección extra con una flag enableDebugMenu que sea true solo en development.
  5. Instala dotenv (npm install dotenv) y crea un archivo .env con variables para las URLs. Usa .env.example como template y asegúrate de que .gitignore excluya .env.
  6. Ejecuta NODE_ENV=production expo prebuild --clean y verifica que los archivos en ios/ y android/ reflejen la configuración de producción.
  7. En tu código, accede a la configuración extra con import Constants from 'expo-constants'; y usa Constants.expoConfig?.extra para ajustar el comportamiento de la app.
Pistas
  • Usa un switch statement en app.config.js para manejar los entornos de forma limpia.
  • Recuerda que process.env.NODE_ENV puede no estar definido; establece un valor por defecto como 'development'.
  • Para probar rápidamente, puedes simular entornos con cross-env: npx cross-env NODE_ENV=staging expo prebuild.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.