Introduction
Un lab local est un espace de travail sûr et reproductible pour le développement Expo où vous pouvez tester, dépanner et apprendre sans risquer de compromettre votre travail de production. Dans ce guide, vous allez :
- Installer et verrouiller la chaîne d'outils principale pour le développement Expo.
- Créer un espace de travail dédié pour des expériences propres et isolées.
- Ajouter des scripts reproductibles pour des exécutions cohérentes sur toutes les machines.
- Construire un petit pilote mesurable que vous pouvez inspecter localement.
Pourquoi c'est important :
- Boucle d'apprentissage plus rapide : portée réduite, retour plus rapide.
- Risque moindre : isoler les changements des applications et dépôts principaux.
- Répétabilité : les scripts et versions verrouillées réduisent la dérive.
Vue d'Ensemble du Flux de Travail
Le flux ci-dessous sépare la configuration des expériences et rend chaque résultat facile à inspecter localement.
0) Objectifs et Garde-fous
- Définir ce que vous allez apprendre ou valider (par exemple, démarrage de l'émulateur Android avec une FlatList alimentée par une API mock locale).
- Définir des critères de succès observables localement (par exemple, l'application atteint le premier rendu en moins de 10 s sur l'émulateur Android ; la liste affiche 3 éléments depuis
http://10.0.2.2:4000/itemsavec untimeToDataMssous 500 ms).
1) Prérequis
- Node.js LTS (par exemple, 18.x ou 20.x). Le verrouiller avec nvm ou asdf.
- Git
- Java JDK 17 (requis pour les builds Gradle Android)
- Android Studio avec SDKs et un AVD configuré (API 34 recommandée)
- Xcode pour le simulateur iOS (macOS uniquement)
- Un appareil physique (optionnel mais utile pour les tests LAN)
Vérifier les bases :
node -v
java -version
adb --version || echo "ADB pas encore dans le PATH"
2) Créer l'Espace de Travail du Lab
Utilisez un seul répertoire pour garder les expériences organisées et versionnées.
mkdir expo-lab && cd expo-lab
git init -b main
echo "18.19.0" > .nvmrc
Ajouts recommandés au .gitignore :
node_modules/
.expo/
.expo-shared/
.DS_Store
android/
ios/
.expo/*
3) Initialiser les Applications de Référence
Créez deux applications minimales : une gérée, une prête pour un client de développement.
# Exemple workflow géré
npx create-expo-app demo-managed --template blank
# Exemple prêt pour dev-client (on ajoutera expo-dev-client plus tard)
npx create-expo-app demo-dev-client --template blank
4) Boucle Rapide pour l'App Gérée
cd demo-managed
npm install
npm start # ou : npx expo start
- Appuyez sur
apour lancer l'émulateur Android,ipour lancer le simulateur iOS (macOS), ou scannez le code QR avec un appareil physique exécutant Expo Go. - Confirmez que l'application se charge et que le rechargement à chaud des changements d'UI fonctionne.
Ajoutez des scripts de base au package.json pour la reproductibilité :
{
"scripts": {
"lab:start": "expo start",
"lab:android": "expo start --android",
"lab:ios": "expo start --ios",
"lab:clean": "rimraf node_modules .expo && npm install",
"lab:doctor": "expo doctor",
"lab:inspect:deps": "npm ls --depth=0 || true"
}
}
Installez rimraf si vous utilisez le script de nettoyage sur Windows :
npm install --save-dev rimraf
5) Matrice d'Appareils
Visez à valider sur trois cibles dès le début :
- Émulateur Android (AVD, API 34)
- Simulateur iOS (macOS, iPhone 15 Pro)
- Appareil physique avec Expo Go sur le même LAN
Cela fait ressortir les problèmes spécifiques à l'environnement (résolution d'hôte réseau, connectivité au bundler Metro, disponibilité des modules natifs) alors que les changements sont encore minimes.
6) Journalisation, Métriques et Captures d'Écran
- Utilisez
console.logavec des étiquettes claires, par exemple :[LAB] mount,[LAB] fetch ok,[LAB] error: .... - Capturez un horodatage au démarrage de l'application et après le premier rendu de données pour estimer le temps de démarrage à froid.
- Gardez un dossier
screenshots/dans le dépôt pour les preuves avant/après.
7) API Mock Locale
Une API mock locale rend les expériences déterministes et indépendantes du réseau.
# Depuis la racine expo-lab
npm install --save-dev json-server
# Créer un fichier de données
cat > db.json <<'JSON'
{
"items": [
{ "id": 1, "name": "Alpha" },
{ "id": 2, "name": "Bravo" },
{ "id": 3, "name": "Charlie" }
]
}
JSON
# Lancer le serveur sur le port 4000
npx json-server --watch db.json --port 4000
Astuces pour l'hôte réseau :
- Simulateur iOS :
http://localhost:4000fonctionne. - Émulateur Android : utilisez
http://10.0.2.2:4000(10.0.2.2 correspond au localhost de l'hôte). - Appareil physique : utilisez l'IP LAN de votre machine, ex.
http://192.168.1.50:4000(exécutezifconfig | grep "inet " | grep -v 127.0.0.1pour la trouver).
8) Écran Exemple avec Feature Flag
Dans demo-managed, créez une liste simple avec un feature flag pour basculer le tri.
cd demo-managed
npm install react-native-safe-area-context
App.js :
import React, { useEffect, useState, useMemo } from 'react';
import { Platform } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { View, Text, FlatList, Switch, StyleSheet } from 'react-native';
const HOST_ANDROID = 'http://10.0.2.2:4000';
const HOST_IOS_OR_SIM = 'http://localhost:4000';
function hostForPlatform() {
const isAndroid = Platform.OS === 'android';
return isAndroid ? HOST_ANDROID : HOST_IOS_OR_SIM;
}
export default function App() {
const [items, setItems] = useState([]);
const [sortAsc, setSortAsc] = useState(true);
const [startedAt] = useState(Date.now());
useEffect(() => {
const url = `${hostForPlatform()}/items`;
console.log('[LAB] fetching', url);
fetch(url)
.then(r => r.json())
.then(json => {
console.log('[LAB] fetch ok, count=', json.length);
setItems(json);
console.log('[LAB] timeToDataMs=', Date.now() - startedAt);
})
.catch(e => console.log('[LAB] fetch error', e));
}, [startedAt]);
const data = useMemo(() => {
const copy = [...items];
copy.sort((a, b) => sortAsc
? a.name.localeCompare(b.name)
: b.name.localeCompare(a.name));
return copy;
}, [items, sortAsc]);
return (
<SafeAreaView style={styles.root}>
<View style={styles.row}>
<Text style={styles.title}>Expo Lab List</Text>
<View style={styles.switchRow}>
<Text>Trier A-Z</Text>
<Switch value={sortAsc} onValueChange={setSortAsc} />
</View>
</View>
<FlatList
data={data}
keyExtractor={item => String(item.id)}
renderItem={({ item }) => (
<View style={styles.card}><Text>{item.name}</Text></View>
)}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
root: { flex: 1, padding: 16, backgroundColor: '#fff' },
row: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
switchRow: { flexDirection: 'row', alignItems: 'center', gap: 8 },
title: { fontSize: 20, fontWeight: '600' },
card: { padding: 12, marginVertical: 6, borderWidth: 1, borderColor: '#ddd', borderRadius: 8 }
});
Lancez-le :
npm run lab:android # ou : npm run lab:ios
Vérifiez les étiquettes de console pour timeToDataMs et confirmez que la liste bascule comme prévu.
9) Optionnel : Build de Développement pour Modules Natifs
Si vous avez besoin de modules natifs non disponibles dans Expo Go, créez un build de développement localement.
cd ../demo-dev-client
npm install
npm install expo-dev-client
npx expo prebuild
# Build et installation sur Android
echo "sdk.dir=$HOME/Library/Android/sdk" >> android/local.properties || true
./android/gradlew -p android assembleDebug
npx expo run:android
# Pour iOS (macOS)
# npx expo run:ios
Gardez le chemin dev-client séparé des expériences gérées quotidiennes pour éviter le churn.
10) Checklist de Reproductibilité et Scripts
Ajoutez un Makefile simple ou des scripts npm pour standardiser la boucle. Exemple de Makefile :
.PHONY: start android ios mock clean doctor
start:
cd demo-managed && npm run lab:start
android:
cd demo-managed && npm run lab:android
ios:
cd demo-managed && npm run lab:ios
mock:
npx json-server --watch db.json --port 4000
clean:
cd demo-managed && npm run lab:clean
doctor:
cd demo-managed && npm run lab:doctor
Une session typique :
make mock # terminal 1 : API locale
make android # terminal 2 : lancer l'app sur l'émulateur Android
# Modifier le code, observer les logs, capturer les captures d'écran
11) Mapper vers GitLab CI/CD Localement
Quand vous êtes prêt à miroir des parties de votre lab dans GitLab CI/CD, gardez ce qui suit cohérent avec les exécutions locales :
- Verrouillez les versions de Node et Java dans
.gitlab-ci.yml(correspondre à.nvmrcet JDK 17). - Assurez-vous que les outils Android SDK sont présents dans l'image du runner (utilisez l'image Docker
android-sdkou installez viasdkmanager). - Réutilisez vos scripts de lab pour l'installation, le lint, le build et les tests.
Plus vos scripts locaux sont proches de vos étapes de runner, moins vous aurez de retravailler plus tard.
Plan de Pilote Local
Commencez petit et mesurable pour pouvoir inspecter les résultats localement avant d'élargir la portée.
Objectif du Pilote
- Afficher une liste depuis une API mock locale dans une app Expo gérée.
- Basculer l'ordre de tri avec un feature flag.
- Valider sur émulateur Android, simulateur iOS et appareil physique.
Critères de Succès
- L'application se lance jusqu'au premier rendu en moins de 10 secondes sur l'émulateur Android (API 34, démarrage à froid).
timeToDataMsconstamment sous 500 ms avec l'API mock locale.- Aucune erreur non gérée dans la console pendant l'opération normale.
- Captures d'écran sauvegardées dans
screenshots/sur chaque cible.
Plan
- Environnement
- Confirmer Node LTS et Java 17.
- Créer et démarrer un AVD Android (API 34), confirmer le simulateur Xcode si sur macOS.
- Application
- Initialiser
demo-managedet ajouter l'écran exemple ci-dessus. - Ajouter les scripts :
lab:start,lab:android,lab:ios,lab:doctor.
- API Mock
- Lancer
json-serversur le port 4000. - Vérifier la sélection d'hôte pour chaque cible (
localhostvs10.0.2.2vs IP LAN).
- Exécution et Mesure
- Lancer sur l'émulateur Android, observer
timeToDataMs. - Lancer sur le simulateur iOS, capturer une capture d'écran.
- Lancer sur l'appareil avec Expo Go en utilisant l'IP LAN.
- Documenter et Stabiliser
- Enregistrer les versions de Node, npm,
json-serverdansREADME.md. - Sauvegarder les commandes et timings utilisés pour reproduire les résultats.
Extensions (Après Succès)
- Ajouter un second écran qui écrit dans
AsyncStorageet relit. - Introduire un test de base avec Jest et React Native Testing Library.
- Créer un build de développement dans
demo-dev-clientsi vous avez besoin de modules natifs.
Conclusion
Vous disposez maintenant d'un lab Expo local pratique et d'un premier pilote qui prouve la boucle de bout en bout. La clé est la clarté : séparer la configuration des expériences, garder le premier pilote étroit et mesurable, et codifier tout avec des scripts pour que les exécutions soient reproductibles.
Prochaines Étapes Immédiates
- Verrouiller les versions (
.nvmrc, Java 17) et documenter les prérequis. - Commiter vos scripts de lab et un
README.mdcourt avec la checklist de repro. - Capturer les métriques de base et captures d'écran dans le contrôle de version.
- Partager le template de lab avec votre équipe et l'étendre incrémentalement.
En gardant la portée serrée et les étapes scriptées, votre lab Expo restera rapide, sûr et facile à faire évoluer.