Το Metro Bundler είναι ένα εξειδικευμένο JavaScript bundler από τη Meta, που αναπτύχθηκε αποκλειστικά για το React Native και αποτελεί τον πυρήνα του framework. Σύμφωνα με την επίσημη τεκμηρίωση του React Native 0.76 (2025), το Metro παρέχει επαυξητική δημιουργία με Fast Refresh και επίλυση μονάδων λαμβάνοντας υπόψη τις επεκτάσεις πλατφόρμας .native.js, .ios.js και .android.js. Σε αντίθεση με το Webpack, το Metro δεν χρησιμοποιεί μακροχρόνια προσωρινή μνήμη module graph — αντίθετα ανακατασκευάζει το γράφημα κάθε φορά που αλλάζουν αρχεία, δίνοντας άμεσο Hot Reload κατά την ανάπτυξη.
Κύρια σημεία
Metro Bundler είναι ένα bundler JavaScript ανοιχτού κώδικα, που αναπτύχθηκε από τη Meta για το React Native και χρησιμοποιείται προεπιλεγμένα σε όλα τα έργα του framework. Καθήκον του Metro είναι να πάρει τον κώδικα JavaScript του έργου μαζί με τις εξαρτήσεις και να δημιουργήσει ένα ή περισσότερα bundles που εκτελούνται στη συσκευή. Σε αντίθεση με τα καθολικά bundler (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 με presets και plugins, μετατρέπει JSX, TypeScript ή Flow σε καθαρό JavaScript. Το Bundler είναι το τελικό στάδιο: λαμβάνει το γράφημα εξαρτήσεων από το Resolver και τα μετασχηματισμένα αρχεία από το Transformer, στη συνέχεια τα σειριοποιεί σε ένα ή περισσότερα bundles (module bundles). Ο διαχωρισμός σε τρία βήματα επιτρέπει στο Metro να αποθηκεύει προσωρινά τα αποτελέσματα κάθε σταδίου: αν άλλαξε μόνο ένα αρχείο, τα Resolver και Bundler μπορούν να χρησιμοποιήσουν την προσωρινή μνήμη για τα υπόλοιπα modules, δίνοντας αύξηση ταχύτητας δημιουργίας έως και 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 για σύγχρονα πρότυπα JavaScript (async/await, optional chaining, nullish coalescing). Το Transformer λειτουργεί σε παράλληλη λειτουργία: κάθε module μεταγλωττίζεται ανεξάρτητα, χρησιμοποιώντας μια δεξαμενή διεργασιών εργασίας (από προεπιλογή ο αριθμός αντιστοιχεί στον αριθμό των CPU). Από το Metro 0.80, υποστηρίζεται το Granular Transformer Cache — ακύρωση προσωρινής μνήμης σε επίπεδο μεμονωμένου αρχείου.
Ένα από τα βασικά χαρακτηριστικά του 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.
// 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 ή στυλ. Αν άλλαξε κώδικας με hooks ή κατάσταση, το Fast Refresh εκτελεί επανατοποθέτηση μόνο του τροποποιημένου στοιχείου. Το 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+). Για έργα με monorepo, προσθέστε watchFolders — αυτό θα επιτρέψει στο Metro να παρακολουθεί αλλαγές σε πακέτα εκτός της ρίζας του έργου. Για τη διαμόρφωση sourceExts, προσθέστε 'svg', 'png', 'gql' για προσαρμοσμένους μετασχηματιστές. Το Metro υποστηρίζει ασύγχρονες διαμορφώσεις μέσω async function — αυτό είναι χρήσιμο για δυναμική δημιουργία διαμόρφωσης βάσει περιβάλλοντος.
Η βελτιστοποίηση της δημιουργίας Metro ξεκινά με τη σωστή διαμόρφωση της προσωρινής μνήμης. Ορίστε το maxWorkers στον αριθμό CPU μείον 1. Για διανομές, χρησιμοποιήστε resetCache στο CI. Ελαχιστοποιήστε το sourceExts — οι επιπλέον επεκτάσεις επιβραδύνουν την επίλυση μονάδων. Για μεγάλα έργα, διαμορφώστε watchFolders μόνο στους απαραίτητους καταλόγους. Το Metro υποστηρίζει Hermes bytecode minification, που δίνει μικρότερο μέγεθος bundle από το τυπικό Terser — χρησιμοποιήστε minifierPath: 'metro-minify-terser'.
Το Metro υποστηρίζει λειτουργία δημιουργίας απευθείας σε Hermes bytecode — παραλείποντας το στάδιο JavaScript AST. Κατά τη δημιουργία με HermesTransformer, οι μονάδες μεταγλωττίζονται σε HBC (Hermes ByteCode) αντί για απλό JavaScript. Αυτό δίνει: μικρότερο μέγεθος bundle (κατά 30-40%), ταχύτερη εκκίνηση εφαρμογής (κατά 20-30%) και χαμηλότερη κατανάλωση μνήμης. Για ενεργοποίηση, ορίστε hermesCommand στο metro.config.js και ενεργοποιήστε τη σημαία Hermes στο build.gradle (Android) ή Podfile (iOS). Η δημιουργία Hermes bundles πραγματοποιείται σε δύο στάδια: πρώτα το Metro δημιουργεί το JavaScript bundle, στη συνέχεια το Hermes CLI το μετατρέπει σε HBC. Από το React Native 0.70, το Hermes είναι ο προεπιλεγμένος κινητήρας στο Android, στο iOS απαιτεί ρητή ενεργοποίηση.
Η διαφορά μεταξύ Metro και Webpack οφείλεται σε διαφορετικούς στόχους. Το Webpack είναι ένα καθολικό bundler για τον ιστό με τεράστιο οικοσύστημα plugins και loaders. Το Metro είναι ένα εξειδικευμένο bundler για το React Native, όπου προτεραιότητα είναι η ταχύτητα επαυξητικής δημιουργίας και η σωστή λειτουργία με εγγενείς μονάδες. Το Webpack χρησιμοποιεί μακροχρόνιο γράφημα μονάδων με έξυπνη ακύρωση προσωρινής μνήμης — αυτό δίνει γρήγορες ανακατασκευές στον ιστό, αλλά δημιουργεί προβλήματα με επεκτάσεις πλατφόρμας. Το Metro δεν αποθηκεύει προσωρινά το γράφημα μεταξύ δημιουργιών, αλλά το κατασκευάζει κάθε φορά — αυτό απλοποιεί την επεξεργασία επεκτάσεων πλατφόρμας και μονάδων Haste. Το Webpack υποστηρίζει δυναμικές εισαγωγές με chunks, το Metro επίσης — μέσω React.lazy() και Suspense, αλλά με περιορισμό ενός ενεργού αιτήματος. Το οικοσύστημα του Metro είναι σημαντικά μικρότερο: δεν υπάρχει αντικατάσταση για style-loader, css-loader, file-loader — αυτές οι εργασίες επιλύονται διαφορετικά στο React Native.
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 για κινητά bundles.
Συχνές Ερωτήσεις
Εκτελέστε npx react-native start --reset-cache ή διαγράψτε τον φάκελο $TMPDIR/metro-* και τον κατάλογο .metro-health-check* στη ρίζα του έργου. Εναλλακτικά: npx react-native clean — αυτή η εντολή καθαρίζει όλα τα προσωρινά αρχεία του Metro, συμπεριλαμβανομένης της προσωρινής μνήμης Babel και του χάρτη Haste. Μετά τον καθαρισμό, η πρώτη δημιουργία θα είναι πλήρης (60-120 δευτερόλεπτα), αλλά οι επόμενες επαυξητικές δημιουργίες θα επιστρέψουν στην κανονική ταχύτητα.
Ελέγξτε την παρουσία του πακέτου στο package.json dependencies (όχι devDependencies). Αν η μονάδα βρίσκεται σε monorepo, προσθέστε τη διαδρομή στο 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 για παραγωγικές δημιουργίες — αυτό επιταχύνει την τελική δημιουργία παρακάμπτοντας τη συμπίεση JS. Για ανάπτυξη, ενεργοποιήστε Fast Refresh (είναι ενεργοποιημένο από προεπιλογή). Περιορίστε το sourceExts μόνο στις απαραίτητες επεκτάσεις. Εξετάστε τον διαχωρισμό του bundle σε chunks μέσω lazy loading.
Τεχνικά ναι, αλλά δεν συνιστάται. Το Metro δεν είναι βελτιστοποιημένο για δημιουργίες ιστού: δεν υπάρχει υποστήριξη για CSS, HTML, εικόνες ως μονάδες, δεν υπάρχει code splitting με δυναμική εισαγωγή σε επίπεδο προγράμματος περιήγησης. Για ιστό, χρησιμοποιήστε Webpack, Vite ή Parcel. Το Metro είναι μια εξειδικευμένη λύση για το React Native, και η προσπάθεια προσαρμογής του για τον ιστό θα οδηγήσει σε απώλεια απόδοσης και έλλειψη οικοσυστήματος loader.
Re.Pack είναι ένα εργαλείο κοινότητας για αντικατάσταση του Metro με Webpack σε έργα React Native. Παρέχει πρόσβαση στο οικοσύστημα loader του Webpack (css-loader, svg-loader) και προηγμένο code splitting. Ωστόσο, το Re.Pack είναι πιο περίπλοκο στη διαμόρφωση, δεν υποστηρίζεται επίσημα από τη Meta και δεν εγγυάται συμβατότητα με νέες εκδόσεις του React Native. Το Metro παραμένει το μόνο επίσημα υποστηριζόμενο bundler, που παρέχει σταθερότητα και εγγύηση συμβατότητας με κάθε έκδοση.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης