Perfiles de compilación y sabores
Desarrollo, vista previa, producción y variantes de etiqueta blanca - la guía para estructurar perfiles de eas.json y app.config.ts dinámico en Expo SDK 57.
Busca en todas las páginas de la documentación
Desarrollo, vista previa, producción y variantes de etiqueta blanca - la guía para estructurar perfiles de eas.json y app.config.ts dinámico en Expo SDK 57.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
// eas.json - línea base de tres entornos
{
"cli": { "version": ">= 16.0.0", "appVersionSource": "remote" },
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"environment": "development",
"channel": "development"
},
"preview": {
"distribution": "internal",
"environment": "preview",
"channel": "preview"
},
"production": {
"distribution": "store",
"environment": "production",
"channel": "production",
"autoIncrement": true
}
}
}// app.config.ts - APP_VARIANT del entorno de eas.json
import type { ExpoConfig } from "expo/config";
const variant = process.env.APP_VARIANT ?? "production";
const bundleIds: Record<string, string> = {
development: "com.example.shopapp.dev",
preview: "com.example.shopapp.staging",
production: "com.example.shopapp",
};
const config: ExpoConfig = {
name: variant === "production" ? "Shop" : `Shop (${variant})`,
slug: "shop-app",
ios: { bundleIdentifier: bundleIds[variant] },
android: { package: bundleIds[variant] },
extra: {
apiUrl: process.env.EXPO_PUBLIC_API_URL,
eas: { projectId: "00000000-0000-0000-0000-000000000000" },
},
};
export default config;// eas.json - pasar variante al prebuild
{
"build": {
"preview": {
"env": { "APP_VARIANT": "preview" },
"environment": "preview"
}
}
}Cuándo usar esto:
Paso 1 - Definir responsabilidades del perfil
| Perfil | Público | Distribución | Binario típico |
|---|---|---|---|
| development | Ingenieros | internal | Cliente de desarrollo + simulador/APK |
| preview | Control de calidad / partes interesadas | internal | IPA/APK con forma de lanzamiento |
| production | Usuarios finales | store | AAB + App Store IPA |
eas build --profile development --platform all
eas build --profile preview --platform ios
eas build --profile production --platform androidPaso 2 - Vincular entornos de EAS
Crea variables en el panel de control de Expo → Project → Environment variables:
development EXPO_PUBLIC_API_URL=https://api.dev.example.com
preview EXPO_PUBLIC_API_URL=https://api.staging.example.com
production EXPO_PUBLIC_API_URL=https://api.example.com{
"build": {
"preview": { "environment": "preview" }
}
}environment extrae variables de EAS - no del .env.local del portátileas update --environment production debe coincidir con el perfil de producción - Reglas de lanzamiento y OTAPaso 3 - Etiqueta blanca con app.config.ts
// app.config.ts - multi-marca desde env BRAND
type Brand = "acme" | "contoso";
const brand = (process.env.BRAND ?? "acme") as Brand;
const brands: Record<Brand, { name: string; bundleId: string; icon: string }> = {
acme: {
name: "Acme Shop",
bundleId: "com.acme.shop",
icon: "./brands/acme/icon.png",
},
contoso: {
name: "Contoso Market",
bundleId: "com.contoso.market",
icon: "./brands/contoso/icon.png",
},
};
const config: ExpoConfig = {
name: brands[brand].name,
slug: `shop-${brand}`,
icon: brands[brand].icon,
ios: { bundleIdentifier: brands[brand].bundleId },
android: {
package: brands[brand].bundleId,
adaptiveIcon: { foregroundImage: brands[brand].icon, backgroundColor: "#fff" },
},
};
export default config;// eas.json - un perfil por marca para producción
{
"build": {
"production-acme": {
"extends": "production",
"env": { "BRAND": "acme" },
"environment": "production-acme"
},
"production-contoso": {
"extends": "production",
"env": { "BRAND": "contoso" },
"environment": "production-contoso"
}
}
}eas build --profile production-acme --platform all
eas build --profile production-contoso --platform allprojectId separado o un aislamiento cuidadoso de canales por ID de paquetebundleIdentifier / packageComparte configuración entre perfiles:
{
"build": {
"base": {
"node": "22.11.0",
"resourceClass": "medium"
},
"development": {
"extends": "base",
"developmentClient": true,
"distribution": "internal"
},
"production": {
"extends": "base",
"distribution": "store",
"autoIncrement": true
},
"production-ios-simulator": {
"extends": "production",
"ios": { "simulator": true },
"distribution": "internal"
}
}
}extends fusiona claves padre - las anulaciones secundarias gananExpo CNG generalmente usa un applicationId de Gradle por prebuild impulsado por app.config.ts:
eas.json profile → APP_VARIANT env → app.config.ts → applicationIdLos sabores de producto de Android nativo en build.gradle son posibles en proyectos brownfield pero entran en conflicto con la regeneración de CNG. Prefiere:
app.config.ts dinámico para ID de paquete, nombre e iconosConsulta Conceptos básicos de Prebuild - los sabores de producto de android/app/build.gradle editados a mano se pierden en prebuild limpio.
// app.config.ts
runtimeVersion: {
policy: "fingerprint",
},
updates: {
url: "https://u.expo.dev/<project-id>",
},{
"build": {
"preview": { "channel": "preview" },
"production": { "channel": "production" }
}
}eas update --channel preview --environment preview --message "QA fix"
eas update --channel production --environment production --message "Hotfix"eas updatebundleIdentifier / package difieren - usa sufijos APP_VARIANT como .dev y .staging.extends cuando sea necesario."jane-debug") - usa entornos y canales en su lugar.BRAND + credenciales separadas por nombre de paquete.Versiones de pila: Esta página fue escrita para React 19.2.3, React Native 0.86.0 y Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última actualización: 19 jul 2026