Metro: definizione, funzionalità principali e principio di funzionamento

Autore: IT Sectr Pubblicato: 2026-05-19 Tempo di lettura: 8 min

Metro è un bundler JavaScript sviluppato specificamente per React Native e utilizzato di default per compilare applicazioni mobili su questa piattaforma. A differenza dei bundler universali, Metro è ottimizzato per le risorse limitate dei dispositivi mobili e fornisce integrazione con il motore Hermes e Fast Refresh. Secondo Metro Documentation (2026), il bundler gestisce oltre il 90% dei progetti React Native nel mondo.

Punti chiave

  • Metro è il bundler predefinito per React Native, ottimizzato per lo sviluppo mobile su iOS e Android.
  • Architettura trifase di Metro include risoluzione dei moduli, trasformazione e serializzazione nel bundle di output.
  • Fast Refresh è un meccanismo di ricarica a caldo dei componenti senza perdita dello stato dell'applicazione.
  • Inline Requires ritardano il caricamento dei moduli fino alla loro prima chiamata, riducendo il bundle iniziale.
  • Hermes è un motore JavaScript di Meta che utilizza Metro per generare bytecode precompilato.

Cos'è Metro?

Metro è un bundler JavaScript open source creato dal team di Meta per React Native. Ha sostituito il Packager delle prime versioni di React Native ed è diventato lo strumento di compilazione standard per questa piattaforma. Metro non è progettato per lo sviluppo web: la sua architettura è focalizzata esclusivamente su applicazioni mobili che funzionano sui motori JavaScript JSC (JavaScriptCore) o Hermes.

Storia e posizionamento

Metro è apparso nel 2018 in sostituzione del vecchio React Native Packager. Il motivo principale della sua creazione è stata la necessità di un bundler che funzionasse efficientemente con milioni di moduli in grandi applicazioni mobili. A differenza di Webpack, Metro non supporta CSS, HTML o immagini come moduli — queste risorse sono gestite da strumenti React Native separati. Facebook utilizza Metro per compilare la sua applicazione principale, che contiene oltre 100 mila file.

Metro è distribuito tramite npm come pacchetto metro e si installa automaticamente con React Native CLI. La versione di Metro è legata alla versione di React Native, quindi l'aggiornamento del bundler avviene insieme all'aggiornamento della piattaforma.

Come funziona il bundler Metro?

Metro riceve in input il punto di ingresso dell'applicazione, costruisce un grafo delle dipendenze, trasforma ogni modulo e serializza il risultato in un unico bundle. Il processo attraversa tre fasi: Resolve (risoluzione dei moduli), Transform (trasformazione) e Serialize (serializzazione).

Processo di compilazione in Metro

js
// Esempio di configurazione Metro per trasformazione personalizzata
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);
      };
    },
  },
};

Nella fase Resolve, Metro determina la posizione di ogni modulo importato, tenendo conto di alias e node_modules. Nella fase Transform, ogni file passa attraverso un trasformatore Babel per convertire JSX, TypeScript e altre estensioni in JavaScript puro. La fase finale Serialize raccoglie tutti i moduli trasformati in uno o più file bundle.

Architettura di Metro

Metro è costruito su un'architettura modulare dove ogni fase di compilazione è implementata come un componente indipendente. Ciò consente di sostituire i moduli standard con moduli personalizzati senza modificare il nucleo del bundler. L'architettura di Metro include tre pacchetti principali: metro, metro-config e metro-resolver.

Componenti chiave di Metro

Metro Server — un server di sviluppo che si avvia con il comando npx react-native start. Gestisce le richieste di trasformazione dei moduli in tempo reale, fornendo Fast Refresh. Module Store — una cache che memorizza i moduli trasformati in memoria per accelerare le ricompilazioni. Dependency Graph — un grafo delle dipendenze che viene aggiornato incrementalmente quando i file cambiano.

Watchman — un osservatore di file di Meta che Metro utilizza per rilevare le modifiche nel file system. Senza Watchman, Metro è costretto a riscansionare l'intera struttura dei file a ogni modifica, rallentando significativamente lo sviluppo. L'installazione di Watchman è obbligatoria per lavorare comodamente con Metro su progetti di qualsiasi dimensione.

Configurazione di Metro in un progetto React Native

La configurazione di Metro è definita nel file metro.config.js nella radice del progetto. Un file tipico definisce cartelle aggiuntive per la ricerca dei moduli, blocklist per escludere file non necessari e trasformatori personalizzati. In React Native 0.72+ viene utilizzato il rilevamento automatico della configurazione, ma per i monorepo la configurazione è obbligatoria.

Configurazione di base di Metro per 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 esclude i file di test dalla compilazione, riducendo la dimensione del bundle. nodeModulesPaths specifica percorsi aggiuntivi per la ricerca dei pacchetti — fondamentale per i monorepo. extraNodeModules crea alias per pacchetti condivisi utilizzati in diversi progetti del monorepo.

Ottimizzazione della compilazione di Metro

Metro fornisce diversi meccanismi per ottimizzare la dimensione del bundle e la velocità di compilazione. Inline Requires — la tecnica più efficace, che converte le importazioni di livello superiore in chiamate require locali all'interno delle funzioni. RAM bundles consentono di caricare i moduli incrementalmente. Hermes compila JavaScript in bytecode, riducendo la dimensione dell'applicazione del 20–30%.

Abilitazione di Inline Requires e Hermes

js
// metro.config.js — ottimizzazione per la produzione
const config = {
  transformer: {
    async transform({ src, filename, options }) {
      const inlineRequires = options.dev ? false : true;
      return await defaultTransform({ src, filename, options: { ...options, inlineRequires } });
    },
  },
  serializer: {
    polyfillModuleNames: [],
  },
};

// Per abilitare Hermes — in build.gradle (Android):
// project.ext.react = [enableHermes: true, bundleInRelease: true]
// Per iOS — in Podfile: :hermes_enabled => true

Per la diagnosi della dimensione del bundle, Metro fornisce il flag --bundle-output con output di statistiche. Utilizza bundle-visualizer per analizzare la composizione del bundle e trovare moduli grandi che possono essere caricati in modo lazy. Il controllo regolare della dimensione del bundle dovrebbe far parte della pipeline CI/CD del progetto React Native.

Delta Bundles e compilazione incrementale

Metro supporta i delta bundle — un meccanismo in cui, dopo la prima compilazione completa, il server invia solo le modifiche (delta) tra la vecchia e la nuova versione del bundle. Questo accelera radicalmente le compilazioni successive: il tempo di aggiornamento scende da secondi a decine di millisecondi. I delta bundle sono particolarmente efficaci in fase di sviluppo, quando lo sviluppatore salva frequentemente le modifiche e ricarica l'applicazione.

Per abilitare i delta bundle in React Native si utilizza il flag --delta nel comando npx react-native bundle. Sul lato client, i delta bundle sono supportati a partire da React Native 0.64. Nelle compilazioni di produzione, i delta bundle non vengono utilizzati — viene invece utilizzato un bundle completo con bytecode Hermes per le massime prestazioni di avvio. Ciò è possibile perché il guadagno in velocità di sviluppo compensa il costo della prima compilazione completa.

Hermes e Metro: lavoro congiunto

Hermes è un motore JavaScript sviluppato da Meta specificamente per React Native. Metro genera bytecode Hermes in fase di compilazione, consentendo all'applicazione di avviarsi senza una costosa compilazione JavaScript sul dispositivo. Per abilitare Hermes, basta aggiungere enableHermes: true in metro.config.js e configurare build.gradle o Podfile. Hermes riduce il tempo di avvio dell'applicazione del 30–50% e la dimensione dell'APK del 20–30% rispetto a JavaScriptCore.

Quando si utilizza Hermes, è importante ricordare le limitazioni: il motore non supporta Proxy, Reflect e alcune funzionalità ES6. La maggior parte delle applicazioni React Native non utilizza direttamente queste funzionalità, ma alcune librerie potrebbero entrare in conflitto. Prima di abilitare Hermes, verificare la compatibilità di tutte le dipendenze del progetto tramite la lista di controllo ufficiale di compatibilità. Metro passa automaticamente alla modalità di generazione del bytecode quando Hermes viene attivato.

Monitoraggio delle prestazioni di Metro

Per monitorare l'efficienza di compilazione di Metro, utilizza le metriche integrate disponibili tramite Flipper — lo strumento di debug di React Native. Metro pubblica eventi: bundle_request, transform, resolve con il tempo di esecuzione di ogni fase. L'analisi di questi dati aiuta a identificare i colli di bottiglia: se la fase di trasformazione richiede più del 70% del tempo, il problema è nel trasformatore Babel. Attiva la registrazione dei log di Metro tramite il flag --verbose per una diagnosi dettagliata.

Domande frequenti

Si può sostituire Metro con Webpack in React Native?

Tecnicamente sì — esistono progetti sperimentali come react-native-webpack, ma non sono ufficialmente supportati. Metro è integrato con il bridge di React Native, Turbo Modules e Hermes a un livello non accessibile per Webpack. La sostituzione di Metro comporterebbe la perdita di Fast Refresh e del supporto ufficiale.

Perché Metro non supporta CSS?

React Native non utilizza CSS per lo styling — invece viene applicato lo styling JavaScript tramite StyleSheet.create. Poiché Metro è creato esclusivamente per React Native, il supporto CSS non è necessario. Per il rendering web tramite React Native Web, il CSS viene gestito da strumenti separati al di fuori di Metro.

Come gestisce Metro immagini e font?

Metro non elabora immagini o font come moduli. Le risorse vengono importate tramite require('./image.png'), ma Metro le registra solo come dipendenze stringa. Il caricamento effettivo delle immagini viene eseguito dal codice nativo di React Native tramite il componente Image, e Metro copia le risorse nel bundle.

In cosa si differenzia Metro da Rollup?

Rollup genera moduli ES con tree shaking a livello di modulo, ottenendo una dimensione minima del bundle per le librerie. Metro genera un bundle CommonJS con trasformazione inline e ottimizzazione per i motori mobili. Rollup non supporta Fast Refresh e non può funzionare con i moduli nativi di React Native.

Come velocizzare la compilazione a freddo di Metro?

La compilazione a freddo di Metro è rallentata dalla scansione completa di node_modules. Soluzioni: aggiungere watchFolders per i monorepo, utilizzare maxWorkers per la trasformazione parallela e installare Watchman. Per progetti con oltre 10.000 file, considerare metro-memory-fs per la cache in memoria.

Riepilogo

  • Metro è il bundler standard di React Native, ottimizzato per piattaforme mobili con risorse limitate.
  • Architettura trifase (Resolve, Transform, Serialize) consente compilazioni incrementali e Fast Refresh.
  • Fast Refresh — ricarica a caldo dei componenti modificati senza perdita dello stato dell'applicazione.
  • Inline Requires ritardano il caricamento dei moduli fino alla prima chiamata, riducendo il bundle iniziale del 15–30%.
  • Hermes — un motore JavaScript di Meta che compila JS in bytecode tramite Metro per un avvio più rapido.
  • Watchman — un osservatore di file obbligatorio per lavorare comodamente con Metro su progetti con un grande numero di file.
  • Per i monorepo, è necessaria la configurazione di watchFolders e extraNodeModules per la corretta risoluzione dei moduli.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche