Ang Metro Bundler ay isang espesyalisadong JavaScript bundler mula sa Meta, na eksklusibong binuo para sa React Native at bahagi ng core ng framework. Ayon sa opisyal na dokumentasyon ng React Native 0.76 (2025), nagbibigay ang Metro ng incremental na pagbuo gamit ang Fast Refresh at resolusyon ng modyul na isinasaalang-alang ang mga extension ng platform na .native.js, .ios.js, at .android.js. Hindi tulad ng Webpack, hindi gumagamit ang Metro ng mahabang buhay na module graph cache — sa halip ay muli nitong binuo ang graph sa bawat pagbabago ng mga file, na nagbibigay ng agarang Hot Reload sa pag-unlad.
Mga Pangunahing Punto
Metro Bundler ay isang open-source JavaScript bundler, na binuo ng Meta para sa React Native at ginagamit bilang default sa lahat ng proyekto ng framework. Ang gawain ng Metro ay kunin ang JavaScript code ng proyekto kasama ang mga dependency at bumuo ng isa o higit pang mga bundle na isinasagawa sa device. Hindi tulad ng mga universal bundler (Webpack, Rollup, Parcel), ang Metro ay na-optimize para sa mga detalye ng mobile development: minimal na oras ng pagbuo, incremental na mga update sa pag-unlad, at tamang paggana sa mga module ng platform (native modules Objective-C, Swift, Java, Kotlin). Ang Metro ay kasama sa React Native CLI at hindi nangangailangan ng hiwalay na pag-install. Simula sa React Native 0.72, ang Metro bersyon 0.80+ ay sumusuporta sa parallel transpilation ng mga modyul, na nagpapabilis ng pagbuo sa mga multi-core processor ng hanggang 40%.
Ang arkitektura ng Metro ay nahahati sa tatlong independiyenteng bahagi: Resolver, Transformer, at Bundler. Ang Resolver ay responsable para sa paghahanap at resolusyon ng mga modyul — binabasa nito ang mga import/require expression, hinahanap ang mga kaukulang file na isinasaalang-alang ang mga extension ng platform, at nagbabalik ng mga absolute path. Ang Transformer ay nagsasagawa ng transpilation: inilalapat ang Babel na may mga preset at plugin, ginagawang purong JavaScript ang JSX, TypeScript, o Flow. Ang Bundler ay ang huling yugto: tinatanggap nito ang dependency graph mula sa Resolver at mga transformed file mula sa Transformer, pagkatapos ay isinaserye ang mga ito sa isa o higit pang mga bundle (module bundles). Ang paghahati sa tatlong hakbang ay nagpapahintulot sa Metro na i-cache ang mga resulta ng bawat yugto: kung isang file lang ang nagbago, maaaring gamitin ng Resolver at Bundler ang cache para sa natitirang mga modyul, na nagbibigay ng pagtaas ng bilis ng pagbuo ng hanggang 10 beses sa development mode.
Resolver sa Metro ay nagpapatupad ng algorithm ng resolusyon ng modyul, bahagyang katugma sa Node.js module resolution. Ang pangunahing pagkakaiba mula sa Node.js — suporta para sa mga extension ng platform: require('./Component') ay naghahanap ng Component.native.js, Component.ios.js, Component.android.js sa tinukoy na pagkakasunud-sunod ng priyoridad. Sinusuportahan din ng Resolver ang package.json field na "react-native" para sa pag-map ng mga modyul sa mga alternatibong implementasyon — ito ang karaniwang mekanismo para sa mga library na may platform code. Kung hindi matagpuan ang file, nagtatapon ang Resolver ng error na may kumpletong stack ng paghahanap.
Transformer sa loob ng Metro ay gumagamit ng Babel na may preset na metro-react-native-babel-preset. Kasama sa karaniwang konfigurasyon ang: pagbabago ng JSX sa React.createElement, suporta para sa TypeScript (pag-alis ng mga uri), suporta para sa Flow, at polyfill para sa mga modernong pamantayan ng JavaScript (async/await, optional chaining, nullish coalescing). Ang Transformer ay gumagana sa parallel mode: bawat modyul ay independiyenteng tinitranspile, gamit ang pool ng mga worker process (bilang default ang bilang ay tumutugma sa bilang ng CPU). Simula sa Metro 0.80, sinusuportahan ang Granular Transformer Cache — pagpapawalang-bisa ng cache sa antas ng indibidwal na file.
Isa sa mga pangunahing tampok ng Metro ay ang suporta para sa mga extension ng file ng platform. Ang isang React Native project ay maaaring maglaman ng tatlong bersyon ng isang modyul: Component.ios.js (iOS), Component.android.js (Android), at Component.native.js (parehong platform). Sa pag-import ng require('./Component'), awtomatikong pinipili ng Resolver ang tamang bersyon depende sa target na platform ng pagbuo. Ito ay nagpapahintulot sa pagsulat ng code na nakadepende sa platform nang walang conditional na Platform.OS constructs. Ang pagkakasunud-sunod ng priyoridad: pangalan.platform.js > pangalan.native.js > pangalan.js. Ang extension na .native.js ay ginagamit para sa karaniwang code na gumagana sa parehong platform ngunit hindi tugma sa web. Ang mga extension na .ios.js at .android.js ay nagsisilbi para sa pagpapatupad ng mga tiyak na feature — navigation, gestures, pagtatrabaho sa file system. Sinusuportahan ng Metro ang mga custom na extension sa pamamagitan ng konfigurasyong resolver.sourceExts.
// metro.config.js — pag-setup ng sourceExts at 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')],
};
Fast Refresh ay ang mekanismo ng mainit na muling pagkarga ng React Native na ipinatupad sa ibabaw ng Metro. Kapag binago ng developer ang isang file, tinitranspile lamang ng Metro ang binagong modyul at nagpapadala ng update sa app sa pamamagitan ng WebSocket. Ina-update ng Fast Refresh ang interface nang hindi ni-re-reload ang buong app at pinapanatili ang estado ng React components kung JSX o styles lamang ang binago. Kung ang code na may hooks o estado ay binago, ang Fast Refresh ay nagsasagawa ng remounting ng binagong komponent lamang. Sinusuportahan ng Metro ang dalawang mode: Hot Module Replacement (HMR) para sa agarang pagpapalit ng mga modyul at Live Reload para sa ganap na muling pagkarga ng app kapag nagbago ang native modules o konfigurasyon. Ang Fast Refresh ay naka-enable bilang default sa React Native 0.76 at hindi nangangailangan ng karagdagang konfigurasyon — sapat na ang patakbuhin ang npx react-native start.
| Mode | Bilis | Pinapanatili ang estado | Trigger |
|---|---|---|---|
| Fast Refresh | 200-500ms | Oo | Pagbabago ng JS/TS file |
| HMR | 100-300ms | Oo | Pagbabago ng CSS/styles |
| Live Reload | 1-3s | Hindi | Pagbabago ng native config |
| Full Rebuild | 10-60s | Hindi | Pagbabago ng podspec/build.gradle |
metro.config.js ay ang file ng konfigurasyon ng Metro, na matatagpuan sa root ng React Native project. Dito naka-configure ang: resolver (sourceExts, platformExtensions, extraNodeModules), transformer (babelTransformerPath, minifierConfig), server (port, host, enableFastRefresh), at watcher (watchFolders, healthCheck). Ang karaniwang konfigurasyon ng Metro ay minana mula sa package na @react-native/metro-config (React Native 0.76+). Para sa mga proyektong may monorepo, magdagdag ng watchFolders — ito ay magpapahintulot sa Metro na subaybayan ang mga pagbabago sa mga package sa labas ng root ng proyekto. Para sa konfigurasyon ng sourceExts, magdagdag ng 'svg', 'png', 'gql' para sa custom na mga transformer. Sinusuportahan ng Metro ang mga asynchronous na konfigurasyon sa pamamagitan ng async function — ito ay kapaki-pakinabang para sa dynamic na pagbuo ng konfigurasyon batay sa kapaligiran.
Ang pag-optimize ng pagbuo ng Metro ay nagsisimula sa tamang konfigurasyon ng cache. Itakda ang maxWorkers sa bilang ng CPU minus 1. Para sa mga pamamahagi, gamitin ang resetCache sa CI. I-minimize ang sourceExts — ang mga dagdag na extension ay nagpapabagal ng resolusyon ng modyul. Para sa malalaking proyekto, i-configure ang watchFolders lamang sa mga kinakailangang direktoryo. Sinusuportahan ng Metro ang Hermes bytecode minification, na nagbibigay ng mas maliit na sukat ng bundle kaysa sa karaniwang Terser — gamitin ang minifierPath: 'metro-minify-terser'.
Sinusuportahan ng Metro ang mode ng pagbuo nang direkta sa Hermes bytecode — lalaktawan ang yugto ng JavaScript AST. Sa pagbuo gamit ang HermesTransformer, ang mga modyul ay nako-compile sa HBC (Hermes ByteCode) sa halip na plain JavaScript. Ito ay nagbibigay ng: mas maliit na sukat ng bundle (30-40%), mas mabilis na pag-start ng app (20-30%), at mas mababang paggamit ng memory. Para i-activate, itakda ang hermesCommand sa metro.config.js at i-activate ang Hermes flag sa build.gradle (Android) o Podfile (iOS). Ang pagbuo ng Hermes bundle ay isinasagawa sa dalawang yugto: una, binuo ng Metro ang JavaScript bundle, pagkatapos ay kino-convert ito ng Hermes CLI sa HBC. Simula sa React Native 0.70, ang Hermes ay ang default na engine sa Android, sa iOS ay nangangailangan ng tahasang pag-activate.
Ang pagkakaiba sa pagitan ng Metro at Webpack ay dahil sa magkaibang layunin. Ang Webpack ay isang universal bundler para sa web na may malawak na ekosistema ng mga plugin at loader. Ang Metro ay isang espesyalisadong bundler para sa React Native, kung saan ang priyoridad ay ang bilis ng incremental na pagbuo at tamang paggana sa native modules. Gumagamit ang Webpack ng mahabang buhay na graph ng modyul na may matalinong pagpapawalang-bisa ng cache — nagbibigay ito ng mabilis na muling pagbuo sa web, ngunit lumilikha ng mga problema sa mga extension ng platform. Hindi ni-ca-cache ng Metro ang graph sa pagitan ng mga pagbuo, sa halip ay binuo ito sa bawat pagkakataon — pinapadali nito ang pagproseso ng mga extension ng platform at Haste modules. Sinusuportahan ng Webpack ang mga dynamic na import na may mga chunk, gayundin ang Metro — sa pamamagitan ng React.lazy() at Suspense, ngunit may limitasyon ng isang aktibong request. Ang ekosistema ng Metro ay makabuluhang mas maliit: walang kapalit para sa style-loader, css-loader, file-loader — ang mga gawaing ito ay nalulutas nang iba sa React Native.
Metro ay ang tanging tamang pagpipilian para sa React Native projects. Hindi sinusuportahan ng Webpack ang platform-aware resolution nang diretso, at ang pag-configure ng React Native gamit ang Webpack ay nangangailangan ng malaking pagsisikap (haul bundler, expo web packager). Ang Metro ay isinama sa React Native CLI, sinusuportahan ng opisyal na koponan ng Meta, at tumatanggap ng mga update sa bawat release ng React Native. Para sa React Native Web projects, maaari mong gamitin ang Webpack para sa web build, habang pinapanatili ang Metro para sa mobile bundles.
Mga Madalas Itanong
Patakbuhin ang npx react-native start --reset-cache o tanggalin ang folder na $TMPDIR/metro-* at direktoryong .metro-health-check* sa root ng proyekto. Alternatibo: npx react-native clean — nililinis ng command na ito ang lahat ng pansamantalang file ng Metro, kabilang ang Babel cache at Haste map. Pagkatapos ng paglilinis, ang unang pagbuo ay magiging buo (60-120 segundo), ngunit ang mga susunod na incremental na pagbuo ay babalik sa normal na bilis.
Suriin ang presensya ng package sa package.json dependencies (hindi devDependencies). Kung ang modyul ay nasa monorepo, idagdag ang path sa watchFolders sa metro.config.js. Hindi sinusunod ng Metro ang symlinks bilang default — gamitin ang resolver.extraNodeModules para sa tahasang pagma-map. Para sa Yarn PnM, itakda ang resolver.useWatchman: false. Kung ang modyul ay gumagamit ng mga extension ng platform, tiyakin na ang mga file na .ios.js o .android.js ay umiiral sa tinukoy na path.
Taasan ang maxWorkers sa metro.config.js sa bilang ng CPU minus 1. I-configure ang watchFolders lamang sa mga kinakailangang direktoryo. Gamitin ang Hermes bytecode para sa production builds — pinapabilis nito ang huling pagbuo sa pamamagitan ng paglaktaw sa JS minification. Para sa pag-unlad, i-enable ang Fast Refresh(naka-enable bilang default). Limitahan ang sourceExts lamang sa mga kinakailangang extension. Isaalang-alang ang paghahati ng bundle sa mga chunk sa pamamagitan ng lazy loading.
Teknikal na oo, ngunit hindi ito inirerekomenda. Ang Metro ay hindi na-optimize para sa web builds: walang suporta para sa CSS, HTML, mga imahe bilang modyul, walang code splitting na may dynamic na import sa antas ng browser. Para sa web, gamitin ang Webpack, Vite, o Parcel. Ang Metro ay isang espesyalisadong solusyon para sa React Native, at ang pagtatangkang iakma ito para sa web ay hahantong sa pagkawala ng pagganap at kakulangan ng ekosistema ng loader.
Re.Pack ay isang community tool para palitan ang Metro ng Webpack sa React Native projects. Nagbibigay ito ng access sa ekosistema ng Webpack loader (css-loader, svg-loader) at advanced na code splitting. Gayunpaman, ang Re.Pack ay mas kumplikado sa konfigurasyon, hindi opisyal na sinusuportahan ng Meta, at hindi ginagarantiyahan ang compatibility sa mga bagong bersyon ng React Native. Ang Metro ay nananatiling tanging opisyal na sinusuportahang bundler, na nagbibigay ng katatagan at garantiya ng compatibility sa bawat release.
Buod
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