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 не е предназначен за уеб разработка: неговата архитектура е насочена изключително към мобилни приложения, работещи под JSC (JavaScriptCore) или Hermes JavaScript двигатели.

История на създаването и позициониране

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 всеки файл преминава през Babel трансформер за преобразуване на JSX, TypeScript и други разширения в чист JavaScript. Крайната фаза 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 с 20–30% в сравнение с JavaScriptCore.

При използване на Hermes е важно да помните ограниченията: двигателът не поддържа Proxy, Reflect и някои възможности на ES6. Повечето React Native приложения не използват тези възможности директно, но някои библиотеки могат да причинят конфликти. Преди да включите Hermes, проверете съвместимостта на всички зависимости на проекта чрез официалния контролен списък за съвместимост. Metro автоматично преминава в режим на генериране на байткод при активация на Hermes.

Мониторинг на производителността на Metro

За проследяне на ефективността на компилацията на Metro, използвайте вградените метрики, достъпни чрез Flipper — инструмента за отлаждане на React Native. Metro публикува събития: bundle_request, transform, resolve с времето за изпълнение на всяка фаза. Анализът на тези данни помага да се идентифицират тесните места: ако фазата transform отнима повече от 70% от времето, проблемът е в Babel трансформера. Включете воденето на дневници на 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 бъндъл с inline трансформация и оптимизация за мобилни двигатели. 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 създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

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

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