Metro Bundler: какво е, изграждане на проект и принцип на работа

Автор: IT Sectr Публикувано: 2026-07-06 Време за четене: 8 мин

Metro Bundler е специализиран JavaScript пакетировчик от 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 — официалният JavaScript пакетировчик за React Native с поддръжка на платформени разширения
  • Fast Refresh — горещо презареждане със запазване на състоянието на компонентите при промяна на код
  • Haste Module System — система от стабилни модулни идентификатори за инкрементални изграждания
  • Платформени разширения — .native.js, .ios.js, .android.js за разделяне на код според платформата
  • Hermes bytecode — режим на изграждане директно в байткод за двигателя Hermes

Какво е Metro Bundler

Metro Bundler е JavaScript пакетировчик с отворен код, разработен от Meta за React Native и използван по подразбиране във всички проекти на рамката. Задачата на Metro е да вземе JavaScript кода на проекта заедно със зависимостите и да изгради един или повече пакета, които се изпълняват на устройството. За разлика от универсалните пакетировчици (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

Архитектурата на Metro е разделена на три независими компонента: Resolver, Transformer и Bundler. Resolver отговаря за търсене и разрешаване на модули — чете import/require изрази, намира съответните файлове, като взема предвид платформените разширения, и връща абсолютни пътища. Transformer извършва транспилация: прилага Babel с preset-ове и plugin-ове, преобразува JSX, TypeScript или Flow в чист JavaScript. Bundler е крайният етап: приема графа на зависимостите от Resolver и трансформираните файлове от Transformer, след което ги сериализира в един или повече пакета (module bundles). Разделянето на три стъпки позволява на Metro да кешира резултатите от всеки етап: ако само един файл се е променил, Resolver и Bundler могат да използват кеша за останалите модули, което дава увеличение на скоростта на изграждане до 10 пъти в режим на разработка.

Resolver: разрешаване на модули и platform-aware търсене

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: Babel и транспилация

Transformer вътре в Metro използва Babel с preset metro-react-native-babel-preset. Стандартната конфигурация включва: преобразуване на JSX в React.createElement, поддръжка на TypeScript (премахване на типове), поддръжка на Flow и polyfill за съвременни JavaScript стандарти (async/await, optional chaining, nullish coalescing). Transformer работи в паралелен режим: всеки модул се транспилира независимо, използвайки пул от работни процеси (по подразбиране броят съответства на броя CPU). От Metro 0.80 нататък се поддържа Granular Transformer Cache — инвалидиране на кеш на ниво отделен файл.

Платформени разширения в Metro

Една от ключовите характеристики на Metro е поддръжката на платформени файлови разширения. React Native проект може да съдържа три версии на един модул: Component.ios.js (iOS), Component.android.js (Android) и Component.native.js (и двете платформи). При импорт на require('./Component') Resolver автоматично избира правилната версия в зависимост от целевата платформа за изграждане. Това позволява писане на код, зависим от платформата, без условни конструкции Platform.OS. Редът на приоритет: име.платформа.js > име.native.js > име.js. Разширението .native.js се използва за общ код, работещ на двете платформи, но несъвместим с уеб. Разширенията .ios.js и .android.js служат за имплементиране на специфични функции — навигация, жестове, работа с файлова система. Metro поддържа персонализирани разширения чрез конфигурация resolver.sourceExts.

js
// 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')],
};

Hot Reload и Fast Refresh в Metro

Fast Refresh е механизмът за горещо презареждане на React Native, имплементиран върху Metro. Когато разработчик промени файл, Metro транспилира отново само променения модул и изпраща актуализацията до приложението чрез WebSocket. Fast Refresh актуализира интерфейса без презареждане на цялото приложение и запазва React състоянието на компонентите, ако са променени само JSX или стилове. Ако е променен код с hooks или състояние, Fast Refresh извършва повторно монтиране само на променения компонент. Metro поддържа два режима: Hot Module Replacement (HMR) за подмяна на модули на място и Live Reload за пълно презареждане на приложението при промяна на родни модули или конфигурация. Fast Refresh е активиран по подразбиране в React Native 0.76 и не изисква допълнителна конфигурация — достатъчно е да стартирате npx react-native start.

РежимСкоростЗапазва състояниеЗадействане
Fast Refresh200-500msДаПромяна на JS/TS файлове
HMR100-300msДаПромяна на CSS/стилове
Live Reload1-3sНеПромяна на native config
Full Rebuild10-60sНеПромяна на podspec/build.gradle

Конфигурация на Metro: metro.config.js

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'.

Hermes пакетиране: изграждане в байткод

Metro поддържа режим на изграждане директно в Hermes bytecode — пропускайки етапа JavaScript AST. При изграждане с HermesTransformer модулите се компилират в HBC (Hermes ByteCode) вместо обикновен JavaScript. Това дава: по-малък размер на пакета (с 30-40%), по-бързо стартиране на приложението (с 20-30%) и по-малка консумация на памет. За активиране задайте hermesCommand в metro.config.js и активирайте флага Hermes в build.gradle (Android) или Podfile (iOS). Изграждането на Hermes пакети се извършва в два етапа: първо Metro изгражда JavaScript пакета, след това Hermes CLI го конвертира в HBC. От React Native 0.70 нататък, Hermes е двигателят по подразбиране на Android, на iOS изисква изрично активиране.

Metro срещу Webpack: сравнение на подходите

Разликата между Metro и Webpack се дължи на различни цели. Webpack е универсален пакетировчик за уеб с огромна екосистема от plugin-ове и loader-и. Metro е специализиран пакетировчик за React Native, където приоритетът е скоростта на инкрементално изграждане и правилната работа с родни модули. Webpack използва дълготраен граф от модули с интелигентно инвалидиране на кеш — това дава бързи преизграждания в уеб, но създава проблеми с платформени разширения. Metro не кешира графа между изгражданията, а го изгражда всеки път — това опростява обработката на платформени разширения и Haste модули. Webpack поддържа динамични импорти с парчета, Metro също — чрез React.lazy() и Suspense, но с ограничение за една активна заявка. Екосистемата на Metro е значително по-малка: няма заместител за style-loader, css-loader, file-loader — тези задачи се решават по различен начин в React Native.

Кога да изберете Metro

Metro е единственият правилен избор за React Native проекти. Webpack не поддържа platform-aware resolution веднага, а конфигурирането на React Native с Webpack изисква значителни усилия (haul bundler, expo web packager). Metro е интегриран в React Native CLI, поддържа се от официалния екип на Meta и получава актуализации с всяко издание на React Native. За React Native Web проекти можете да използвате Webpack за уеб изграждане, като запазите Metro за мобилни пакети.

Често задавани въпроси

Как да изчистя кеша на Metro Bundler?

Стартирайте npx react-native start --reset-cache или изтрийте папката $TMPDIR/metro-* и директорията .metro-health-check* в корена на проекта. Алтернативно: npx react-native clean — тази команда изчиства всички временни файлове на Metro, включително кеша на Babel и Haste картата. След изчистването първото изграждане ще бъде пълно (60-120 секунди), но следващите инкрементални изграждания ще се върнат към нормална скорост.

Защо Metro не вижда модула от node_modules?

Проверете наличието на пакета в package.json dependencies (не devDependencies). Ако модулът е в монорепозиторий, добавете пътя в watchFolders в metro.config.js. Metro не следва симлинкове по подразбиране — използвайте resolver.extraNodeModules за изрично картографиране. За Yarn PnM задайте resolver.useWatchman: false. Ако модулът използва платформени разширения, уверете се, че файловете .ios.js или .android.js съществуват на посочения път.

Как да ускоря изграждането на Metro в голям проект?

Увеличете maxWorkers в metro.config.js на броя CPU минус 1. Конфигурирайте watchFolders само на необходимите директории. Използвайте Hermes bytecode за продукционни изграждания — това ускорява окончателното изграждане чрез пропускане на JS минификация. За разработка включете Fast Refresh (включен е по подразбиране). Ограничете sourceExts само до необходимите разширения. Обмислете разделяне на пакета на парчета чрез lazy loading.

Може ли Metro да се използва за уеб проекти?

Технически да, но не се препоръчва. Metro не е оптимизиран за уеб изграждания: няма поддръжка за CSS, HTML, изображения като модули, няма code splitting с динамичен импорт на ниво браузър. За уеб използвайте Webpack, Vite или Parcel. Metro е специализирано решение за React Native и опитът за адаптирането му за уеб ще доведе до загуба на производителност и липса на екосистема от loader-и.

Каква е разликата между Metro и Re.Pack?

Re.Pack е инструмент на общността за замяна на Metro с Webpack в React Native проекти. Той предоставя достъп до екосистемата от Webpack loader-и (css-loader, svg-loader) и разширено code splitting. Въпреки това, Re.Pack е по-сложен за конфигуриране, не се поддържа официално от Meta и не гарантира съвместимост с новите версии на React Native. Metro остава единственият официално поддържан пакетировчик, което дава стабилност и гаранция за съвместимост с всяко издание.

Обобщение

  • Metro Bundler — официалният JavaScript пакетировчик за React Native с архитектура Resolver-Transformer-Bundler
  • Платформени разширения (.ios.js, .android.js, .native.js) — ключова функция за разделяне на платформен код
  • Fast Refresh — горещо презареждане със запазване на състоянието на компонентите, работещо чрез WebSocket
  • Конфигурация чрез metro.config.js: sourceExts, watchFolders, maxWorkers за оптимизация на изграждане
  • Hermes bytecode — режим на изграждане в байткод за по-бързо стартиране и по-малък размер на пакета
  • Resolver използва Haste Module System и platform-aware resolution — несъвместим с Webpack
  • Transformer работи паралелно чрез Babel с пул от работни процеси
  • Metro е част от React Native CLI и не изисква отделна инсталация или конфигурация за стартиране

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също