Loops locales de expo run:ios / expo run:android y la decisión de cuándo hacer commit de ios/ y android/ en un flujo de trabajo de Generación Nativa Continua. El código nativo personalizado pertenece a modules/, plugins de configuración y EAS Build - no a ediciones silenciosas de Xcode que desaparecen en prebuild limpio.
# Andamio de un módulo Expo local (preferido sobre código de bridge crudo)npx create-expo-module@latest expo-device-info-plus# Mueve a modules/ si el CLI creó una carpeta hermana
CustomNative/├── app.config.ts├── modules/│ └── expo-device-info-plus/ # Hacer commit esto - fuente de verdad├── plugins/ # Hacer commit plugins de configuración personalizados├── ios/ # Gitignore bajo CNG└── android/ # Gitignore bajo CNG
// App.tsximport * as DeviceInfoPlus from "expo-device-info-plus";import { useEffect, useState } from "react";import { Text, View } from "react-native";export default function App() { const [model, setModel] = useState<string>("…"); useEffect(() => { DeviceInfoPlus.getModelAsync().then(setModel); }, []); return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <Text>Modelo de dispositivo: {model}</Text> </View> );}
# Primera compilación nativa en un clon fresconpm installnpx expo run:ios# Después de cambiar Swift/Kotlin en modules/npx expo run:ios --no-build-cache
Lo que esto demuestra:
modules/ se hace commit - el código fuente nativo sobrevive prebuild limpio
ios//android/ se generan - recreados desde config + autovínculo en cada prebuild
expo run:ios orquesta prebuild - pod install - compilación de Xcode
Los cambios de módulos requieren recompilación - Fast Refresh de Metro no recarga código nativo
npx expo prebuild --no-install# Verificar que Podfile contiene script de autovínculo de Expo# Verificar que android/settings.gradle incluye useExpoModules()
El autovínculo faltante se manifiesta como módulo nativo indefinido en tiempo de ejecución - no un error de Metro.
# 1. Inventariar diffs de Xcode/Gradle vs prebuild frescorm -rf ios androidnpx expo prebuild --no-installgit diff # contra ios/ comprometido anteriormente# 2. Transportar cada trozo de diff a un plugin de configuración o cambio de modules/# 3. Compuerta final: prebuild limpio coincide con comportamientorm -rf ios android && npx expo prebuild
Editar AppDelegate generado sin un plugin - Perdido en SDK 57 prebuild limpio. Solución: plugin expo-dev-client o plugin de configuración personalizado.
Esperando que Expo Go cargue módulos personalizados - El binario de Expo Go es fijo. Solución: Cliente dev mediante expo run:ios o compilación de desarrollo EAS.
Olvidar reconstruir después del cambio de Swift - Metro Fast Refresh solo actualiza JS. Solución: Volver a ejecutar expo run:ios.
Dos copias de react-native en monorepo - El autovínculo elige la instancia incorrecta. Solución:npx expo-doctor, único react-native hoisted.
Hacer commit de ios/Pods/ - Inflado masivo de repo y conflictos de fusión. Solución: Gitignore Pods; pod install en CI/EAS.
Mezclar CNG y Gradle editado manualmente - Prebuild sobrescribe ediciones sin codificar. Solución:expo-build-properties o plugin personalizado.
Si falta ios/, sí. Si ios/ existe, usa el proyecto existente - que puede estar obsoleto. Después de cambios de plugins de configuración, ejecuta npx expo prebuild o elimina ios/ primero.
¿Dónde debe vivir el código Swift personalizado?
En modules/<module-name>/ios/ como un módulo Expo - el autovínculo lo cablerea en prebuild. Evita editar ios/MyApp/ generado directamente bajo CNG.
¿Puedo usar Xcode para depurar y luego mover cambios a un plugin?
Sí - ruta común de migración brownfield. Usa expo prebuild --no-clean mientras iteras, luego verifica que prebuild limpio reproduce el comportamiento.
¿Cómo encajan las bibliotecas nativas de terceros en CNG?