Metro Bundler : qu’est-ce que c’est, le bundling de projet et le principe de fonctionnement

Auteur : IT Sectr Publié le : 2026-07-06 Temps de lecture : 8 min

Metro Bundler est un bundler JavaScript spécialisé de Meta, développé exclusivement pour React Native et inclus dans le cœur du framework. Selon la documentation officielle de React Native 0.76 (2025), Metro fournit des builds incrémentaux avec Fast Refresh et la résolution de modules avec des extensions spécifiques aux plateformes .native.js, .ios.js et .android.js. Contrairement à Webpack, Metro n’utilise pas de cache de graphe de modules à long terme — il reconstruit le graphe à chaque modification de fichier, offrant ainsi un rechargement à chaud instantané pendant le développement.

Points clés

  • Metro Bundler — le bundler JavaScript officiel de React Native avec prise en charge des extensions spécifiques aux plateformes
  • Fast Refresh — rechargement à chaud avec conservation de l’état des composants lors des modifications de code
  • Haste Module System — système d’IDs de modules stables pour les builds incrémentaux
  • Extensions de plateforme — .native.js, .ios.js, .android.js pour la séparation du code par plateforme
  • Hermes bytecode — mode de build directement en bytecode pour le moteur Hermes

Qu’est-ce que Metro Bundler

Metro Bundler est un bundler JavaScript open source développé par Meta pour React Native et utilisé par défaut dans tous les projets du framework. La tâche de Metro est de prendre le code JavaScript du projet avec ses dépendances et de le regrouper en un ou plusieurs bundles qui s’exécutent sur l’appareil. Contrairement aux bundlers universels (Webpack, Rollup, Parcel), Metro est optimisé pour les spécificités du développement mobile : temps de build minimal, mises à jour incrémentales pendant le développement et gestion correcte des modules de plateforme (modules natifs Objective-C, Swift, Java, Kotlin). Metro est fourni avec React Native CLI et ne nécessite pas d’installation séparée. À partir de React Native 0.72, Metro version 0.80+ prend en charge la transpilation parallèle des modules, accélérant les builds sur les processeurs multicœurs jusqu’à 40%.

Architecture de Metro : Resolver, Transformer et Bundler

L’architecture de Metro est divisée en trois composants indépendants : Resolver, Transformer et Bundler. Le Resolver est responsable de la recherche et de la résolution des modules — il lit les expressions import/require, trouve les fichiers correspondants en tenant compte des extensions de plateforme et renvoie les chemins absolus. Le Transformer effectue la transpilation : il applique Babel avec ses presets et plugins, transforme JSX, TypeScript ou Flow en JavaScript pur. Le Bundler est l’étape finale : il prend le graphe de dépendances du Resolver et les fichiers transformés du Transformer, puis les sérialise en un ou plusieurs bundles (module bundles). La séparation en trois étapes permet à Metro de mettre en cache les résultats de chaque étape : si un seul fichier a changé, le Resolver et le Bundler peuvent utiliser le cache pour les modules restants, offrant une augmentation de la vitesse de build jusqu’à 10 fois en mode développement.

Resolver : résolution de modules et recherche consciente de la plateforme

Le Resolver dans Metro implémente un algorithme de résolution de modules partiellement compatible avec la résolution de modules de Node.js. La différence clé par rapport à Node.js est la prise en charge des extensions de plateforme : require(‘./Component’) recherche Component.native.js, Component.ios.js, Component.android.js dans l’ordre de priorité spécifié. Le Resolver prend également en charge le champ package.json “react-native” pour mapper les modules vers des implémentations alternatives — c’est le mécanisme standard pour les bibliothèques avec du code spécifique à une plateforme. Si un fichier n’est pas trouvé, le Resolver lance une erreur avec la pile de recherche complète.

Transformer : Babel et transpilation

Le Transformer à l’intérieur de Metro utilise Babel avec le preset metro-react-native-babel-preset. La configuration standard comprend : la transformation de JSX en React.createElement, la prise en charge de TypeScript (suppression des types), la prise en charge de Flow et les polyfills pour les normes JavaScript modernes (async/await, optional chaining, nullish coalescing). Le Transformer fonctionne en mode parallèle : chaque module est transpilé indépendamment, en utilisant un pool de processus workers (par défaut, le nombre correspond au nombre de CPU). À partir de Metro 0.80, le Granular Transformer Cache est pris en charge — invalidation du cache au niveau du fichier individuel.

Extensions spécifiques aux plateformes dans Metro

L’une des principales fonctionnalités de Metro est la prise en charge des extensions de fichier de plateforme. Un projet React Native peut contenir trois versions du même module : Component.ios.js (iOS), Component.android.js (Android) et Component.native.js (les deux plateformes). Lors de l’import de require(‘./Component’), le Resolver sélectionne automatiquement la bonne version en fonction de la plateforme de build cible. Cela permet d’écrire du code dépendant de la plateforme sans constructions conditionnelles Platform.OS. Ordre de priorité : nom.plateforme.js > nom.native.js > nom.js. L’extension .native.js est utilisée pour le code commun qui fonctionne sur les deux plateformes mais est incompatible avec le web. Les extensions .ios.js et .android.js servent à implémenter des fonctionnalités spécifiques — navigation, gestes, opérations du système de fichiers. Metro prend en charge les extensions personnalisées via la configuration resolver.sourceExts.

js
// metro.config.js — configuration de sourceExts et watchFolders
const config = {
  resolver: {
    sourceExts: ['jsx', 'js', 'tsx', 'ts', 'json'],
    platformExtensions: ['ios', 'android', 'native'],
  },
  transformer: {
    babelTransformerPath: require('metro-react-native-babel-transformer'),
  },
  watchFolders: [path.resolve('../shared')],
};

Hot Reload et Fast Refresh dans Metro

Fast Refresh est un mécanisme de rechargement à chaud pour React Native construit sur Metro. Lorsqu’un développeur modifie un fichier, Metro re-transpile uniquement le module modifié et envoie la mise à jour à l’application via WebSocket. Fast Refresh met à jour l’interface sans recharger toute l’application et conserve l’état des composants React si seuls JSX ou les styles ont été modifiés. Si du code avec des hooks ou de l’état est modifié, Fast Refresh remonte uniquement le composant modifié. Metro prend en charge deux modes : Hot Module Replacement (HMR) pour le remplacement de modules à la volée et Live Reload pour le rechargement complet de l’application lors des modifications de modules natifs ou de configuration. Fast Refresh est activé par défaut dans React Native 0.76 et ne nécessite aucune configuration supplémentaire — il suffit d’exécuter npx react-native start.

ModeVitesseConserve l’étatDéclencheur
Fast Refresh200-500msOuiModification de fichiers JS/TS
HMR100-300msOuiModification de CSS/styles
Live Reload1-3sNonModification de config native
Full Rebuild10-60sNonModification de podspec/build.gradle

Configuration de Metro : metro.config.js

Le fichier metro.config.js est le fichier de configuration de Metro situé à la racine d’un projet React Native. Il configure : resolver (sourceExts, platformExtensions, extraNodeModules), transformer (babelTransformerPath, minifierConfig), server (port, host, enableFastRefresh) et watcher (watchFolders, healthCheck). La configuration standard de Metro hérite du paquet @react-native/metro-config (React Native 0.76+). Pour les projets avec monorepo, ajoutez watchFolders — cela permet à Metro de suivre les modifications dans les paquets en dehors de la racine du projet. Pour configurer sourceExts, ajoutez ‘svg’, ‘png’, ‘gql’ pour les transformateurs personnalisés. Metro prend en charge les configurations asynchrones via async function — utile pour la génération dynamique de configuration basée sur l’environnement.

Optimisation du build via la configuration

L’optimisation des builds Metro commence par une configuration de cache appropriée. Définissez maxWorkers au nombre de CPU moins 1. Pour les distributions, utilisez resetCache sur CI. Minimisez sourceExts — les extensions supplémentaires ralentissent la résolution des modules. Pour les grands projets, configurez watchFolders uniquement pour les répertoires nécessaires. Metro prend en charge la minification Hermes bytecode, qui produit une taille de bundle plus petite que Terser standard — utilisez minifierPath : ‘metro-minify-terser’.

Hermes bundling : build en bytecode

Metro prend en charge un mode de build directement en Hermes bytecode — en sautant l’étape AST de JavaScript. Lors du build avec HermesTransformer, les modules sont compilés en HBC (Hermes ByteCode) au lieu de JavaScript standard. Cela offre : une taille de bundle plus petite (30-40%), un démarrage d’application plus rapide (20-30%) et une consommation mémoire réduite. Pour activer, définissez hermesCommand dans metro.config.js et activez le flag Hermes dans build.gradle (Android) ou Podfile (iOS). Le build du bundle Hermes se fait en deux étapes : d’abord Metro construit le bundle JavaScript, puis Hermes CLI le convertit en HBC. À partir de React Native 0.70, Hermes est le moteur par défaut sur Android, sur iOS il nécessite une activation explicite.

Metro vs Webpack : comparaison des approches

La différence entre Metro et Webpack est due à des objectifs différents. Webpack est un bundler universel pour le web avec un énorme écosystème de plugins et de loaders. Metro est un bundler spécialisé pour React Native où la priorité est la vitesse de build incrémental et le travail correct avec les modules natifs. Webpack utilise un graphe de modules à long terme avec invalidation intelligente du cache — cela offre des reconstructions rapides sur le web mais crée des problèmes avec les extensions de plateforme. Metro ne met pas en cache le graphe entre les builds, mais le construit à chaque fois — cela simplifie la gestion des extensions de plateforme et des modules Haste. Webpack prend en charge les imports dynamiques avec chunks, Metro aussi — via React.lazy() et Suspense, mais avec une limitation d’une requête active. L’écosystème de Metro est nettement plus petit : il n’y a pas de remplacement pour style-loader, css-loader, file-loader — ces tâches sont résolues différemment dans React Native.

Quand choisir Metro

Metro est le seul choix correct pour les projets React Native. Webpack ne prend pas en charge la résolution consciente de la plateforme par défaut, et configurer React Native avec Webpack nécessite des efforts considérables (haul bundler, expo web packager). Metro est intégré à React Native CLI, est supporté par l’équipe officielle de Meta et reçoit des mises à jour avec chaque version de React Native. Pour les projets React Native Web, vous pouvez utiliser Webpack pour les builds web tout en conservant Metro pour les bundles mobiles.

Foire aux questions

Comment vider le cache de Metro Bundler ?

Exécutez npx react-native start --reset-cache ou supprimez le dossier $TMPDIR/metro-* et le répertoire .metro-health-check* à la racine du projet. Alternative : npx react-native clean — cette commande nettoie tous les fichiers temporaires de Metro, y compris le cache Babel et la carte Haste. Après le nettoyage, le premier build sera complet (60-120 secondes), mais les builds incrémentaux suivants retrouveront une vitesse normale.

Pourquoi Metro ne voit-il pas un module de node_modules ?

Vérifiez que le paquet se trouve dans les dependencies du package.json (pas devDependencies). Si le module est dans un monorepo, ajoutez le chemin dans watchFolders de metro.config.js. Metro ne suit pas les liens symboliques par défaut — utilisez resolver.extraNodeModules pour un mapping explicite. Pour Yarn PnM, définissez resolver.useWatchman : false. Si le module utilise des extensions de plateforme, assurez-vous que les fichiers .ios.js ou .android.js existent dans le chemin spécifié.

Comment accélérer le build Metro dans un grand projet ?

Augmentez maxWorkers dans metro.config.js au nombre de CPU moins 1. Configurez watchFolders uniquement pour les répertoires nécessaires. Utilisez Hermes bytecode pour les builds de production — cela accélère le build final en sautant la minification JS. Pour le développement, activez Fast Refresh (il est activé par défaut). Limitez sourceExts aux seules extensions nécessaires. Envisagez de diviser le bundle en chunks via le chargement différé.

Peut-on utiliser Metro pour des projets web ?

Techniquement oui, mais ce n’est pas recommandé. Metro n’est pas optimisé pour les builds web : il n’y a pas de prise en charge de CSS, HTML, images en tant que modules, ni de code splitting avec imports dynamiques au niveau navigateur. Pour le web, utilisez Webpack, Vite ou Parcel. Metro est une solution spécialisée pour React Native, et tenter de l’adapter au web entraînera une perte de performance et une absence d’écosystème de loaders.

En quoi Metro diffère-t-il de Re.Pack ?

Re.Pack est un outil communautaire pour remplacer Metro par Webpack dans les projets React Native. Il donne accès à l’écosystème de loaders Webpack (css-loader, svg-loader) et au code splitting avancé. Cependant, Re.Pack est plus complexe à configurer, n’est pas officiellement supporté par Meta et ne garantit pas la compatibilité avec les nouvelles versions de React Native. Metro reste le seul bundler officiellement supporté, offrant stabilité et compatibilité garantie avec chaque version.

Résumé

  • Metro Bundler — le bundler JavaScript officiel de React Native avec architecture Resolver-Transformer-Bundler
  • Extensions de plateforme (.ios.js, .android.js, .native.js) — fonctionnalité clé pour la séparation du code par plateforme
  • Fast Refresh — rechargement à chaud avec conservation de l’état des composants, fonctionne via WebSocket
  • Configuration via metro.config.js : sourceExts, watchFolders, maxWorkers pour l’optimisation du build
  • Hermes bytecode — mode de build en bytecode pour un démarrage plus rapide et une taille de bundle réduite
  • Resolver utilise Haste Module System et la résolution consciente de la plateforme — incompatible avec Webpack
  • Transformer fonctionne en parallèle via Babel avec un pool de processus workers
  • Metro est fourni avec React Native CLI et ne nécessite ni installation ni configuration séparée pour démarrer

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi