Metro: این چیست، قابلیت‌های کلیدی و اصل کار

نویسنده: IT Sectr منتشر شده: 2026-05-19 زمان مطالعه: 8 دقیقه

Metro — باندلر JavaScript است که به‌طور ویژه برای React Native طراحی شده و به صورت پیش‌فرض برای ساخت اپلیکیشن‌های موبایل در این پلتفرم استفاده می‌شود. بر خلاف باندلرهای جهانی، Metro برای منابع محدود دستگاه‌های موبایل بهینه‌سازی شده و انتگراسیون با Hermes engine و Fast Refresh را فراهم می‌کند. به گزارش Metro Documentation (2026)، این باندلر بیش از 90% پروژه‌های React Native را در جهان پردازش می‌کند.

نکات کلیدی

  • Metro — باندلر پیش‌فرض برای React Native، بهینه‌سازی شده برای توسعه موبایل در iOS و Android.
  • معماری سه مرحله‌ای Metro شامل حل مدول‌ها، تبدیل و سریالی‌سازی به خروجی باندل است.
  • Fast Refresh — مکانیسم بارگیری مجدد گرم کامپوننت‌ها بدون از دست دادن وضعیت اپلیکیشن.
  • Inline Requires بارگیری مدول‌ها را تا زمان فراخوانی اول به تأخیر می‌اندازد و باندل ابتدایی را کاهش می‌دهد.
  • Hermes — موتور JavaScript از Meta که از Metro برای تولید بایت کد از پیش کامپایل شده استفاده می‌کند.

Metro چیست؟

Metro یک باندلر JavaScript منبع‌باز است که توسط تیم Meta برای React Native ساخته شده است. آن جایگزین Packager از نسخه‌های اولیه React Native شد و به ابزار استاندارد ساخت برای این پلتفرم تبدیل شد. Metro برای توسعه وب طراحی نشده است: معماری آن فقط بر اپلیکیشن‌های موبایل متکی است که تحت موتورهای JavaScript JSC (JavaScriptCore) یا Hermes کار می‌کنند.

تاریخچه ایجاد و جایگابی

Metro در سال 2018 به عنوان جایگزین React Native Packager قدیمی معرفی شد. دلیل اصلی ایجاد آن نیاز به یک باندلر بود که با میلیون‌ها مدول در اپلیکیشن‌های موبایل بزرگ به صورت مؤثر کار کند. بر خلاف Webpack، Metro از CSS، HTML یا تصاویر به عنوان مدول پشتیبانی نمی‌کند — این منابع توسط ابزارهای جداگانه React Native پردازش می‌شوند. Facebook از Metro برای ساخت اپلیکیشن اصلی خود استفاده می‌کند که بیش از 100 هزار فایل دارد.

Metro از طریق npm به عنوان بسته metro منتشر می‌شود و همراه با React Native CLI به صورت خودکار نصب می‌شود. نسخه Metro به نسخه React Native وابسته است، بنابراین به‌روزرسانی باندلر همراه با به‌روزرسانی پلتفرم انجام می‌شود.

باندلر Metro چگونه کار می‌کند؟

Metro نقطه ورودی اپلیکیشن را دریافت می‌کند، گراف وابستگی را می‌سازد، هر مدول را تبدیل می‌کند و نتیجه را به یک باندل واحد سریالی می‌کند. فرآیند از سه مرحله عبور می‌کند: Resolve (حل مدول‌ها)، Transform (تبدیل) و Serialize (سریالی‌سازی).

فرآیند کامپایل در Metro

js
// نمونه پیکربندی Metro برای تبدیل سفارشی
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);
      };
    },
  },
};

در مرحله Resolve، Metro مکان هر مدول وارداتی را با توجه به الیاس‌ها و node_modules تعیین می‌کند. در مرحله Transform، هر فایل برای تبدیل JSX، TypeScript و سایر افزونه‌ها به JavaScript خالص از Babel transformer عبور می‌کند. مرحله نهایی Serialize تمام مدول‌های تبدیل شده را در یک یا چند فایل باندل جمع آوری می‌کند.

معماری Metro

Metro بر روی معماری مدولار ساخته شده است که هر مرحله کامپایل به عنوان یک کامپوننت جداگانه پیاده‌سازی شده است. این امکان جایگزینی مدول‌های استاندارد با مدول‌های سفارشی بدون تغییر هسته باندلر را فراهم می‌کند. معماری Metro شامل سه بسته اصلی است: metro، metro-config و metro-resolver.

کامپوننت‌های کلیدی Metro

Metro Server — سرور توسعه که با دستور npx react-native start راه‌اندازی می‌شود. آن درخواست‌های تبدیل مدول را در زمان واقعی پیشخوانی کرده و Fast Refresh را فراهم می‌کند. Module Store — کش است که مدول‌های تبدیل شده را در حافظه برای سرعت بخشیدن کامپایل‌های مجدد ذخیره می‌کند. Dependency Graph — گراف وابستگی که با تغییر فایل‌ها به صورت افزایشی به‌روز می‌شود.

Watchman — ناظر فایل از Meta که Metro برای تشخیص تغییرات در سیستم فایل استفاده می‌کند. بدون Watchman، Metro مجبور است در هر تغییر کل ساختار فایل را مجدداً اسکن کند که به طور قابل توجهی توسعه را کند می‌کند. نصب Watchman برای کار راحت با Metro در پروژه‌های هر اندازه‌ای ضروری است.

پیکربندی Metro در پروژه React Native

پیکربندی Metro در فایل metro.config.js در ریشه پروژه تعیین می‌شود. یک فایل پیکربندی طیپی پوشه‌های اضافه برای جستجوی مدول‌ها، بلوک‌هایی برای حذف فایل‌های غیرضروری و ترانسفورمرهای سفارشی تعیین می‌کند. در React Native 0.72+ از تشخیص خودکار پیکربندی استفاده می‌شود، اما برای مونوریپوزیتوری‌ها پیکربندی ضروری است.

پیکربندی پایه Metro برای React Native

js
// 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 فایل‌های تست را از کامپایل حذف می‌کند و اندازه باندل را کاهش می‌دهد. nodeModulesPaths مسیرهای اضافه برای جستجوی بسته‌ها را نشان می‌دهد — برای مونوریپوزیتوری‌ها حیاتی است. extraNodeModules برای بسته‌های مشترک مورد استفاده در میان پروژه‌های مونوریپوزیتوری الیاس ایجاد می‌کند.

بهینه‌سازی کامپایل Metro

Metro چندین مکانیسم برای بهینه‌سازی اندازه باندل و سرعت کامپایل ارائه می‌دهد. Inline Requires — موثرترین تکنیک است که ایمپورت‌های سطح بالا را به require محلی داخل توابع تبدیل می‌کند. RAM bundles بارگیری افزایشی مدول‌ها را ممکن می‌سازد. Hermes JavaScript را به بایت کد کامپایل می‌کند و اندازه اپلیکیشن را 20–30% کاهش می‌دهد.

فعال‌سازی Inline Requires و Hermes

js
// metro.config.js — بهینه‌سازی برای تولید
const config = {
  transformer: {
    async transform({ src, filename, options }) {
      const inlineRequires = options.dev ? false : true;
      return await defaultTransform({ src, filename, options: { ...options, inlineRequires } });
    },
  },
  serializer: {
    polyfillModuleNames: [],
  },
};

// برای فعال‌سازی Hermes — در build.gradle (Android):
// project.ext.react = [enableHermes: true, bundleInRelease: true]
// برای iOS — در Podfile: :hermes_enabled => true

برای تشخیص اندازه باندل، Metro پرچم --bundle-output را با خروجی آمار ارائه می‌دهد. از bundle-visualizer برای تجزیه و تحلیل ترکیب باندل و پیدا کردن مدول‌های بزرگی که می‌توانند به صورت تنبل بارگیری شوند استفاده کنید. بررسی منظم اندازه باندل باید بخشی از خط لوله CI/CD پروژه React Native باشد.

Delta Bundles و کامپایل افزایشی

Metro از باندل‌های دلتا پشتیبانی می‌کند — مکانیسمی که پس از اولین کامپایل کامل، سرور فقط تغییرات (دلتا) بین نسخه قدیمی و جدید باندل را ارسال می‌کند. این کامپایل‌های بعدی را به طور رادیکال سرعت می‌بخشد: زمان به‌روزرسانی از چند ثانیه به دهه‌ها میلی‌ثانیه کاهش می‌یابد. باندل‌های دلتا به ویژه در مرحله توسعه مؤثر هستند زمانی که توسعه‌دهنده می‌تواند تغییرات را ذخیره کرده و اپلیکیشن را مجدداً بارگیری کند.

برای فعال‌سازی باندل‌های دلتا در React Native از پرچم --delta در دستور npx react-native bundle استفاده می‌شود. در طرف کلینت، باندل‌های دلتا از React Native 0.64 به بعد پشتیبانی می‌شوند. در کامپایل‌های تولیدی، باندل‌های دلتا اعمال نمی‌شوند — به جای آن‌ها برای حداکثر عملکرد راه‌اندازی، از یک باندل کامل با بایت کد Hermes استفاده می‌شود. این به دلیل آن است که افزایش سرعت توسعه هزینه اولین کامپایل کامل را جبران می‌کند.

Hermes و Metro: کار مشترک

Hermes — موتور JavaScript است که توسط Meta به‌طور ویژه برای React Native طراحی شده است. Metro در مرحله کامپایل بایت کد Hermes را تولید می‌کند که به اپلیکیشن اجازه می‌دهد بدون کامپایل پرهزینه JavaScript روی دستگاه راه اندازی شود. برای فعال‌سازی Hermes کافی است enableHermes: true را به metro.config.js اضافه کرده و build.gradle یا Podfile را پیکربندی کنید. Hermes زمان راه‌اندازی اپلیکیشن را 30–50% کاهش می‌دهد و اندازه APK را در مقایسه با JavaScriptCore 20–30% کاهش می‌دهد.

هنگام استفاده از Hermes، مهم است محدودیت‌ها را در نظر داشته باشید: موتور از Proxy، Reflect و برخی امکانات ES6 پشتیبانی نمی‌کند. اکثر اپلیکیشن‌های React Native از این امکانات به صورت مستقیم استفاده نمی‌کنند، اما برخی کتابخانه‌ها ممکن است مناقضه ایجاد کنند. قبل از فعال‌سازی Hermes، سازگاری تمام وابستگی‌های پروژه را از طریق چک لیست رسمی سازگاری بررسی کنید. Metro پس از فعال‌سازی Hermes به طور خودکار به حالت تولید بایت کد تبدیل می‌شود.

نظارت بر عملکرد Metro

برای پیگیری کارایی کامپایل Metro، از متریک‌های ساخته شده قابل دسترسی از طریق Flipper — ابزار اشکال‌زدایی React Native استفاده کنید. Metro رویدادهایی را منتشر می‌کند: bundle_request، transform، resolve با زمان اجرای هر مرحله. تجزیه و تحلیل این داده‌ها به شناسایی گرفته‌های تنگ کمک می‌کند: اگر مرحله transform بیش از 70% زمان را بگیرد، مشکل در Babel transformer است. برای تشخیص جزئیاتی، سبت رویداد‌های Metro را از طریق پرچم --verbose فعال کنید.

سؤالات متداول

آیا می‌توان Metro را با Webpack در React Native جایگزین کرد؟

از نظر فنی بله — پروژه‌های آزمایشی مانند react-native-webpack وجود دارند، اما به طور رسمی پشتیبانی نمی‌شوند. Metro با React Native bridge، Turbo Modules و Hermes در سطحی انتگراسیون دارد که برای Webpack قابل دسترسی نیست. جایگزینی Metro منجر به از دست رفتن Fast Refresh و پشتیبانی رسمی خواهد شد.

چرا Metro از CSS پشتیبانی نمی‌کند؟

React Native از CSS برای سبک‌دهی استفاده نمی‌کند — به جای آن سبک‌دهی JavaScript از طریق StyleSheet.create اعمال می‌شود. از آنجایی که Metro به طور انحصاری برای React Native ساخته شده، پشتیبانی از CSS لازم نیست. برای رندر وب از طریق React Native Web، CSS توسط ابزارهای جداگانه خارج از Metro پردازش می‌شود.

Metro تصاویر و فونت‌ها را چگونه پردازش می‌کند؟

Metro تصاویر یا فونت‌ها را به عنوان مدول پردازش نمی‌کند. منابع از طریق require('./image.png') متصل می‌شوند، اما Metro آن‌ها را فقط به عنوان وابستگی‌های رشته‌ای ثبت می‌کند. بارگیری فعلی تصاویر توسط کد اصلی React Native از طریق کامپوننت Image انجام می‌شود و Metro منابع را به باندل کپی می‌کند.

Metro چه تفاوتی با Rollup دارد؟

Rollup مدول‌های ES را با tree shaking در سطح مدول تولید می‌کند که اندازه باندل حداقل را برای کتابخانه‌ها دارد. Metro باندل CommonJS را با تبدیل داخلی و بهینه‌سازی برای موتورهای موبایل تولید می‌کند. Rollup از Fast Refresh پشتیبانی نمی‌کند و نمی‌تواند با مدول‌های اصلی React Native کار کند.

چگونه می‌توان کامپایل سرد Metro را سرعت بخشید؟

کامپایل سرد Metro به دلیل اسکن کامل node_modules کند می‌شود. راه‌حل‌ها: watchFolders را برای مونوریپوزیتوری‌ها اضافه کنید، از maxWorkers برای تبدیل موازی استفاده کنید و Watchman را نصب کنید. برای پروژه‌هایی با 10 000+ فایل، metro-memory-fs را برای ذخیره‌سازی در حافظه در نظر بگیرید.

نتیجهگیری

  • Metro — باندلر استاندارد React Native، بهینه‌سازی شده برای پلتفرم‌های موبایل با منابع محدود.
  • معماری سه مرحله‌ای (Resolve, Transform, Serialize) کامپایل افزایشی و Fast Refresh را تامین می‌کند.
  • Fast Refresh — بارگیری مجدد گرم کامپوننت‌های تغییر یافته بدون از دست دادن وضعیت اپلیکیشن.
  • Inline Requires بارگیری مدول‌ها را تا اولین فراخوانی به تأخیر می‌اندازد و باندل ابتدایی را 15–30% کاهش می‌دهد.
  • Hermes — موتور JavaScript از Meta که JS را برای سرعت بخشیدن راه‌اندازی از طریق Metro به بایت کد کامپایل می‌کند.
  • Watchman — ناظر فایل ضروری برای کار راحت Metro در پروژه‌های با تعداد زیاد فایل.
  • برای مونوریپوزیتوری‌ها پیکربندی watchFolders و extraNodeModules برای حل صحیح مدول‌ها مورد نیاز است.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید