Metro — isang JavaScript bundler na espesyal na binuo para sa React Native at ginagamit bilang default para sa pagbuo ng mga mobile application sa platform na ito. Hindi tulad ng mga universal bundler, ang Metro ay na-optimize para sa limitadong mga mapagkukunan ng mga mobile device at nagbibigay ng integrasyon sa Hermes engine at Fast Refresh. Ayon sa Metro Documentation (2026), ang bundler ay nagpoproseso ng higit sa 90% ng mga React Native na proyekto sa mundo.
Mga Pangunahing Punto
Metro ay isang open-source JavaScript bundler, na ginawa ng Meta team para sa React Native. Pinalitan nito ang Packager mula sa mga naunang bersyon ng React Native at naging karaniwang tool sa pag-compile para sa platform na ito. Ang Metro ay hindi para sa web development: ang arkitektura nito ay nakatuon lamang sa mga mobile application na tumatakbo sa ilalim ng JSC (JavaScriptCore) o Hermes JavaScript engines.
Metro ay lumitaw noong 2018 bilang kapalit ng lumang React Native Packager. Ang pangunahing dahilan ng paglikha ay ang pangangailangan para sa isang bundler na mahusay na gumagana sa milyun-milyong module sa malalaking mobile application. Hindi tulad ng Webpack, hindi sinusuportahan ng Metro ang CSS, HTML o mga larawan bilang mga module — ang mga mapagkukunang ito ay pinoproseso ng hiwalay na React Native tools. Facebook ay gumagamit ng Metro para sa pagbuo ng pangunahing application nito, na naglalaman ng higit sa 100 libong mga file.
Ang Metro ay ipinamamahagi sa pamamagitan ng npm bilang package na metro at awtomatikong naka-install kasama ng React Native CLI. Ang bersyon ng Metro ay naka-link sa bersyon ng React Native, kaya ang pag-update ng bundler ay nangyayari kasabay ng pag-update ng platform.
Metro ay tumatanggap ng entry point ng application, bumubuo ng dependency graph, binabago ang bawat module at nise-serialize ang resulta sa iisang bundle. Ang proseso ay dumadaan sa tatlong phase: Resolve (resolution ng module), Transform (transformasyon) at Serialize (serialization).
// Halimbawa ng configuration ng Metro para sa custom na transformasyon
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);
};
},
},
};
Sa Resolve phase, tinutukoy ng Metro ang lokasyon ng bawat na-import na module, isinasaalang-alang ang mga alias at node_modules. Sa Transform phase, ang bawat file ay dumadaan sa Babel transformer para sa conversion ng JSX, TypeScript at iba pang mga extension sa purong JavaScript. Ang huling Serialize phase ay kumokolekta ng lahat ng mga nabagong module sa isa o higit pang bundle file.
Metro ay binuo sa modular na arkitektura, kung saan ang bawat yugto ng compilation ay ipinatupad bilang isang hiwalay na component. Ito ay nagpapahintulot sa pagpapalit ng mga karaniwang module ng mga custom na module nang hindi binabago ang core ng bundler. Ang arkitektura ng Metro ay may kasamang tatlong pangunahing package: metro, metro-config at metro-resolver.
Metro Server — development server na pinapatakbo gamit ang command na npx react-native start. Ito ay naghahain ng mga request para sa module transformation sa real-time, na nagbibigay ng Fast Refresh. Module Store — cache na nag-iimbak ng mga nabagong module sa memory para pabilisin ang mga paulit-ulit na compilation. Dependency Graph — dependency graph na ina-update nang incremental kapag nagbago ang mga file.
Watchman — file watcher mula sa Meta na ginagamit ng Metro para sa pag-detect ng mga pagbabago sa file system. Kung wala ang Watchman, kailangan ng Metro na i-scan muli ang buong file structure sa bawat pagbabago, na makabuluhang nagpapabagal sa development. Ang pag-install ng Watchman ay kinakailangan para sa komportableng pagtatrabaho sa Metro sa mga proyekto ng anumang laki.
Configuration ng Metro ay tinutukoy sa file na metro.config.js sa root directory ng proyekto. Ang tipikal na file ay tumutukoy ng mga karagdagang folder para sa paghahanap ng module, mga block para sa pagbubukod ng mga hindi kinakailangang file at mga custom na transformer. Sa React Native 0.72+, ginagamit ang awtomatikong pag-detect ng configuration, ngunit para sa mga monorepository, kinakailangan ang configuration.
// 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 ay nagbubukod ng mga test file mula sa compilation, binabawasan ang laki ng bundle. nodeModulesPaths ay nagpapahiwatig ng mga karagdagang path para sa paghahanap ng mga package — kritikal para sa mga monorepository. extraNodeModules ay lumilikha ng mga alias para sa mga shared package na ginagamit sa iba't ibang proyekto ng monorepository.
Metro ay nagbibigay ng ilang mga mekanismo para sa pag-optimize ng laki ng bundle at bilis ng compilation. Inline Requires — ang pinaka-epektibong technique, na ginagawang lokal na require sa loob ng mga function ang mga import sa pinakamataas na antas. RAM bundles ay nagpapahintulot ng incremental na pag-load ng mga module. Hermes ay nagco-compile ng JavaScript sa bytecode, na binabawasan ang laki ng application ng 20–30%.
// metro.config.js — optimization para sa produksyon
const config = {
transformer: {
async transform({ src, filename, options }) {
const inlineRequires = options.dev ? false : true;
return await defaultTransform({ src, filename, options: { ...options, inlineRequires } });
},
},
serializer: {
polyfillModuleNames: [],
},
};
// Para i-enable ang Hermes — sa build.gradle (Android):
// project.ext.react = [enableHermes: true, bundleInRelease: true]
// Para sa iOS — sa Podfile: :hermes_enabled => true
Para sa diagnostics ng laki ng bundle, nagbibigay ang Metro ng flag na --bundle-output na may output ng statistics. Gumamit ng bundle-visualizer para sa pagsusuri ng komposisyon ng bundle at paghahanap ng malalaking module na maaaring i-load nang tamad. Ang regular na pagsusuri ng laki ng bundle ay dapat na bahagi ng CI/CD pipeline ng React Native project.
Metro ay sumusuporta sa delta-bundles — isang mekanismo kung saan pagkatapos ng unang buong compilation, ang server ay nagpapadala lamang ng mga pagbabago (delta) sa pagitan ng luma at bagong bersyon ng bundle. Ito ay radikal na nagpapabilis ng mga susunod na compilation: ang oras ng pag-update ay nababawasan mula sa mga segundo hanggang sa sampu-sampung millisecond. Ang delta-bundles ay lalong epektibo sa yugto ng development, kapag ang developer ay madalas na nagse-save ng mga pagbabago at nagre-reload ng application.
Para sa pag-enable ng delta-bundles sa React Native, ginagamit ang flag na --delta sa command na npx react-native bundle. Sa side ng client, ang delta-bundles ay sinusuportahan simula sa React Native 0.64. Sa production compilations, hindi ina-apply ang delta-bundles — sa halip, ginagamit ang buong bundle na may Hermes bytecode para sa maximum na startup performance. Ito ay nakakamit dahil ang pagtaas ng bilis ng development ay nagko-compensate sa mga gastos ng unang buong compilation.
Hermes — JavaScript engine na binuo ng Meta na espesyal para sa React Native. Ang Metro ay bumubuo ng Hermes bytecode sa yugto ng compilation, na nagpapahintulot sa application na mag-start nang walang mamahaling JavaScript compilation sa device. Para sa pag-enable ng Hermes, sapat na ang magdagdag ng enableHermes: true sa metro.config.js at i-configure ang build.gradle o Podfile. Binabawasan ng Hermes ang startup time ng application ng 30–50% at ang laki ng APK ng 20–30% kumpara sa JavaScriptCore.
Kapag gumagamit ng Hermes, mahalagang tandaan ang mga limitasyon: hindi sinusuportahan ng engine ang Proxy, Reflect at ilang ES6 capabilities. Karamihan sa React Native applications ay hindi direktang gumagamit ng mga capability na ito, ngunit ang ilang mga library ay maaaring magdulot ng conflict. Bago i-enable ang Hermes, suriin ang compatibility ng lahat ng project dependencies sa pamamagitan ng opisyal na checklist ng compatibility. Ang Metro ay awtomatikong lumilipat sa mode ng pagbuo ng bytecode kapag na-activate ang Hermes.
Para sa pagsubaybay ng efficiency ng Metro compilation, gamitin ang mga built-in na metrics na available sa pamamagitan ng Flipper — ang React Native debug tool. Ang Metro ay nag-publish ng mga event: bundle_request, transform, resolve na may execution time ng bawat stage. Ang pagsusuri ng data na ito ay tumutulong sa pagtukoy ng mga bottleneck: kung ang transform phase ay tumatagal ng higit sa 70% ng oras, ang problema ay nasa Babel transformer. I-enable ang Metro logs sa pamamagitan ng flag na --verbose para sa detalyadong diagnostics.
Mga Madalas Itanong
Sa teknikal na paraan oo — may mga eksperimental na proyekto tulad ng react-native-webpack, ngunit hindi sila opisyal na sinusuportahan. Metro ay isinama sa React Native bridge, Turbo Modules at Hermes sa antas na hindi ma-access ng Webpack. Ang pagpapalit ng Metro ay magreresulta sa pagkawala ng Fast Refresh at opisyal na suporta.
Ang React Native ay hindi gumagamit ng CSS para sa styling — sa halip, ginagamit ang JavaScript styling sa pamamagitan ng StyleSheet.create. Dahil ang Metro ay ginawa nang eksklusibo para sa React Native, hindi kailangan ang CSS support. Para sa web rendering sa pamamagitan ng React Native Web, ang CSS ay pinoproseso ng hiwalay na mga tool sa labas ng Metro.
Metro ay hindi nagpoproseso ng mga larawan o font bilang mga module. Ang mga resources ay ina-attach sa pamamagitan ng require('./image.png'), ngunit ang Metro ay nagre-register lamang ng mga ito bilang string dependencies. Ang aktwal na pag-load ng mga larawan ay ginagawa ng native code ng React Native sa pamamagitan ng Image component, at kinokopya ng Metro ang mga resources sa bundle.
Rollup ay bumubuo ng ES modules na may tree shaking sa antas ng module, na nagbibigay ng minimal na laki ng bundle para sa mga library. Metro ay bumubuo ng CommonJS bundle na may inline transformation at optimization para sa mobile engines. Hindi sinusuportahan ng Rollup ang Fast Refresh at hindi ito maaaring gumana sa native React Native modules.
Ang malamig na compilation ng Metro ay bumagal dahil sa buong pag-scan ng node_modules. Mga solusyon: magdagdag ng watchFolders para sa mga monorepository, gumamit ng maxWorkers para sa parallel transformation at i-install ang Watchman. Para sa mga proyektong may 10,000+ file, isaalang-alang ang metro-memory-fs para sa caching sa memory.
Buod
watchFolders at extraNodeModules para sa tamang module resolution.Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din