Metro Bundler: wat het is, project bouwen en werkingsprincipe

Auteur: IT Sectr Gepubliceerd: 2026-07-06 Leestijd: 8 min

Metro Bundler is een gespecialiseerde JavaScript-bundler van Meta, exclusief ontwikkeld voor React Native en onderdeel van de kern van het framework. Volgens de officiële React Native 0.76 (2025) documentatie biedt Metro incrementeel builden met Fast Refresh en module-resolutie rekening houdend met platformextensies .native.js, .ios.js en .android.js. In tegenstelling tot Webpack gebruikt Metro geen langlevende module graph cache — in plaats daarvan herbouwt het de graaf elke keer wanneer bestanden veranderen, wat directe Hot Reload geeft tijdens het ontwikkelen.

Belangrijkste punten

  • Metro Bundler — de officiële JavaScript-bundler voor React Native met ondersteuning voor platformextensies
  • Fast Refresh — hot reloaden met behoud van componentstatus bij codewijzigingen
  • Haste Module System — systeem van stabiele module-ID's voor incrementele builds
  • Platformextensies — .native.js, .ios.js, .android.js voor het scheiden van code per platform
  • Hermes bytecode — buildmodus direct naar bytecode voor de Hermes-engine

Wat is Metro Bundler

Metro Bundler is een open-source JavaScript-bundler, ontwikkeld door Meta voor React Native en standaard gebruikt in alle projecten van het framework. De taak van Metro is om de JavaScript-code van het project samen met afhankelijkheden te nemen en een of meerdere bundles te bouwen die op het apparaat worden uitgevoerd. In tegenstelling tot universele bundlers (Webpack, Rollup, Parcel) is Metro geoptimaliseerd voor de specificiteit van mobiele ontwikkeling: minimale buildtijd, incrementele updates tijdens ontwikkeling en correcte werking met platformmodules (native modules Objective-C, Swift, Java, Kotlin). Metro wordt geleverd binnen React Native CLI en vereist geen aparte installatie. Vanaf React Native 0.72 ondersteunt Metro versie 0.80+ parallelle transpilatie van modules, wat het builden op multi-core processors tot 40% versnelt.

Metro Architectuur: Resolver, Transformer en Bundler

De architectuur van Metro is verdeeld in drie onafhankelijke componenten: Resolver, Transformer en Bundler. Resolver is verantwoordelijk voor het zoeken en oplossen van modules — het leest import/require-expressies, vindt de bijbehorende bestanden rekening houdend met platformextensies en retourneert absolute paden. Transformer voert transpilatie uit: past Babel toe met presets en plugins, zet JSX, TypeScript of Flow om in zuivere JavaScript. Bundler is de laatste fase: het ontvangt de afhankelijkheidsgraaf van Resolver en getransformeerde bestanden van Transformer, en serialiseert ze vervolgens in een of meerdere bundles (module bundles). De verdeling in drie stappen stelt Metro in staat om de resultaten van elke fase te cachen: als slechts één bestand is gewijzigd, kunnen Resolver en Bundler de cache gebruiken voor de overige modules, wat de buildsnelheid in ontwikkelmodus tot 10 keer verhoogt.

Resolver: module-resolutie en platform-aware zoeken

Resolver in Metro implementeert het module-resolutie-algoritme, gedeeltelijk compatibel met Node.js module resolution. Het belangrijkste verschil met Node.js — ondersteuning voor platformextensies: require('./Component') zoekt naar Component.native.js, Component.ios.js, Component.android.js in de gespecificeerde prioriteitsvolgorde. Resolver ondersteunt ook het package.json-veld "react-native" voor het mappen van modules naar alternatieve implementaties — dit is het standaardmechanisme voor bibliotheken met platformcode. Als het bestand niet wordt gevonden, gooit Resolver een fout met de volledige zoekstack.

Transformer: Babel en transpilatie

Transformer binnen Metro gebruikt Babel met de preset metro-react-native-babel-preset. De standaardconfiguratie omvat: transformatie van JSX naar React.createElement, ondersteuning voor TypeScript (verwijderen van types), ondersteuning voor Flow en polyfills voor moderne JavaScript-standaarden (async/await, optional chaining, nullish coalescing). Transformer werkt in parallelle modus: elke module wordt onafhankelijk getranspileerd met behulp van een pool van worker-processen (standaard komt het aantal overeen met het aantal CPU's). Vanaf Metro 0.80 wordt Granular Transformer Cache ondersteund — cache-invalidatie op het niveau van een afzonderlijk bestand.

Platformextensies in Metro

Een van de belangrijkste kenmerken van Metro is de ondersteuning voor platformbestandsextensies. Een React Native-project kan drie versies van één module bevatten: Component.ios.js (iOS), Component.android.js (Android) en Component.native.js (beide platformen). Bij import require('./Component') kiest Resolver automatisch de juiste versie op basis van het doelplatform van de build. Dit maakt het mogelijk om platformafhankelijke code te schrijven zonder conditionele Platform.OS-constructies. De prioriteitsvolgorde: naam.platform.js > naam.native.js > naam.js. De extensie .native.js wordt gebruikt voor gemeenschappelijke code die op beide platformen werkt maar niet compatibel is met het web. De extensies .ios.js en .android.js dienen voor het implementeren van specifieke functies — navigatie, gebaren, werken met het bestandssysteem. Metro ondersteunt aangepaste extensies via configuratie resolver.sourceExts.

js
// metro.config.js — sourceExts en watchFolders instellen
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 en Fast Refresh in Metro

Fast Refresh is het hot reload-mechanisme van React Native, geïmplementeerd bovenop Metro. Wanneer een ontwikkelaar een bestand wijzigt, transpileert Metro alleen de gewijzigde module en stuurt de update naar de app via WebSocket. Fast Refresh werkt de interface bij zonder de hele app te herladen en behoudt de React-componentstatus als alleen JSX of stijlen zijn gewijzigd. Als code met hooks of status is gewijzigd, voert Fast Refresh een hermontage uit van alleen de gewijzigde component. Metro ondersteunt twee modi: Hot Module Replacement (HMR) voor het ter plekke vervangen van modules en Live Reload voor het volledig herladen van de app bij wijziging van native modules of configuratie. Fast Refresh is standaard ingeschakeld in React Native 0.76 en vereist geen extra configuratie — het volstaat om npx react-native start uit te voeren.

ModusSnelheidBehoudt statusTrigger
Fast Refresh200-500msJaWijziging van JS/TS-bestanden
HMR100-300msJaWijziging van CSS/stijlen
Live Reload1-3sNeeWijziging van native config
Full Rebuild10-60sNeeWijziging van podspec/build.gradle

Metro Configuratie: metro.config.js

metro.config.js is het configuratiebestand van Metro, gelegen in de hoofdmap van het React Native-project. Hierin worden geconfigureerd: resolver (sourceExts, platformExtensions, extraNodeModules), transformer (babelTransformerPath, minifierConfig), server (port, host, enableFastRefresh) en watcher (watchFolders, healthCheck). De standaard Metro-configuratie wordt overgenomen van het pakket @react-native/metro-config (React Native 0.76+). Voor projecten met een monorepository voegt u watchFolders toe — dit stelt Metro in staat om wijzigingen in pakketten buiten de projecthoofdmap te volgen. Voor het configureren van sourceExts voegt u 'svg', 'png', 'gql' toe voor aangepaste transformatoren. Metro ondersteunt asynchrone configuraties via async function — dit is handig voor het dynamisch genereren van configuratie op basis van de omgeving.

Build-optimalisatie via configuratie

Optimalisatie van Metro-builden begint met de juiste cache-configuratie. Stel maxWorkers in op het aantal CPU's min 1. Gebruik voor distributies resetCache op CI. Minimaliseer sourceExts — extra extensies vertragen module-resolutie. Voor grote projecten configureert u watchFolders alleen op de benodigde mappen. Metro ondersteunt Hermes bytecode minification, die een kleinere bundelgrootte geeft dan standaard Terser — gebruik minifierPath: 'metro-minify-terser'.

Hermes bundling: builden naar bytecode

Metro ondersteunt de modus om direct naar Hermes bytecode te builden — de JavaScript AST-fase overslaand. Bij builden met HermesTransformer worden modules gecompileerd naar HBC (Hermes ByteCode) in plaats van gewone JavaScript. Dit geeft: kleinere bundelgrootte (met 30-40%), snellere app-start (met 20-30%) en lager geheugengebruik. Om te activeren stelt u hermesCommand in in metro.config.js en activeert u de Hermes-vlag in build.gradle (Android) of Podfile (iOS). Het bouwen van Hermes-bundels gebeurt in twee fasen: eerst bouwt Metro de JavaScript-bundel, vervolgens converteert Hermes CLI deze naar HBC. Vanaf React Native 0.70 is Hermes de standaard-engine op Android, op iOS is expliciete activering vereist.

Metro vs Webpack: vergelijking van benaderingen

Het verschil tussen Metro en Webpack is te wijten aan verschillende doelen. Webpack is een universele bundler voor het web met een enorm ecosysteem van plugins en loaders. Metro is een gespecialiseerde bundler voor React Native, waar prioriteit ligt bij de snelheid van incrementeel builden en correcte werking met native modules. Webpack gebruikt een langlevende module-graaf met intelligente cache-invalidatie — dit geeft snelle herbuilds op het web, maar creëert problemen met platformextensies. Metro cacht de graaf niet tussen builds, maar bouwt deze elke keer opnieuw — dit vereenvoudigt de verwerking van platformextensies en Haste-modules. Webpack ondersteunt dynamische imports met chunks, Metro ook — via React.lazy() en Suspense, maar met een beperking van één actief verzoek. Het Metro-ecosysteem is aanzienlijk kleiner: er is geen vervanging voor style-loader, css-loader, file-loader — deze taken worden anders opgelost in React Native.

Wanneer Metro kiezen

Metro is de enige juiste keuze voor React Native-projecten. Webpack ondersteunt geen platform-aware resolution uit de doos, en het configureren van React Native met Webpack vereist aanzienlijke inspanning (haul bundler, expo web packager). Metro is geïntegreerd in React Native CLI, wordt ondersteund door het officiële Meta-team en krijgt updates met elke React Native-release. Voor React Native Web-projecten kunt u Webpack gebruiken voor web-builds, terwijl Metro behouden blijft voor mobiele bundels.

Veelgestelde vragen

Hoe maak ik de cache van Metro Bundler leeg?

Voer npx react-native start --reset-cache uit of verwijder de map $TMPDIR/metro-* en de directory .metro-health-check* in de projecthoofdmap. Alternatief: npx react-native clean — dit commando verwijdert alle tijdelijke Metro-bestanden, inclusief de Babel-cache en Haste-kaart. Na het leegmaken zal de eerste build volledig zijn (60-120 seconden), maar daaropvolgende incrementele builds keren terug naar normale snelheid.

Waarom ziet Metro de module uit node_modules niet?

Controleer de aanwezigheid van het pakket in package.json dependencies (niet devDependencies). Als de module zich in een monorepository bevindt, voeg dan het pad toe aan watchFolders in metro.config.js. Metro volgt standaard geen symlinks — gebruik resolver.extraNodeModules voor expliciete mapping. Stel voor Yarn PnM resolver.useWatchman: false in. Als de module platformextensies gebruikt, zorg er dan voor dat de .ios.js- of .android.js-bestanden bestaan op het opgegeven pad.

Hoe versnel ik Metro-builden in een groot project?

Verhoog maxWorkers in metro.config.js naar het aantal CPU's min 1. Configureer watchFolders alleen op de benodigde mappen. Gebruik Hermes bytecode voor productie-builds — dit versnelt de uiteindelijke build door JS-minificatie over te slaan. Schakel voor ontwikkeling Fast Refresh in (standaard ingeschakeld). Beperk sourceExts tot alleen de benodigde extensies. Overweeg het opsplitsen van de bundel in chunks via lazy loading.

Kan Metro worden gebruikt voor webprojecten?

Technisch ja, maar het wordt niet aanbevolen. Metro is niet geoptimaliseerd voor web-builds: er is geen ondersteuning voor CSS, HTML, afbeeldingen als modules, geen code splitting met dynamische import op browserniveau. Gebruik voor het web Webpack, Vite of Parcel. Metro is een gespecialiseerde oplossing voor React Native en een poging om het aan te passen voor het web zal leiden tot prestatieverlies en gebrek aan een loader-ecosysteem.

Wat is het verschil tussen Metro en Re.Pack?

Re.Pack is een community-tool voor het vervangen van Metro door Webpack in React Native-projecten. Het geeft toegang tot het Webpack-loader-ecosysteem (css-loader, svg-loader) en geavanceerde code splitting. Echter, Re.Pack is complexer in configuratie, wordt niet officieel ondersteund door Meta en garandeert geen compatibiliteit met nieuwe versies van React Native. Metro blijft de enige officieel ondersteunde bundler, wat stabiliteit en compatibiliteitsgarantie biedt bij elke release.

Samenvatting

  • Metro Bundler — de officiële JavaScript-bundler voor React Native met Resolver-Transformer-Bundler architectuur
  • Platformextensies (.ios.js, .android.js, .native.js) — kernfunctie voor het scheiden van platformcode
  • Fast Refresh — hot reloaden met behoud van componentstatus, werkend via WebSocket
  • Configuratie via metro.config.js: sourceExts, watchFolders, maxWorkers voor build-optimalisatie
  • Hermes bytecode — buildmodus naar bytecode voor snellere start en kleinere bundelgrootte
  • Resolver gebruikt Haste Module System en platform-aware resolution — niet compatibel met Webpack
  • Transformer werkt parallel via Babel met een pool van worker-processen
  • Metro maakt deel uit van React Native CLI en vereist geen aparte installatie of configuratie om te starten

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook