Metro คือบัณเดลอร์ JavaScript ที่พัฒนาขึ้นเฉพาะสำหรับ React Native และใช้เป็นค่าเริ่มต้นสำหรับการสร้างแอปพลิเคชันมือถือบนแพลตฟอร์มนี้ แตกต่างจากบัณเดลอร์ทั่วไป Metro ได้รับการปรับให้เหมาะสมกับทรัพยากรที่จำกัดของอุปกรณ์มือถือและให้การทำงานร่วมกับเอนจิน Hermes และ Fast Refresh ตาม Metro Documentation (2026) บัณเดลอร์นี้จัดการโปรเจกต์ React Native กว่า 90% ทั่วโลก
ประเด็นสำคัญ
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,000 ไฟล์
Metro เผยแพร่ผ่าน npm เป็นแพ็กเกจ metro และติดตั้งโดยอัตโนมัติพร้อมกับ React Native CLI เวอร์ชันของ Metro เชื่อมโยงกับเวอร์ชันของ React Native ดังนั้นการอัปเดตบัณเดลอร์จึงเกิดขึ้นพร้อมกับการอัปเดตแพลตฟอร์ม
Metro รับจุดเริ่มต้นของแอปพลิเคชันเป็นอินพุต สร้างกราฟการพึ่งพา แปลงแต่ละโมดูล และทำให้ผลลัพธ์เป็นอนุกรมเป็นบัณเดลเดียว กระบวนการผ่านสามเฟส: Resolve (การแก้ไขโมดูล), Transform (การแปลง) และ Serialize (การทำให้เป็นอนุกรม)
// ตัวอย่างการกำหนดค่า 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-config และ metro-resolver
Metro Server — เซิร์ฟเวอร์สำหรับพัฒนาที่เริ่มต้นด้วยคำสั่ง npx react-native start มันให้บริการคำขอแปลงโมดูลแบบเรียลไทม์ ให้ Fast Refresh Module Store — แคชที่เก็บโมดูลที่แปลงแล้วในหน่วยความจำเพื่อเร่งการบิลด์ซ้ำ Dependency Graph — กราฟการพึ่งพาที่อัปเดตแบบเพิ่มหน่วยเมื่อไฟล์เปลี่ยนแปลง
Watchman — ตัวติดตามไฟล์จาก Meta ที่ Metro ใช้เพื่อตรวจจับการเปลี่ยนแปลงในระบบไฟล์ หากไม่มี Watchman Metro จะต้องสแกนโครงสร้างไฟล์ทั้งหมดใหม่ทุกครั้งที่มีการเปลี่ยนแปลง ซึ่งทำให้การพัฒนาช้าลงอย่างมาก การติดตั้ง Watchman เป็นสิ่งจำเป็นสำหรับการทำงานที่สะดวกกับ Metro ในโปรเจกต์ทุกขนาด
การกำหนดค่า ของ Metro ถูกตั้งค่าในไฟล์ metro.config.js ในรูทของโปรเจกต์ ไฟล์ทั่วไปจะกำหนดโฟลเดอร์เพิ่มเติมสำหรับค้นหาโมดูล รายการบล็อกเพื่อแยกไฟล์ที่ไม่จำเป็น และตัวแปลงที่กำหนดเอง ใน React Native 0.72+ จะใช้การตรวจจับการกำหนดค่าอัตโนมัติ แต่สำหรับโมโนรีโป การกำหนดค่าเป็นสิ่งจำเป็น
// 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 มีกลไกหลายอย่างสำหรับเพิ่มประสิทธิภาพขนาดบัณเดลและความเร็วในการบิลด์ Inline Requires — เทคนิคที่มีประสิทธิภาพที่สุด แปลงการนำเข้าในระดับบนสุดเป็นการเรียก require ในเครื่องภายในฟังก์ชัน RAM bundles อนุญาตให้โหลดโมดูลแบบเพิ่มหน่วย Hermes คอมไพล์ JavaScript เป็นไบต์โค้ด ลดขนาดแอปพลิเคชันลง 20–30%
// 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
Metro รองรับเดลต้าบัณเดล — กลไกที่หลังจากบิลด์เต็มครั้งแรก เซิร์ฟเวอร์จะส่งเฉพาะการเปลี่ยนแปลง (เดลต้า) ระหว่างเวอร์ชันเก่าและใหม่ของบัณเดล ซึ่งช่วยเร่งการบิลด์ครั้งต่อๆ ไปอย่างมาก: เวลาอัปเดตลดลงจากวินาทีเหลือเพียงสิบมิลลิวินาที เดลต้าบัณเดลมีประสิทธิภาพโดยเฉพาะในช่วงการพัฒนา เมื่อนักพัฒนาบันทึกการเปลี่ยนแปลงบ่อยครั้งและโหลดแอปพลิเคชันใหม่
ในการเปิดใช้งานเดลต้าบัณเดลใน React Native ให้ใช้แฟล็ก --delta ในคำสั่ง npx react-native bundle ฝั่งไคลเอ็นต์ เดลต้าบัณเดลรองรับตั้งแต่ React Native 0.64 ในการบิลด์สำหรับโปรดักชัน จะไม่ใช้เดลต้าบัณเดล — แต่จะใช้บัณเดลเต็มรูปแบบกับไบต์โค้ด Hermes เพื่อประสิทธิภาพการเริ่มต้นสูงสุด ซึ่งเป็นไปได้เพราะความเร็วในการพัฒนาที่เพิ่มขึ้นชดเชยต้นทุนของการบิลด์เต็มครั้งแรก
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 ให้ใช้เมตริกในตัวที่มีให้ผ่าน Flipper — เครื่องมือดีบัก React Metro เผยแพร่อีเวนต์: bundle_request, transform, resolve พร้อมเวลาดำเนินการของแต่ละขั้นตอน การวิเคราะห์ข้อมูลนี้ช่วยระบุคอขวด: หากเฟส transform ใช้เวลามากกว่า 70% ปัญหาอยู่ที่ตัวแปลง Babel เปิดใช้งานการบันทึก Metro ผ่านแฟล็ก --verbose สำหรับการวินิจฉัยโดยละเอียด
คำถามที่พบบ่อย
ในทางเทคนิคได้ — มีโปรเจกต์ทดลองเช่น react-native-webpack แต่ไม่ได้รับการสนับสนุนอย่างเป็นทางการ Metro ถูกรวมเข้ากับบริดจ์ React Native, Turbo Modules และ Hermes ในระดับที่ Webpack ไม่สามารถเข้าถึงได้ การแทนที่ Metro จะทำให้สูญเสีย Fast Refresh และการสนับสนุนอย่างเป็นทางการ
React Native ไม่ใช้ CSS สำหรับการจัดแต่ง — แต่ใช้การจัดแต่งสไตล์ผ่าน JavaScript ผ่าน StyleSheet.create เนื่องจาก Metro สร้างขึ้นสำหรับ React Native โดยเฉพาะ จึงไม่จำเป็นต้องรองรับ CSS สำหรับการเรนเดอร์เว็บผ่าน React Native Web CSS จะถูกจัดการโดยเครื่องมือแยกต่างหากนอก Metro
Metro ไม่ประมวลผลรูปภาพหรือฟอนต์เป็นโมดูล ทรัพยากรถูกนำเข้าผ่าน require('./image.png') แต่ Metro ลงทะเบียนเป็นเพียงการพึ่งพาสตริงเท่านั้น การโหลดรูปภาพจริงดำเนินการโดยโค้ดเนทีฟของ React Native ผ่านคอมโพเนนต์ Image และ Metro คัดลอกทรัพยากรไปยังบัณเดล
Rollup สร้างโมดูล ES พร้อม tree shaking ในระดับโมดูล ทำให้ขนาดบัณเดลน้อยที่สุดสำหรับไลบรารี Metro สร้างบัณเดล CommonJS พร้อมการแปลงแบบอินไลน์และการเพิ่มประสิทธิภาพสำหรับเอนจินมือถือ Rollup ไม่รองรับ Fast Refresh และไม่สามารถทำงานกับโมดูลเนทีฟของ React Native
การบิลด์เย็นของ Metro ช้าลงเนื่องจากการสแกน node_modules ทั้งหมด วิธีแก้ไข: เพิ่ม watchFolders สำหรับโมโนรีโป ใช้ maxWorkers สำหรับการแปลงแบบขนาน และติดตั้ง Watchman สำหรับโปรเจกต์ที่มีไฟล์มากกว่า 10,000 ไฟล์ ให้พิจารณา metro-memory-fs สำหรับแคชในหน่วยความจำ
สรุป
watchFolders และ extraNodeModules เพื่อการแก้ไขโมดูลที่ถูกต้องเราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ