Metro — en JavaScript-bundler speciellt utvecklad för React Native och som används som standard för att bygga mobila applikationer på denna plattform. Till skillnad från universella bundlers är Metro optimerad för mobila enheters begränsade resurser och säkerställer integration med Hermes engine och Fast Refresh. Enligt Metro Documentation (2026) bearbetar bundlern över 90% av React Native-projekten i världen.
Huvudpunkter
Metro är en JavaScript-bundler med öppen källkod, skapad av Meta-teamet för React Native. Den ersatte Packager från tidigare versioner av React Native och blev standardverktyget för kompilering på denna plattform. Metro är inte avsett för webbutveckling: dess arkitektur är inriktad enbart på mobila applikationer som körs under JSC (JavaScriptCore) eller Hermes JavaScript-motorer.
Metro dök upp 2018 som en ersättning för den gamla React Native Packager. Huvudorsaken till skapandet var behovet av en bundler som effektivt arbetar med miljontals moduler i stora mobila applikationer. Till skillnad från Webpack stöder Metro inte CSS, HTML eller bilder som moduler — dessa resurser bearbetas av separata React Native-verktyg. Facebook använder Metro för att bygga sin huvudapplikation som innehåller över 100 tusen filer.
Metro distribueras via npm som paketet metro och installeras automatiskt tillsammans med React Native CLI. Versionen av Metro är kopplad till versionen av React Native, så uppdatering av bundlern sker tillsammans med plattformsuppdateringen.
Metro tar emot applikationens startpunkt, bygger en beroendegraf, transformerar varje modul och serialiserar resultatet till en enda bundle. Processen går igenom tre faser: Resolve (modulupplösning), Transform (transformation) och Serialize (serialisering).
// Exempel på Metro-konfiguration för anpassad transformation
const metroConfig = {
transformer: {
babelTransformerPath: require('metro-babel-transformer'),
async transform({ src, filename, options }) {
const result = await babelTransform({ src, filename, options });
return {
ast: result.ast,
code: result.code,
map: result.map,
dependencies: [],
};
},
},
serializer: {
createModuleIdFactory() {
let nextId = 0;
const moduleIds = new Map();
return ({ path }) => {
if (!moduleIds.has(path)) {
moduleIds.set(path, nextId++);
}
return moduleIds.get(path);
};
},
},
};
I Resolve-fasen bestämmer Metro platsen för varje importerad modul, med hänsyn till alias och node_modules. I Transform-fasen går varje fil igenom en Babel-transformator för konvertering av JSX, TypeScript och andra tillägg till ren JavaScript. Den slutliga Serialize-fasen samlar alla transformerade moduler i en eller flera bundle-filer.
Metro är byggd på en modulär arkitektur, där varje kompileringssteg implementeras som en separat komponent. Detta gör det möjligt att ersätta standardmoduler med anpassade moduler utan att ändra bundlerns kärna. Metros arkitektur innehåller tre huvudpaket: metro, metro-config och metro-resolver.
Metro Server — utvecklingsservern som startas med kommandot npx react-native start. Den hanterar modultransformationsförfrågningar i realtid och möjliggör Fast Refresh. Module Store — cache som lagrar transformerade moduler i minnet för att påskynda återkommande kompileringar. Dependency Graph — beroendegraf som uppdateras inkrementellt när filer ändras.
Watchman — en filbevakare från Meta som Metro använder för att upptäcka ändringar i filsystemet. Utan Watchman måste Metro skanna om hela filstrukturen vid varje ändring, vilket avsevärt saktar ner utvecklingen. Installation av Watchman är obligatorisk för bekvämt arbete med Metro på projekt oavsett storlek.
Konfiguration av Metro anges i filen metro.config.js i projektets rotkatalog. En typisk fil definierar ytterligare mappar för modulsökning, blockeringar för att utesluta onödiga filer och anpassade transformatorer. I React Native 0.72+ används automatisk konfigurationsdetektering, men för monorepositories är konfiguration obligatorisk.
// metro.config.js
const config = {
resolver: {
sourceExts: ['js', 'jsx', 'ts', 'tsx', 'json'],
nodeModulesPaths: ['node_modules'],
blockList: [/\.test\.js$/, /__tests__\/.*/],
extraNodeModules: {
'shared-components': path.resolve(__dirname, '../shared/src'),
},
},
transformer: {
minifierConfig: {
keep_classnames: true,
keep_fnames: true,
mangle: { reserved: ['React', 'Component'] },
},
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
blockList utesluter testfiler från kompileringen, vilket minskar bundle-storleken. nodeModulesPaths anger ytterligare sökvägar för paket — kritiskt för monorepositories. extraNodeModules skapar alias för delade paket som används i olika projekt inom monorepositoriet.
Metro tillhandahåller flera mekanismer för att optimera bundle-storlek och kompileringshastighet. Inline Requires — den mest effektiva tekniken, som omvandlar import på högsta nivå till lokala require inuti funktioner. RAM bundles möjliggör inkrementell laddning av moduler. Hermes kompilerar JavaScript till bytekod och minskar applikationens storlek med 20–30%.
// metro.config.js — optimering för produktion
const config = {
transformer: {
async transform({ src, filename, options }) {
const inlineRequires = options.dev ? false : true;
return await defaultTransform({ src, filename, options: { ...options, inlineRequires } });
},
},
serializer: {
polyfillModuleNames: [],
},
};
// För att aktivera Hermes — i build.gradle (Android):
// project.ext.react = [enableHermes: true, bundleInRelease: true]
// För iOS — i Podfile: :hermes_enabled => true
För diagnostik av bundle-storlek tillhandahåller Metro flaggan --bundle-output med statistikutdata. Använd bundle-visualizer för att analysera bundle-sammansättning och hitta stora moduler som kan laddas lättjefullt. Regelbunden kontroll av bundle-storlek bör vara en del av CI/CD-pipelinen för React Native-projekt.
Metro stödjer delta-bundles — en mekanism där servern efter den första fullständiga kompileringen endast skickar ändringarna (delta) mellan den gamla och nya versionen av bundlen. Detta påskyndar drastiskt efterföljande kompileringar: uppdateringstiden minskar från sekunder till tiotals millisekunder. Delta-bundles är särskilt effektiva under utvecklingsfasen, när utvecklaren ofta sparar ändringar och laddar om applikationen.
För att aktivera delta-bundles i React Native används flaggan --delta i kommandot npx react-native bundle. På klientsidan stöds delta-bundles från React Native 0.64. I produktionskompileringar används inte delta-bundles — istället används en fullständig bundle med Hermes bytekod för maximal startprestanda. Detta uppnås eftersom ökningen i utvecklingshastighet kompenserar kostnaderna för den första fullständiga kompileringen.
Hermes — en JavaScript-motor utvecklad av Meta speciellt för React Native. Metro genererar Hermes bytekod under kompileringsfasen, vilket gör att applikationen kan starta utan dyr JavaScript-kompilering på enheten. För att aktivera Hermes räcker det att lägga till enableHermes: true i metro.config.js och konfigurera build.gradle eller Podfile. Hermes minskar starttiden för applikationen med 30–50% och APK-storleken med 20–30% jämfört med JavaScriptCore.
När du använder Hermes är det viktigt att komma ihåg begränsningarna: motorn stöder inte Proxy, Reflect och vissa ES6-funktioner. De flesta React Native-applikationer använder inte dessa funktioner direkt, men vissa bibliotek kan orsaka konflikter. Innan du aktiverar Hermes, kontrollera kompatibiliteten för alla projektberoenden via den officiella kompatibilitetschecklistan. Metro växlar automatiskt till bytekodsgenereringsläge när Hermes aktiveras.
För att övervaka effektiviteten av Metro-kompilering, använd inbyggda mätvärden som är tillgängliga via Flipper — felsökningsverktyget för React Native. Metro publicerar händelser: bundle_request, transform, resolve med exekveringstid för varje fas. Analys av dessa data hjälper till att identifiera flaskhalsar: om transform-fasen tar mer än 70% av tiden ligger problemet i Babel-transformatorn. Aktivera Metro-loggar via flaggan --verbose för detaljerad diagnostik.
Vanliga frågor
Tekniskt sett ja — det finns experimentella projekt som react-native-webpack, men de stöds inte officiellt. Metro är integrerat med React Native bridge, Turbo Modules och Hermes på en nivå som inte är tillgänglig för Webpack. Att ersätta Metro skulle leda till förlust av Fast Refresh och officiellt stöd.
React Native använder inte CSS för styling — istället används JavaScript-styling genom StyleSheet.create. Eftersom Metro är skapat exklusivt för React Native behövs inte CSS-stöd. För webbrendering via React Native Web hanteras CSS av separata verktyg utanför Metro.
Metro hanterar inte bilder eller teckensnitt som moduler. Resurser kopplas via require('./image.png'), men Metro registrerar dem bara som strängberoenden. Den faktiska bildladdningen utförs av React Native-inbyggd kod via Image-komponenten, och Metro kopierar resurserna till bundlen.
Rollup genererar ES-moduler med tree shaking på modulnivå, vilket ger minimal bundle-storlek för bibliotek. Metro genererar en CommonJS-bundle med inline-transformation och optimering för mobila motorer. Rollup stöder inte Fast Refresh och kan inte arbeta med inbyggda React Native-moduler.
Kall kompilering av Metro saktas ner av full genomsökning av node_modules. Lösningar: lägg till watchFolders för monorepositories, använd maxWorkers för parallell transformation och installera Watchman. För projekt med 10 000+ filer, överväg metro-memory-fs för cachelagring i minnet.
Sammanfattning
watchFolders och extraNodeModules för korrekt modulupplösning.Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också