Metro Bundler یک باندلر تخصصی جاوااسکریپت از Meta است که منحصراً برای React Native طراحی شده و هسته فریمورک را تشکیل میدهد. بر اساس مستندات رسمی React Native 0.76 (2025)، Metro ساخت افزایشی با Fast Refresh و حل ماژول با در نظر گرفتن پسوندهای پلتفرمی .native.js، .ios.js و .android.js را فراهم میکند. برخلاف Webpack، Metro از کش طولانیمدت module graph استفاده نمیکند — در عوض هر بار که فایلها تغییر میکنند، گراف را دوباره میسازد که Hot Reload فوری را در هنگام توسعه فراهم میکند.
نکات اصلی
Metro Bundler یک باندلر جاوااسکریپت با کد منبع باز است که توسط Meta برای React Native توسعه یافته و به طور پیشفرض در تمام پروژههای فریمورک استفاده میشود. وظیفه Metro این است که کد جاوااسکریپت پروژه را همراه با وابستگیها گرفته و یک یا چند باندل بسازد که روی دستگاه اجرا میشوند. برخلاف باندلرهای جهانی (Webpack، Rollup، Parcel)، Metro برای ویژگیهای توسعه موبایل بهینه شده است: حداقل زمان ساخت، بهروزرسانیهای افزایشی در هنگام توسعه و کار صحیح با ماژولهای پلتفرمی (ماژولهای بومی Objective-C، Swift، Java، Kotlin). Metro در ترکیب React Native CLI ارائه میشود و نیاز به نصب جداگانه ندارد. از React Native 0.72 به بعد، Metro نسخه 0.80+ از ترجمه موازی ماژولها پشتیبانی میکند که ساخت را روی پردازندههای چند هستهای تا 40% تسریع میکند.
معماری Metro به سه مؤلفه مستقل تقسیم میشود: Resolver، Transformer و Bundler. Resolver مسئول جستجو و حل ماژولها است — عبارتهای import/require را میخواند، فایلهای مربوطه را با در نظر گرفتن پسوندهای پلتفرمی پیدا میکند و مسیرهای مطلق را برمیگرداند. Transformer ترجمه را انجام میدهد: Babel را با presetها و pluginها اعمال میکند، JSX، TypeScript یا Flow را به جاوااسکریپت خالص تبدیل میکند. Bundler مرحله نهایی است: گراف وابستگی را از Resolver و فایلهای تبدیلشده را از Transformer دریافت میکند، سپس آنها را در یک یا چند باندل (module bundles) سریالسازی میکند. تقسیم به سه مرحله به Metro اجازه میدهد نتایج هر مرحله را کش کند: اگر فقط یک فایل تغییر کرده باشد، Resolver و Bundler میتوانند از کش برای ماژولهای باقیمانده استفاده کنند که سرعت ساخت را در حالت توسعه تا 10 برابر افزایش میدهد.
Resolver در Metro الگوریتم حل ماژول را پیادهسازی میکند که تا حدی با Node.js module resolution سازگار است. تفاوت کلیدی با Node.js — پشتیبانی از پسوندهای پلتفرمی: require('./Component') به ترتیب اولویت تعیینشده به دنبال Component.native.js، Component.ios.js، Component.android.js میگردد. Resolver همچنین از فیلد package.json "react-native" برای نگاشت ماژولها به پیادهسازیهای جایگزین پشتیبانی میکند — این مکانیزم استاندارد برای کتابخانههای دارای کد پلتفرمی است. اگر فایل پیدا نشود، Resolver با پشته جستجوی کامل خطا میدهد.
Transformer در داخل Metro از Babel با preset metro-react-native-babel-preset استفاده میکند. پیکربندی استاندارد شامل: تبدیل JSX به React.createElement، پشتیبانی از TypeScript (حذف انواع)، پشتیبانی از Flow و polyfill برای استانداردهای مدرن جاوااسکریپت (async/await، optional chaining، nullish coalescing). Transformer در حالت موازی کار میکند: هر ماژول به طور مستقل ترجمه میشود و از استخر فرآیندهای کارگر استفاده میکند (به طور پیشفرض تعداد مطابق با تعداد CPU است). از Metro 0.80 به بعد، Granular Transformer Cache پشتیبانی میشود — ابطال کش در سطح فایل جداگانه.
یکی از ویژگیهای کلیدی Metro پشتیبانی از پسوندهای فایل پلتفرمی است. پروژه React Native میتواند سه نسخه از یک ماژول داشته باشد: Component.ios.js (iOS)، Component.android.js (Android) و Component.native.js (هر دو پلتفرم). هنگام import require('./Component')، Resolver به طور خودکار نسخه صحیح را بسته به پلتفرم هدف ساخت انتخاب میکند. این امکان نوشتن کد وابسته به پلتفرم را بدون ساختارهای شرطی Platform.OS فراهم میکند. ترتیب اولویت: name.platform.js > name.native.js > name.js. پسوند .native.js برای کد مشترکی که روی هر دو پلتفرم کار میکند اما با وب ناسازگار است استفاده میشود. پسوندهای .ios.js و .android.js برای پیادهسازی ویژگیهای خاص — ناوبری، ژستها، کار با سیستم فایل — خدمت میکنند. Metro از پسوندهای سفارشی از طریق پیکربندی resolver.sourceExts پشتیبانی میکند.
// metro.config.js — راهاندازی sourceExts و 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 مکانیزم بارگذاری مجدد داغ React Native است که بر روی Metro پیادهسازی شده است. وقتی توسعهدهنده فایلی را تغییر میدهد، Metro فقط ماژول تغییر یافته را دوباره ترجمه میکند و بهروزرسانی را از طریق WebSocket به برنامه ارسال میکند. Fast Refresh رابط کاربری را بدون بارگذاری مجدد کل برنامه بهروز میکند و وضعیت کامپوننتهای React را حفظ میکند اگر فقط JSX یا استایلها تغییر کرده باشند. اگر کد با hookها یا وضعیت تغییر کرده باشد، FastRefresh فقط کامپوننت تغییر یافته را دوباره نصب میکند. Metro از دو حالت پشتیبانی میکند: Hot Module Replacement (HMR) برای تعویض ماژولها در لحظه و Live Reload برای بارگذاری مجدد کامل برنامه هنگام تغییر ماژولهای بومی یا پیکربندی. Fast Refresh در React Native 0.76 به طور پیشفرض فعال است و نیازی به پیکربندی اضافی ندارد — فقط کافی است npx react-native start را اجرا کنید.
| حالت | سرعت | وضعیت را حفظ میکند | علت |
|---|---|---|---|
| Fast Refresh | 200-500ms | بله | تغییر فایلهای JS/TS |
| HMR | 100-300ms | بله | تغییر CSS/استایلها |
| Live Reload | 1-3s | خیر | تغییر native config |
| Full Rebuild | 10-60s | خیر | تغییر podspec/build.gradle |
metro.config.js فایل پیکربندی Metro است که در ریشه پروژه React Native قرار دارد. در آن پیکربندی میشود: resolver (sourceExts، platformExtensions، extraNodeModules)، transformer (babelTransformerPath، minifierConfig)، server (port، host، enableFastRefresh) و watcher (watchFolders، healthCheck). پیکربندی استاندارد Metro از بسته @react-native/metro-config (React Native 0.76+) به ارث میرسد. برای پروژههای با مونورپو، watchFolders را اضافه کنید — این به Metro اجازه میدهد تغییرات در بستههای خارج از ریشه پروژه را ردیابی کند. برای پیکربندی sourceExts، 'svg'، 'png'، 'gql' را برای تبدیلکنندههای سفارشی اضافه کنید. Metro از پیکربندیهای ناهمگام از طریق async function پشتیبانی میکند — این برای تولید پویای پیکربندی بر اساس محیط مفید است.
بهینهسازی ساخت Metro با پیکربندی صحیح کش آغاز میشود. maxWorkers را برابر تعداد CPU منهای 1 تنظیم کنید. برای توزیعها از resetCache در CI استفاده کنید. sourceExts را به حداقل برسانید — پسوندهای اضافی حل ماژول را کند میکنند. برای پروژههای بزرگ، watchFolders را فقط روی دایرکتوریهای ضروری تنظیم کنید. Metro از Hermes bytecode minification پشتیبانی میکند که اندازه باندل کوچکتری نسبت به Terser استاندارد میدهد — از minifierPath: 'metro-minify-terser' استفاده کنید.
Metro از حالت ساخت مستقیم به Hermes bytecode پشتیبانی میکند — با رد شدن از مرحله AST جاوااسکریپت. هنگام ساخت با HermesTransformer، ماژولها به جای جاوااسکریپت ساده به HBC (Hermes ByteCode) کامپایل میشوند. این مزایا را به همراه دارد: اندازه باندل کوچکتر (30-40%)، راهاندازی سریعتر برنامه (20-30%) و مصرف حافظه کمتر. برای فعالسازی، hermesCommand را در metro.config.js تنظیم کنید و پرچم Hermes را در build.gradle (Android) یا Podfile (iOS) فعال کنید. ساخت باندلهای Hermes در دو مرحله انجام میشود: ابتدا Metro باندل جاوااسکریپت را میسازد، سپس Hermes CLI آن را به HBC تبدیل میکند. از React Native 0.70 به بعد، Hermes موتور پیشفرض در Android است، در iOS نیاز به فعالسازی صریح دارد.
تفاوت بین Metro و Webpack ناشی از اهداف متفاوت است. Webpack یک باندلر جهانی برای وب با اکوسیستم عظیم پلاگینها و لودرها است. Metro یک باندلر تخصصی برای React Native است که در آن اولویت سرعت ساخت افزایشی و کار صحیح با ماژولهای بومی است. Webpack از گراف ماژول طولانیمدت با ابطال هوشمند کش استفاده میکند — این ساختهای مجدد سریع در وب را فراهم میکند اما با پسوندهای پلتفرمی مشکل ایجاد میکند. Metro گراف را بین ساختها کش نمیکند، بلکه هر بار آن را میسازد — این پردازش پسوندهای پلتفرمی و ماژولهای Haste را ساده میکند. Webpack از importهای پویا با chunkها پشتیبانی میکند، Metro هم — از طریق React.lazy() و Suspense، اما با محدودیت یک درخواست فعال. اکوسیستم Metro به طور قابل توجهی کوچکتر است: جایگزینی برای style-loader، css-loader، file-loader وجود ندارد — این وظایف در React Native به روش دیگری حل میشوند.
Metro تنها انتخاب صحیح برای پروژههای React Native است. Webpack از resolution آگاه از پلتفرم خارج از جعبه پشتیبانی نمیکند و پیکربندی React Native با Webpack نیاز به تلاش قابل توجهی دارد (haul bundler، expo web packager). Metro در React Native CLI یکپارچه شده، توسط تیم رسمی Meta پشتیبانی میشود و با هر انتشار React Native بهروزرسانی دریافت میکند. برای پروژههای React Native Web میتوان از Webpack برای ساخت وب استفاده کرد و Metro را برای باندلهای موبایل حفظ کرد.
سوالات متداول
npx react-native start --reset-cache را اجرا کنید یا پوشه $TMPDIR/metro-* و دایرکتوری .metro-health-check* را در ریشه پروژه حذف کنید. جایگزین: npx react-native clean — این دستور تمام فایلهای موقت Metro از جمله کش Babel و نقشه Haste را پاک میکند. پس از پاکسازی، اولین ساخت کامل خواهد بود (60-120 ثانیه)، اما ساختهای افزایشی بعدی به سرعت عادی بازخواهند گشت.
وجود بسته را در package.json dependencies (نه devDependencies) بررسی کنید. اگر ماژول در مونورپو قرار دارد، مسیر را به watchFolders در metro.config.js اضافه کنید. Metro به طور پیشفرض از symlinks پیروی نمیکند — برای نگاشت صریح از resolver.extraNodeModules استفاده کنید. برای Yarn PnM، resolver.useWatchman: false را تنظیم کنید. اگر ماژول از پسوندهای پلتفرمی استفاده میکند، مطمئن شوید فایلهای .ios.js یا .android.js در مسیر مشخص شده وجود دارند.
maxWorkers را در metro.config.js به تعداد CPU منهای 1 افزایش دهید. watchFolders را فقط روی دایرکتوریهای ضروری تنظیم کنید. برای ساختهای تولیدی از Hermes bytecode استفاده کنید — این کار با رد شدن از minification JS، ساخت نهایی را تسریع میکند. برای توسعه، Fast Refresh را فعال کنید (به طور پیشفرض فعال است). sourceExts را فقط به پسوندهای ضروری محدود کنید. تقسیم باندل به chunkها را از طریق lazy loading در نظر بگیرید.
از نظر فنی بله، اما توصیه نمیشود. Metro برای ساختهای وب بهینه نشده است: پشتیبانی از CSS، HTML، تصاویر به عنوان ماژول وجود ندارد، code splitting با import پویا در سطح مرورگر وجود ندارد. برای وب از Webpack، Vite یا Parcel استفاده کنید. Metro یک راهحل تخصصی برای React Native است و تلاش برای تطبیق آن با وب منجر به کاهش عملکرد و فقدان اکوسیستم لودرها خواهد شد.
Re.Pack یک ابزار جامعه برای جایگزینی Metro با Webpack در پروژههای React Native است. این ابزار دسترسی به اکوسیستم لودرهای Webpack (css-loader، svg-loader) و code splitting پیشرفته را فراهم میکند. با این حال، Re.Pack در پیکربندی پیچیدهتر است، به طور رسمی توسط Meta پشتیبانی نمیشود و سازگاری با نسخههای جدید React Native را تضمین نمیکند. Metro تنها باندلر رسمی پشتیبانیشده باقی میماند که ثبات و تضمین سازگاری با هر انتشار را فراهم میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید