Metro は、React Native専用に開発され、このプラットフォームでモバイルアプリケーションをビルドするためのデフォルトのJavaScriptバンドラーです。汎用バンドラーとは異なり、Metroはモバイルデバイスの限られたリソースに最適化されており、HermesエンジンおよびFast Refreshとの統合を提供します。Metro Documentation (2026) によると、このバンドラーは世界のReact Nativeプロジェクトの90%以上を処理しています。
重要ポイント
Metro は、MetaチームがReact Native向けに作成したオープンソースのJavaScriptバンドラーです。これは初期のReact NativeバージョンのPackagerを置き換え、このプラットフォームの標準ビルドツールになりました。Metroはウェブ開発用に設計されていません。そのアーキテクチャは、JSC(JavaScriptCore)またはHermes JavaScriptエンジン上で動作するモバイルアプリケーションにのみ焦点を当てています。
Metro は2018年に古いReact Native Packagerの後継として登場しました。作成の主な理由は、大規模なモバイルアプリケーションで数百万のモジュールを効率的に処理できるバンドラーの必要性でした。Webpack とは異なり、MetroはCSS、HTML、画像をモジュールとしてサポートしません。これらのリソースは別のReact Nativeツールによって処理されます。Facebook は10万以上のファイルを含むメインアプリケーションのビルドにMetroを使用しています。
Metroはnpmパッケージ metro として配布され、React Native CLIとともに自動的にインストールされます。MetroのバージョンはReact Nativeのバージョンに紐づいており、バンドラーのアップデートはプラットフォームのアップデートとともに行われます。
Metro はアプリケーションのエントリーポイントを入力として受け取り、依存関係グラフを構築し、各モジュールを変換して、結果を単一のバンドルにシリアライズします。プロセスは3つのフェーズを経ます: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 フェーズでは、変換されたすべてのモジュールを1つ以上のバンドルファイルにまとめます。
Metro はモジュラーアーキテクチャに基づいて構築されており、ビルドの各段階が独立したコンポーネントとして実装されています。これにより、バンドラーのコアを変更することなく、標準モジュールをカスタムモジュールに置き換えることができます。Metroアーキテクチャには、metro、metro-config、metro-resolver の3つの主要パッケージが含まれます。
Metro Server は、npx react-native start コマンドで起動する開発サーバーです。リアルタイムでモジュール変換リクエストを処理し、Fast Refreshを提供します。Module Store は、再ビルドを高速化するために変換済みモジュールをメモリに保存するキャッシュです。Dependency Graph は、ファイル変更時に増分的に更新される依存関係グラフです。
Watchman は、Metroがファイルシステムの変更を検出するために使用するMetaのファイル監視ツールです。Watchmanがない場合、Metroは変更のたびにファイル構造全体を再スキャンする必要があり、開発が大幅に遅くなります。Watchmanのインストールは、任意の規模のプロジェクトで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 を使用してバンドルの構成を分析し、遅延ロード可能な大きなモジュールを見つけます。定期的なバンドルサイズチェックは、React NativeプロジェクトのCI/CDパイプラインの一部にする必要があります。
Metro はデルタバンドルをサポートしています。これは、最初の完全ビルド後、サーバーが古いバンドルと新しいバンドルの差分(デルタ)のみを送信する仕組みです。これにより、後続のビルドが劇的に高速化されます。更新時間が秒から数十ミリ秒に短縮されます。デルタバンドルは、開発者が頻繁に変更を保存してアプリケーションをリロードする開発段階で特に効果的です。
React Nativeでデルタバンドルを有効にするには、npx react-native bundle コマンドで --delta フラグを使用します。クライアント側では、デルタバンドルはReact Native 0.64以降でサポートされています。プロダクションビルドではデルタバンドルは使用されません。代わりに、最大の起動パフォーマンスを得るためにHermesバイトコードを含む完全なバンドルが使用されます。これは、開発速度の向上が最初の完全ビルドのコストを相殺するためです。
Hermes は、MetaがReact Native専用に開発したJavaScriptエンジンです。Metroはビルド時にHermesバイトコードを生成し、アプリケーションがデバイス上で負荷の高いJavaScriptコンパイルを行わずに起動できるようにします。Hermesを有効にするには、metro.config.js に enableHermes: true を追加し、build.gradleまたはPodfileを設定します。HermesはJavaScriptCoreと比較して、アプリケーションの起動時間を30~50%短縮し、APKサイズを20~30%削減します。
Hermesを使用する際は、その制限を覚えておくことが重要です。このエンジンは Proxy、Reflect、および一部のES6機能をサポートしていません。ほとんどのReact Nativeアプリケーションはこれらの機能を直接使用しませんが、一部のライブラリは競合する可能性があります。Hermesを有効にする前に、公式互換性チェックリスト ですべてのプロジェクト依存関係の互換性を確認してください。Hermesがアクティブ化されると、Metroは自動的にバイトコード生成モードに切り替わります。
Metroビルドの効率を追跡するには、Flipper(React Nativeデバッグツール)から利用可能な組み込みメトリクスを使用します。Metroは各段階の実行時間とともにイベント(bundle_request、transform、resolve)を公開します。このデータを分析するとボトルネックを特定できます。Transformフェーズが時間の70%以上を占める場合、問題はBabelトランスフォーマーにあります。--verbose フラグを使用してMetroのログ記録を有効にし、詳細な診断を行います。
よくある質問
技術的には可能です。react-native-webpack のような実験的プロジェクトは存在しますが、公式にはサポートされていません。Metro はReact Nativeブリッジ、Turbo Modules、Hermesと、Webpackにはないレベルで統合されています。Metroを置き換えると、Fast Refreshと公式サポートが失われます。
React Nativeはスタイリングに CSS を使用せず、代わりに StyleSheet.create によるJavaScriptスタイリングを適用します。MetroはReact Native専用に作られているため、CSSサポートは不要です。React Native Webを介したウェブレンダリングでは、CSSはMetro外部の別ツールで処理されます。
Metro は画像やフォントをモジュールとして処理しません。リソースは require('./image.png') でインポートされますが、Metroはそれらを文字列の依存関係として登録するだけです。実際の画像読み込みはReact Nativeのネイティブコードによって Image コンポーネントを介して実行され、Metroはリソースをバンドルにコピーします。
Rollup はモジュールレベルのツリーシェイキングでESモジュールを生成し、ライブラリのバンドルサイズを最小限に抑えます。Metro はインライン変換とモバイルエンジン向け最適化を備えたCommonJSバンドルを生成します。RollupはFast Refreshをサポートしておらず、React Nativeのネイティブモジュールと連携できません。
Metroのコールドビルドは、node_modules の完全スキャンにより遅くなります。解決策:モノレポには watchFolders を追加し、並列変換には maxWorkers を使用し、Watchman をインストールします。10,000ファイル以上のプロジェクトでは、メモリキャッシュに metro-memory-fs を検討してください。
まとめ
watchFolders と extraNodeModules の設定が必要です。ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。