Une équipe frontend a déployé une couche de simulation d'API (API-mocking) typée qui ne réside qu'en développement. Grâce aux intercepteurs Axios et au tree-shaking de Vite, le bundle de production reste intact. Les ingénieurs récupèrent les données avec leurs modèles habituels en attendant les points de terminaison (endpoints) du backend, puis basculent un simple drapeau d'environnement pour appeler la véritable API.
Pourquoi l'équipe avait besoin d'une meilleure méthode de simulation
Les développeurs frontend se retrouvent bloqués lorsqu'une route backend n'est pas terminée. La solution rapide — coder en dur une réponse à l'intérieur d'un composant ou parsemer l'interface utilisateur de blocs if (process.env.NODE_ENV === 'development') — permet de faire avancer l'application mais génère une dette technique. Ces objets de simulation deviennent partie intégrante de la logique du composant, augmentent le risque d'envoyer des données fictives en production et rendent le code plus difficile à lire et à tester.
L'équipe souhaitait extraire chaque simulation de l'arborescence des composants, imposer un contrat entre le frontend et le backend, et garantir qu'aucun élément superflu ne se retrouve dans le build de production.
Le processus en trois étapes suivi par l'équipe
- Réunion de contrat – Les ingénieurs frontend et backend se réunissent pour lister chaque requête, son URL, sa méthode et sa charge utile (payload) attendue.
- Contrat typé – Ils transforment cette liste en une interface TypeScript qui devient la source unique de vérité pour la structure des requêtes et des réponses.
- Configuration de l'intercepteur – Un intercepteur Axios examine chaque requête sortante. Si l'URL correspond à une simulation enregistrée, l'intercepteur renvoie les données simulées ; sinon, la requête est transmise au serveur réel.
Comme l'intercepteur est le seul endroit où réside la logique de simulation, le code des composants reste inchangé. Les développeurs continuent d'utiliser leurs hooks de récupération de données habituels — tels que useQuery — sans ajouter de logique conditionnelle.
Comment éviter l'alourdissement de la production
L'équipe a mis en place trois garde-fous permettant à Rollup (le bundler utilisé par Vite) de supprimer entièrement le code de simulation lors de la construction pour la production :
import.meta.env.DEVse résout enfalsedans un build de production, de sorte que l'intégralité du module de l'intercepteur disparaît lors du tree-shaking.- La variable
MODEest définie sur une valeur autre quetestlors de l'exécution des tests unitaires, gardant le code spécifique aux tests séparé. - Un drapeau personnalisé,
VITE_ENABLE_MSW, est par défaut àfalseet doit être activé explicitement pour activer la simulation.
Lorsque ces trois conditions sont fausses, le registre de simulation n'est jamais inclus dans le bundle final.
Organisation des fichiers de simulation
Le dépôt suit une structure centrée sur les fonctionnalités :
interfaces/– Contient les définitions TypeScript générées lors de la réunion de contrat.scenarios.ts– Contient des exemples concrets de réponses réussies et de cas d'erreur pour chaque endpoint.devHandlers.ts– Sert de registre central qui associe les URL aux données de scénario et connecte l'intercepteur à Axios.
Un petit script de scaffolding peut générer ces fichiers automatiquement : donnez-lui une URL et l'interface correspondante, et il crée les fichiers stubs et enregistre la simulation. Le script se trouve en dehors du chemin de code de production, il n'affecte donc pas la taille du bundle.
Ce que l'équipe a gagné
- Zéro simulation dans les composants – Toutes les données fictives résident dans une couche dédiée, gardant le code de l'interface utilisateur propre.
- Sécurité de type de bout en bout – Les données simulées sont conformes aux mêmes interfaces TypeScript que les réponses réelles, de sorte que les incohérences sont détectées lors de la compilation.
- Aucun poids en production – Le tree-shaking supprime entièrement l'intercepteur et les données de simulation, laissant la taille du bundle inchangée.
- Scénarios partagés pour le dev et les tests – Les mêmes définitions de simulation pilotent à la fois le développement local et les tests automatisés, réduisant ainsi la duplication.
Compromis et limites
Cette approche ne remplace pas un véritable backend. Si le contrat de simulation diverge de l'API réelle, les développeurs ne découvrent l'incohérence qu'après avoir basculé le drapeau d'environnement.
Prochaines étapes à surveiller
- Intégration des outils –
- Adoption plus large –
- Surveillance des performances –
La conclusion est claire : déplacer la logique de simulation dans une couche typée et contrôlée par l'environnement permet aux équipes frontend de garder des composants impeccables, de maintenir la sécurité de type et de livrer des builds de production sans charges utiles de simulation cachées. Maintenir un contrat partagé est le prix d'un flux de travail de développement plus fluide et d'une base de code plus propre.
