Introduction
Un lab local est un espace sûr et reproductible pour l'Expo development, où vous pouvez tester, dépanner et apprendre sans risquer d'impacter vos applications de production. Dans ce guide, vous allez :
- Installer et épingler la toolchain essentielle à l'Expo setup.
- Créer un workspace dédié pour des expériences propres et isolées.
- Ajouter des scripts reproductibles pour des exécutions cohérentes sur plusieurs machines.
- Construire un petit pilote mesurable et inspectable localement.
Pourquoi c'est important :
- Boucle d'apprentissage plus rapide : périmètre réduit, feedback immédiat.
- Moins de risques : les changements sont isolés des apps et dépôts principaux.
- Répétabilité : des versions fixées et des scripts stables limitent la dérive.
Vue d'ensemble du workflow
Le workflow ci-dessous réduit les ré-implémentations inutiles en séparant l'étape de setup des expériences, et en rendant chaque résultat facile à valider localement.
0) Objectifs et garde-fous
- Énoncez ce que vous cherchez à apprendre ou valider (ex. : configuration d'un Android emulator et rendu de liste depuis une API mock).
- Définissez des critères de succès observables en local (ex. : l'app démarre en moins de 10 s sur l'émulateur Android et la liste s'affiche depuis l'API locale).
1) Pré-requis
- Node.js LTS (par ex. 18.x ou 20.x). Épinglez avec nvm ou asdf.
- Git
- Java JDK 17 (pour les builds Android)
- Android Studio avec SDK et un AVD configuré
- Xcode pour l'iOS simulator (macOS uniquement)
- Un appareil physique (optionnel mais utile)
Vérifiez les bases :
node -v
java -version
adb --version || echo "ADB pas encore dans le PATH"
2) Créer l'espace de lab
Utilisez un répertoire unique pour garder des expériences rangé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 des apps de référence
Créez deux apps minimales : une en managed, une préparée pour un development client.
# Exemple en managed workflow
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 en managed
cd demo-managed
npm install
npm start # ou : npx expo start
- Tapez a pour lancer l'Android emulator, i pour l'iOS simulator (macOS), ou scannez le QR code avec un appareil physique exécutant Expo Go.
- Confirmez que l'app se charge et que les changements d'UI se rechargent à chaud.
Ajoutez des scripts à 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 clean sous Windows :
npm install --save-dev rimraf
5) Matrice d'appareils
Visez trois cibles dès le début :
- Android emulator (AVD)
- iOS simulator (macOS)
- Appareil physique avec Expo Go
Vous détecterez ainsi tôt les spécificités d'environnement.
6) Logs, métriques et captures
- Utilisez des console.log avec balises claires : « [LAB] mount », « [LAB] fetch ok », « [LAB] error: ... ».
- Capturez un timestamp au démarrage et après le premier rendu pour estimer le cold start.
- Conservez un dossier screenshots/ dans le dépôt pour vos preuves avant/après.
7) API mock locale
Une API mock locale rend vos expériences déterministes et indépendantes du réseau.
# Depuis la racine expo-lab
npm install --save-dev json-server
# Créez un fichier de données
cat > db.json <<'JSON'
{
"items": [
{ "id": 1, "name": "Alpha" },
{ "id": 2, "name": "Bravo" },
{ "id": 3, "name": "Charlie" }
]
}
JSON
# Lancez le serveur sur le port 4000
npx json-server --watch db.json --port 4000
Astuces réseau :
- iOS simulator : http://localhost:4000 fonctionne.
- Android emulator : utilisez http://10.0.2.2:4000 (10.0.2.2 pointe sur l'hôte localhost).
- Appareil physique : utilisez l'IP de votre machine, par ex. http://192.168.1.50:4000.
8) Écran d'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 { SafeAreaView } from 'react-native-safe-area-context';
import { View, Text, FlatList, Switch, StyleSheet, Platform } from 'react-native';
const HOST_ANDROID = 'http://10.0.2.2:4000';
const HOST_IOS_OR_SIM = 'http://localhost:4000';
function hostForPlatform() {
// Heuristique simple : Android utilise l'IP spéciale 10.0.2.2 pour joindre l'hôte
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}>Liste du Lab Expo</Text>
<View style={styles.switchRow}>
<Text>Tri 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 :
npm run lab: android # ou : npm run lab: ios
Vérifiez dans la console les balises timeToDataMs et testez le basculement du tri.
9) Optionnel : development build pour modules natifs
Si vous avez besoin de modules natifs absents d'Expo Go, créez un development build en local.
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 ce chemin dev-client séparé des expériences managed quotidiennes pour éviter la « churn ».
10) Checklist de repro et scripts
Ajoutez un Makefile ou des scripts npm pour standardiser la boucle. Exemple 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
Session type :
make mock # terminal 1 : API locale
make android # terminal 2 : app sur l'émulateur Android
# Éditez le code, suivez les logs, capturez des screenshots
11) Mise en correspondance avec GitLab CI/CD en local
Quand vous souhaitez refléter une partie du lab dans GitLab CI/CD, gardez en cohérence avec vos exécutions locales :
- Épinglez les versions de Node et Java.
- Assurez-vous que les outils Android SDK sont présents dans l'image du runner.
- Réutilisez vos scripts de lab pour installer, linter, builder et tester.
Plus vos scripts locaux ressemblent aux étapes du runner, moins vous aurez de réécritures.
Plan pilote local
Démarrez petit et mesurable pour pouvoir inspecter les résultats en local avant d'élargir.
Objectif du pilote
- Rendre une liste depuis une API mock locale dans une app Expo managed.
- Basculement d'ordre de tri via un feature flag.
- Validation sur Android emulator, iOS simulator et appareil physique.
Critères de succès
- L'app affiche le premier rendu en moins de 10 s sur l'émulateur Android.
- timeToDataMs inférieur à 500 ms de façon constante avec l'API locale.
- Aucune erreur non interceptée dans la console en usage normal.
- Captures d'écran enregistrées dans screenshots/ sur chaque cible.
Plan
- Environnement
- Confirmez Node LTS et Java 17.
- Créez et démarrez un AVD Android, validez l'iOS simulator si vous êtes sur macOS.
- App
- Initialisez demo-managed et ajoutez l'écran d'exemple ci-dessus.
- Ajoutez les scripts : "lab: start", "lab: android", "lab: ios", "lab: doctor".
- API mock
- Lancez json-server sur le port 4000.
- Vérifiez la sélection d'hôte pour chaque cible (localhost vs 10.0.2.2 vs IP LAN).
- Exécution et mesure
- Lancez sur l'Android emulator et observez timeToDataMs.
- Lancez sur l'iOS simulator et capturez une image.
- Lancez sur un appareil avec Expo Go en utilisant l'IP LAN.
- Documentation et stabilisation
- Enregistrez les versions de Node, npm, json-server dans le README.
- Sauvegardez commandes et timings permettant la reproduction.
Extensions (après succès)
- Ajoutez un second écran qui écrit dans le stockage local et relit les données.
- Introduisez un test de base avec Jest et React Native Testing Library.
- Créez un development build dans demo-dev-client si vous avez besoin de modules natifs.
Conclusion
Vous disposez maintenant d'un Expo local lab opérationnel et d'un premier pilote prouvant la boucle de bout en bout. L'essentiel est la clarté : séparez le setup des expériences, gardez un pilote initial étroit et mesurable, et codez tout sous forme de scripts pour rendre chaque exécution répétable.
Prochaines étapes immédiates
- Épinglez les versions (.nvmrc, Java 17) et documentez les pré-requis.
- Commitez vos scripts de lab et un court README avec la checklist de repro.
- Capturez des métriques de base et des screenshots dans le versioning.
- Partagez le template de lab avec l'équipe et étendez-le progressivement.
En gardant un périmètre serré et des étapes scriptées, votre Expo lab restera rapide, sûr et facile à faire évoluer.
Mots-clés à garder en tête pour la recherche et la clarté technique : Expo local lab, Expo setup, Expo testing, Expo examples et Expo development, ainsi que les sujets connexes React Native, Android, GitLab CI/CD, mobile builds et configuration.