### Install Metro with npm Source: https://metrobundler.dev/docs/getting-started Install Metro and metro-core as development dependencies using npm. ```bash npm install --save-dev metro metro-core ``` -------------------------------- ### Basic Package Exports Configuration Source: https://metrobundler.dev/docs/package-exports A minimal example demonstrating how to export a single main entry point for a package. ```json { "exports": { "./FooComponent": "./src/FooComponent.js" } } ``` -------------------------------- ### Install Metro with yarn Source: https://metrobundler.dev/docs/getting-started Install Metro and metro-core as development dependencies using yarn. ```bash yarn add --dev metro metro-core ``` -------------------------------- ### Run Metro server with default options Source: https://metrobundler.dev/docs/getting-started Start a Metro development server using the runServer method with default options. This is a minimal configuration to get the server running. ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config); ``` -------------------------------- ### Run a server and watch the filesystem for changes Source: https://metrobundler.dev/docs/api Starts a full Metro HTTP server that listens for bundle requests and watches the filesystem for changes. ```APIDOC ## runServer ### Description Starts a full Metro HTTP server that listens on a specified host and port, serving bundles and watching for file changes. ### Method `runServer(config, options)` ### Parameters #### Options - **config** (object) - Metro configuration object. - **host** (string) - Optional - The host to listen on. - **port** (number) - Optional - The port to listen on. - **secureServerOptions** (object) - Optional - Options for configuring HTTPS. - **secure** (DEPRECATED) - **secureKey** (DEPRECATED) - **secureCert** (DEPRECATED) ### Request Example ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config); ``` ``` -------------------------------- ### Run Development Server Source: https://metrobundler.dev/docs/api Start a Metro development server that watches the filesystem for changes. This is useful for development workflows. ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config); ``` -------------------------------- ### Metro Performance Logger Factory Example Source: https://metrobundler.dev/docs/configuration Provides a no-op implementation for the unstable_perfLoggerFactory, which is used to log Metro performance timings. This example shows how to return an object implementing the RootPerfLogger interface. ```javascript const unstable_perfLoggerFactory = (type, factoryOpts) => { const getLogger = subSpanLabel => { const logger = { start(opts) {}, end(status, opts) {}, subSpan(label) { return getLogger(`${subSpanLabel ?? ''}/${label}`); }, point(name, opts) {}, annotate(annotations) {}, }; return logger; }; return getLogger(); }; ``` -------------------------------- ### runServer(config, options) Source: https://metrobundler.dev/docs/getting-started Starts a development server based on the given configuration and options. It returns an object containing the Node.js HTTP(S) server. It is recommended to use `runMetro` instead, as `runMetro` internally calls this function. ```APIDOC ## runServer(config, options) ### Description Starts a development server based on the given configuration and options. Returns an object with `httpServer`, the Node.js HTTP(S) server. We recommend using `runMetro` instead of `runServer`, `runMetro` calls this function. ### Method `runServer(config, options)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options * `host (string)`: Where to host the server on. * `onReady (Function)`: Called when the server is ready to serve requests. * `onClose (Function)`: Called when the server and all other Metro processes are closed. You can also observe the server close event directly using `httpServer.on('close', () => {});`. * `secure (boolean)`: **DEPRECATED** Whether the server should run on `https` instead of `http`. * `secureKey (string)`: **DEPRECATED** The key to use for `https` when `secure` is on. * `secureCert (string)`: **DEPRECATED** The cert to use for `https` when `secure` is on. * `secureServerOptions (Object)`: The options object to pass to Metro's HTTPS server. The presence of this object will make Metro's server run on `https`. Refer to the Node docs for valid options. * `waitForBundler (boolean)`: Whether to wait for the bundler to finish initializing before returning the server instance. ### Request Example ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config, { onClose: () => {console.log('metro server and all associated processes are closed')} }); httpServer.on('close', () => {console.log('metro server is closed')}); ``` ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config); ``` ```javascript const fs = require('fs'); const config = await Metro.loadConfig(); await Metro.runServer(config, { secureServerOptions: { ca: fs.readFileSync('path/to/ca'), cert: fs.readFileSync('path/to/cert'), key: fs.readFileSync('path/to/key'), } }); ``` ### Response #### Success Response (200) Returns an object with `httpServer`, the Node.js HTTP(S) server. #### Response Example ```json { "httpServer": "Node.js HTTP(S) server instance" } ``` ``` -------------------------------- ### Example Source Map Structure Source: https://metrobundler.dev/docs/source-map-format Illustrates a complete source map for a single JavaScript file, including standard fields and extended Facebook-specific metadata. ```json { "version": 3, "sources": ["file.js"], "sourcesContent": ["function a(){} function b()"], "mappings": "AAAA", "x_facebook_sources": [ [ { "mappings": "AAA,cC,CC", "names": [ "a", "", "b" ] } ] ] } ``` -------------------------------- ### Importing a React Native Module Source: https://metrobundler.dev/docs/resolution Example of importing a core module like 'react-native'. Metro resolves this to its location within the node_modules directory. ```javascript // src/App.js import {View} from 'react-native'; // ... ``` -------------------------------- ### Importing a Local Module Source: https://metrobundler.dev/docs/resolution Example of importing a local module using a relative path. Metro resolves this to the specified file within the project structure. ```javascript // src/App.js import Comp from './Component'; // ... ``` -------------------------------- ### runMetro(config) Source: https://metrobundler.dev/docs/getting-started Runs the Metro bundler with the given configuration and returns a Metro server instance. This instance can then be used to process HTTP requests, for example, by hooking it into an HTTP server or using it as an Express middleware. ```APIDOC ## runMetro(config) ### Description Given the config, a `metro-server` will be returned. You can then hook this into a proper HTTP(S) server by using its `processRequest` method. ### Method `runMetro(config)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript 'use strict'; const http = require('http'); const Metro = require('metro'); // We first load the config from the file system Metro.loadConfig().then(async (config) => { const metroBundlerServer = await Metro.runMetro(config); const httpServer = http.createServer( metroBundlerServer.processRequest.bind(metroBundlerServer), ); httpServer.listen(8081); }); ``` ### Response #### Success Response (200) Returns a `metro-server` instance. #### Response Example ```json { "metro-server": "instance" } ``` ### Error Handling Metro does not know how to handle the request. ``` -------------------------------- ### Run Metro server with HTTPS options Source: https://metrobundler.dev/docs/getting-started Start a Metro development server using HTTPS by providing secureServerOptions. This includes reading certificate and key files for secure communication. ```javascript const fs = require('fs'); const config = await Metro.loadConfig(); await Metro.runServer(config, { secureServerOptions: { ca: fs.readFileSync('path/to/ca'), cert: fs.readFileSync('path/to/cert'), key: fs.readFileSync('path/to/key'), } }); ``` -------------------------------- ### Legacy Resolution Fallback Example Source: https://metrobundler.dev/docs/package-exports Shows how Metro attempts to resolve a module import when the package.json does not have an 'exports' field, falling back to legacy resolution strategies. ```javascript import FooComponent from 'some-pkg/FooComponent'; // Tries .[platform].js, .native.js, .js (+ TypeScript variants) ``` -------------------------------- ### Start Metro Development Server Source: https://metrobundler.dev/docs/local-development Run the Metro development server within your target React Native project. Remember to restart this command after modifying Metro code or the `metro.config.js` file. ```bash yarn react-native start ``` -------------------------------- ### Merge Multiple Metro Configurations Source: https://metrobundler.dev/docs/configuration This example demonstrates merging default configurations with custom settings using both function and object forms. It extends `additionalExts` and sets a `minifierPath`. Use this when you need to layer multiple configuration adjustments. ```typescript // metro.config.ts import type {ConfigT} from 'metro-config'; import {mergeConfig} from 'metro-config'; export default (defaults: ConfigT) => mergeConfig( defaults, // Function form: extends the default additionalExts config => ({ watcher: {additionalExts: [...config.watcher.additionalExts, 'mts', 'cts']}, }), // Plain object form {transformer: {minifierPath: 'metro-minify-terser'}}, // Function form: additionalExts already includes 'mts' and 'cts' from above config => ({ watcher: {additionalExts: [...config.watcher.additionalExts, 'css']}, }), ); ``` -------------------------------- ### Run Metro server with onClose callback Source: https://metrobundler.dev/docs/getting-started Start a Metro development server and log a message when the server and all associated processes are closed. This uses the runServer method with a custom onClose handler. ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config, { onClose: () => {console.log('metro server and all associated processes are closed')} }); httpServer.on('close', () => {console.log('metro server is closed')}); ``` -------------------------------- ### Exports Subpath Resolution Example Source: https://metrobundler.dev/docs/package-exports Illustrates how Metro resolves an import when the requested subpath is explicitly defined in the 'exports' field of package.json, using the exact target file. ```javascript import FooComponent from 'some-pkg/FooComponent'; // Resolves exact target from "exports" only ``` -------------------------------- ### Enable Metro Debug Logging Source: https://metrobundler.dev/docs/local-development Set the `DEBUG` environment variable to a pattern matching Metro debug scopes before starting Metro to enable logs. This pattern matches all Metro-defined messages. ```bash DEBUG='Metro:*' yarn metro serve ``` -------------------------------- ### Configure TLS Options for HTTPS Server Source: https://metrobundler.dev/docs/configuration Provides an object structure for configuring TLS options when Metro starts an HTTPS server. This includes certificate authority, server certificate, private key, and certificate request options. ```javascript ca?: string | Buffer, cert?: string | Buffer, key?: string | Buffer, requestCert?: boolean, ``` -------------------------------- ### Custom Cache Store Interface Source: https://metrobundler.dev/docs/caching Defines the interface for implementing custom cache stores in Metro. This includes methods for getting, setting, and clearing cache entries. ```typescript interface CacheStore { // Read an entry from the cache. Returns `null` if not found. get(key: Buffer): ?T | Promise; // Write an entry to the cache (if writable) or do nothing (if read-only) set(key: Buffer, value: T): void | Promise; // Clear the cache (if possible) or do nothing clear(): void | Promise; } type JsonSerializable = /* Any JSON-serializable value */; ``` -------------------------------- ### Get Transform Options Function Signature Source: https://metrobundler.dev/docs/configuration Defines the expected signature for the `getTransformOptions` function, which allows custom logic for transformer and serializer options based on bundle specifics. ```javascript function getTransformOptions( entryPoints: $ReadOnlyArray, options: { dev: boolean, hot: boolean, platform: ?string, }, getDependenciesOf: (path: string) => Promise>, ): Promise { // ... } ``` -------------------------------- ### Basic require() usage Source: https://metrobundler.dev/docs/module-api Demonstrates how to use require() to import local modules, assets, JSON files, and components from packages. ```javascript const localModule = require('./path/module'); const asset = require('./path/asset.png'); const jsonData = require('./path/data.json'); const {View} = require('react-native'); ``` -------------------------------- ### runMetro Source: https://metrobundler.dev/docs/api Creates and returns a Metro server based on the provided configuration. ```APIDOC ## runMetro ### Description Creates a Metro server instance based on the provided configuration. This server can be used as middleware in other applications. ### Method `runMetro(config)` ### Parameters #### Parameters - **config** (object) - Required - The Metro configuration object. ### Response - **server** (object) - The Metro server instance. ``` -------------------------------- ### Build a JavaScript Bundle with runBuild Source: https://metrobundler.dev/docs/getting-started Use `runBuild` to create a production-ready JavaScript bundle. Specify entry point, platform, minification, and output path. ```javascript const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', platform: 'ios', minify: true, out: '/Users/Metro/metro-ios.js' }); ``` -------------------------------- ### Create a Connect middleware and plug it into a server Source: https://metrobundler.dev/docs/api Creates a Connect middleware that can be plugged into an existing server to handle Metro bundle requests. ```APIDOC ## createConnectMiddleware ### Description Creates a Connect middleware that handles Metro bundle requests, allowing integration into custom servers. It can optionally invoke a callback when a bundle is built. ### Method `createConnectMiddleware(config, options)` ### Parameters #### Options - **config** (object) - Metro configuration object. - **port** (number) - Optional - The port number for logging purposes. - **onBundleBuilt** (function) - Optional - A callback function invoked when a bundle is finished building. ### Request Example ```javascript const Metro = require('metro'); const express = require('express'); const app = express(); const server = require('http').Server(app); Metro.loadConfig().then(async config => { const connectMiddleware = await Metro.createConnectMiddleware(config); const {server: {port}} = config; app.use(connectMiddleware.middleware); server.listen(port); connectMiddleware.attachHmrServer(server); }); ``` ### Response - **middleware** (function) - The Connect middleware function. - **attachHmrServer** (function) - A function to attach HMR server. ``` -------------------------------- ### Compile a File Source: https://metrobundler.dev/docs/api Use this snippet to compile a single entry file into a bundle. Specify the entry and output file paths in the configuration. ```javascript const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', out: 'bundle.js', }); ``` -------------------------------- ### runBuild(config, options) Source: https://metrobundler.dev/docs/getting-started Builds a bundle given a configuration and options. Returns a Promise that resolves to an object containing the bundle code, map, and optionally assets. This method is useful at build time. ```APIDOC ## Method `runBuild(config, options)` ### Description Builds a bundle given a configuration and options. Returns a Promise that resolves to an object containing the bundle code, map, and optionally assets. This method is useful at build time. ### Parameters #### Options - **assets** (boolean): Whether to include the assets in the result. - **bundleOut** (string): Path to save the bundle. No extension will be added. - **dev** (boolean): Create a development version of the build (`process.env.NODE_ENV = 'development'`). - **entry** (string): Pointing to the entry file to bundle. - **onBegin** (Function): Called when the bundling starts. - **onComplete** (Function): Called when the bundling finishes. - **onProgress** (Function): Called during the bundle, every time there's new information available about the module count/progress. - **minify** (boolean): Whether Metro should minify the bundle. - **out** (string): Shorthand path to the output bundle and source map. A `.js` extension will be added (if not given) for the bundle and `.map` for the source map. Customize with `bundleOut` / `sourceMapOut`. - **platform** ('web' | 'android' | 'ios'): Which platform to bundle for if a list of platforms is provided. - **sourceMap** (boolean): Whether Metro should generate source maps. - **sourceMapOut** (string): Where to save the source map, if `sourceMap == true`. No extension will be added. - **sourceMapUrl** (string): URL where the source map can be found. It defaults to the same same URL as the bundle, but changing the extension from `.bundle` to `.map`. When `inlineSourceMap` is `true`, this property has no effect. ### Request Example ```javascript const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', platform: 'ios', minify: true, out: '/Users/Metro/metro-ios.js' }); ``` ``` -------------------------------- ### Configure Local FileStore Cache Source: https://metrobundler.dev/docs/caching Sets up a local cache using `FileStore` to store transformed modules. The cache directory is dynamically determined using the operating system's temporary directory. ```javascript const os = require('node:os'); const path = require('node:path'); module.exports = { cacheStores: ({ FileStore }) => [ new FileStore({ root: path.join(os.tmpdir(), 'metro-cache'), }), ], }; ``` -------------------------------- ### createConnectMiddleware(config) Source: https://metrobundler.dev/docs/getting-started Creates a Connect middleware that answers to bundle requests, allowing integration into custom servers. The port parameter is optional and used for logging purposes. ```APIDOC ## Method `createConnectMiddleware(config)` ### Description Creates a Connect middleware that answers to bundle requests, allowing integration into custom servers. The port parameter is optional and used for logging purposes. ### Parameters #### Options - **port** (number): Port for the Connect middleware (only for logging purposes). ### Request Example ```javascript const Metro = require('metro'); const express = require('express'); const app = express(); const server = require('http').Server(app); Metro.loadConfig().then(async config => { const connectMiddleware = await Metro.createConnectMiddleware(config); const {server: {port}} = config; app.use(connectMiddleware.middleware); server.listen(port); connectMiddleware.attachHmrServer(server); }); ``` ``` -------------------------------- ### Advanced require() at runtime Source: https://metrobundler.dev/docs/module-api Shows how to use require() with a module ID obtained from require.resolveWeak() to bypass non-constant argument restrictions. ```javascript const localModule = require('./path/module'); const id = require.resolveWeak('./path/module'); // Bypass the restriction on non-constant require() arguments const dynamicRequire = require; dynamicRequire(id) === localModule; // true ``` -------------------------------- ### Custom Resolver for Package Exports in Metro Source: https://metrobundler.dev/docs/package-exports Implement a custom resolver in your Metro configuration to specify how certain packages should be resolved, for example, by prioritizing the 'browser' condition for specific modules like 'some-pkg'. This is useful for handling packages not explicitly designed for React Native. ```javascript // metro.config.js const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); /** * Metro configuration * https://reactnative.dev/docs/metro * * @type {import('@react-native/metro-config').MetroConfig} */ const config = { resolver: { resolveRequest: () => { (context, moduleImport, platform) { // Use the browser version of the package for React Native if (moduleImport === 'some-pkg' || moduleImport.startsWith('some-pkg/')) { return context.resolveRequest( { ...context, unstable_conditionNames: ['browser'], // Alternatively, disable exports for this package // unstable_enablePackageExports: false }, moduleImport, platform, ); } // Fall back to normal resolution for everything else. return context.resolveRequest(context, moduleImport, platform); } } }; module.exports = mergeConfig(getDefaultConfig(__dirname), config); ``` -------------------------------- ### Compile a file Source: https://metrobundler.dev/docs/api Compiles a single entry file into an output bundle file. ```APIDOC ## runBuild ### Description Bundles an entry file for a given platform and saves it to a specified output location. Optionally generates a source map. ### Method `runBuild(config, options)` ### Parameters #### Options - **config** (object) - Metro configuration object. - **entry** (string) - Required - The entry file for the bundle. - **out** (string) - Required - The output file path for the bundle. - **dev** (boolean) - Optional - Whether to build in development mode. - **minify** (boolean) - Optional - Whether to minify the bundle. - **platform** (string) - Optional - The target platform (e.g., 'ios', 'android'). - **sourceMap** (boolean) - Optional - Whether to generate a source map. - **sourceMapUrl** (string) - Optional - The URL for the source map. - **assets** (boolean) - Optional - Whether to generate asset data. ### Request Example ```javascript const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', out: 'bundle.js', }); ``` ### Response - **assets** (array) - Optional - An array of AssetData if `assets` option is true. ``` -------------------------------- ### Create Connect Middleware Source: https://metrobundler.dev/docs/api Integrate Metro's bundling capabilities into your existing Express server by creating Connect middleware. This allows you to serve bundles from your own HTTP server. ```javascript const Metro = require('metro'); const express = require('express'); const app = express(); const server = require('http').Server(app); Metro.loadConfig().then(async config => { const connectMiddleware = await Metro.createConnectMiddleware(config); const {server: {port}} = config; app.use(connectMiddleware.middleware); server.listen(port); connectMiddleware.attachHmrServer(server); }); ``` -------------------------------- ### Define Package Entry Points with 'exports' Source: https://metrobundler.dev/docs/package-exports Explicitly define all public entry points for your package using the 'exports' field. This ensures a well-defined public API and compatibility with existing resolution. ```json { "exports": { ".": "./src/index.js", "./FooComponent": "./src/FooComponent.js", "./FooComponent.js": "./src/FooComponent.js" } } ``` -------------------------------- ### Importing with Exact Subpath in Exports Source: https://metrobundler.dev/docs/package-exports Demonstrates an import statement that requires the exact subpath key to be present in the 'exports' field of package.json. Importing with a '.js' extension will fail if only './FooComponent' is exported. ```javascript import FooComponent from 'some-pkg/FooComponent.js'; // Inaccessible unless the package had also listed "./FooComponent.js" // as an "exports" key ``` -------------------------------- ### Basic Metro Configuration Structure Source: https://metrobundler.dev/docs/configuration This is a basic structure for a Metro configuration file using ESM syntax. It outlines the main configuration sections like resolver, transformer, serializer, server, and watcher. Ensure you import the MetroConfig type for type safety. ```typescript // metro.config.mts import type {MetroConfig} from 'metro-config'; const config: MetroConfig = { /* general options */ resolver: { /* resolver options */ }, transformer: { /* transformer options */ }, serializer: { /* serializer options */ }, server: { /* server options */ }, watcher: { /* watcher options */ watchman: { /* Watchman-specific options */ } } }; export default config; ``` -------------------------------- ### Run Metro programmatically with HTTP server Source: https://metrobundler.dev/docs/getting-started Load configuration, run Metro, and hook its processRequest method into an HTTP server. The server listens on port 8081. ```javascript 'use strict'; const http = require('http'); const Metro = require('metro'); // We first load the config from the file system Metro.loadConfig().then(async (config) => { const metroBundlerServer = await Metro.runMetro(config); const httpServer = http.createServer( metroBundlerServer.processRequest.bind(metroBundlerServer), ); httpServer.listen(8081); }); ``` -------------------------------- ### loadConfig Source: https://metrobundler.dev/docs/api Loads the Metro configuration, either from a specified option or by traversing the directory hierarchy. ```APIDOC ## loadConfig ### Description Loads the Metro configuration. It can be provided directly via the `config` option or found by searching the directory hierarchy from `cwd` for a configuration file (defaulting to `metro.config.js`). The loaded configuration is normalized and merged with Metro's defaults. ### Method `loadConfig(options)` ### Parameters #### Options - **config** (object) - Optional - The Metro configuration object to load. - **cwd** (string) - Optional - The directory to start searching for the configuration file from. ### Response - **config** (object) - The normalized and merged Metro configuration object. ``` -------------------------------- ### Link Metro Packages in Target Project Source: https://metrobundler.dev/docs/local-development In your target React Native project, use `yarn link ` to apply the locally registered Metro packages. At a minimum, `metro` and `metro-runtime` should be linked. ```bash yarn link metro metro-config metro-runtime ``` -------------------------------- ### Link Local Metro Packages Source: https://metrobundler.dev/docs/local-development Use `yarn link` within your Metro clone to register local packages. This command links all packages in the Metro repository. ```bash npm exec --workspaces -- yarn link ``` -------------------------------- ### Exporting Assets with Subpath Patterns Source: https://metrobundler.dev/docs/package-exports Export asset files, especially those with multiple densities, using subpath patterns in the 'exports' field. Specifying the file extension is recommended for asset subpaths. ```json { "exports": { "./assets/*.png": "./dist/assets/*.png" } } ``` -------------------------------- ### Configure Metro watchFolders for Linked Packages Source: https://metrobundler.dev/docs/local-development Add `watchFolders` to your `metro.config.js` to inform Metro about files included via `yarn link`. This ensures Metro follows symlinks to linked modules. ```javascript + const path = require('path'); module.exports = { watchFolders: [ path.resolve(__dirname, './node_modules'), // Include necessary file paths for `yarn link`ed modules path.resolve(__dirname, '../metro/packages'), path.resolve(__dirname, '../metro/node_modules'), ], ... }; ``` -------------------------------- ### Platform-Specific Component Loading with Platform.select Source: https://metrobundler.dev/docs/package-exports When replacing platform-specific extensions, use the 'Platform.select()' API within your component files to conditionally require platform-specific modules. This is recommended over custom conditions for 'android' and 'ios'. ```javascript // src/FooComponent.js const FooComponent = Platform.select({ android: require('./FooComponentAndroid.js'), ios: require('FooComponentIOS.js'), }); export default FooComponent; ``` -------------------------------- ### Haste Implementation Signature Source: https://metrobundler.dev/docs/configuration When using Haste for global module names, the `hasteImplModulePath` should point to a module that exports a `getHasteName` function. This function takes a file path and returns a unique Haste name or null. ```javascript module.exports = { getHasteName(filePath: string): ?string { // ... }, }; ``` -------------------------------- ### Indexed RAM Bundle Structure Source: https://metrobundler.dev/docs/bundling Visual representation of the Indexed RAM bundle's binary structure, including magic number, header, offset table, and code modules. This format is optimal for environments that can load all code into memory simultaneously. ```text ` 0 1 2 3 4 5 6 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Magic number | Header size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Startup code size | Module 0 offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Module 0 length | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + ... + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Module n offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Module n length | Module 0 code | Module 0 code | ... | \0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Module 1 code | Module 1 code | ... | \0 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + ... + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Module n code | Module n code | ... | \0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+` ``` -------------------------------- ### Transform JavaScript with Babel Core Source: https://metrobundler.dev/docs/getting-started Integrate Babel Core into the transformer to transpile JavaScript code. Pass the source code to `transformSync` with your desired Babel options. ```javascript const {transformSync} = require('@babel/core'); module.exports.transform = file => { return transformSync(file.src, { // Babel options... }); }; ``` -------------------------------- ### Integrate Metro with a custom HTTP server Source: https://metrobundler.dev/docs/getting-started Handle requests that Metro cannot process by providing a callback to processRequest. This allows integration with existing or new server logic. ```javascript const httpServer = http.createServer((req, res) => { metroBundlerServer.processRequest(req, res, () => { // Metro does not know how to handle the request. }); }); ``` -------------------------------- ### Use Subpath Patterns for Utility Exports Source: https://metrobundler.dev/docs/package-exports Employ subpath patterns in the 'exports' field to map multiple utility files. This shorthand matches nested directories but does not permit path expansion beyond the pattern. ```json { "exports": { ".": "./index.js", "./utils/*": "./utils/*.js" } } ``` -------------------------------- ### Parse JavaScript to AST with Babylon Source: https://metrobundler.dev/docs/getting-started Use this transformer to parse JavaScript source code into an Abstract Syntax Tree (AST) using Babylon. This is the default transformer that performs the minimum required work. ```javascript const babylon = require('@babel/parser'); module.exports.transform = (file: {filename: string, src: string}) => { const ast = babylon.parse(file.src, {sourceType: 'module'}); return {ast}; }; ``` -------------------------------- ### Package.json with Exact Subpath Export Source: https://metrobundler.dev/docs/package-exports This JSON defines an 'exports' field in package.json where a specific subpath './FooComponent' is mapped to its corresponding file './src/FooComponent.js'. ```json { "name": "some-pkg", "exports": { "./FooComponent": "./src/FooComponent.js" } } ``` -------------------------------- ### Require Metro module Source: https://metrobundler.dev/docs/getting-started Load the Metro module in your JavaScript code. ```javascript const Metro = require('metro'); ``` -------------------------------- ### ESM Import Resolution with Exports Source: https://metrobundler.dev/docs/package-exports Demonstrates how an ES Module import statement ('import') is resolved by Metro when the package.json includes an 'exports' field with an 'import' condition. ```javascript import Foo from 'some-pkg'; ``` -------------------------------- ### Enhance Metro Middleware with Custom Handlers Source: https://metrobundler.dev/docs/configuration Use this function to attach custom connect middleware to Metro. It allows extending the base `metroMiddleware` or mounting additional handlers for specific endpoints. ```javascript enhanceMiddleware: (metroMiddleware: Middleware, metroServer: MetroServer) => { return connect() .use(metroMiddleware) .use('/custom-endpoint', customEndpointMiddleware()); }, ``` -------------------------------- ### getPackageForModule Source: https://metrobundler.dev/docs/resolution Retrieves package information for a given module path. It searches upwards from the provided path to find the nearest package root, parses the package.json, and returns the package-relative path. This function is deprecated. ```APIDOC ## `getPackageForModule: (absoluteModulePath: string) => ?PackageInfo` **Deprecated** Given a candidate absolute module path that may exist under a package, locates and returns the closest package root (working upwards from the given path, stopping at the nearest `node_modules`), parsed `package.json` contents, and the package-relative path of the given path. ``` -------------------------------- ### Metro's Lenient Package Encapsulation Warning Source: https://metrobundler.dev/docs/package-exports This warning is logged by Metro when a module is imported that is not explicitly listed in the package's 'exports'. Metro falls back to file-based resolution instead of throwing an error. ```text warn: You have imported the module "foo/private/fn.js" which is not listed in the "exports" of "foo". Consider updating your call site or asking the package maintainer(s) to expose this API. ``` -------------------------------- ### Custom Resolver Function Signature Source: https://metrobundler.dev/docs/resolution Defines the signature for a custom `resolveRequest` function. It receives the resolution context, module name, and platform, returning a Resolution object. ```javascript function resolveRequest( context: ResolutionContext, moduleName: string, platform: string | null, ): Resolution { // ... } type Resolution = | {type: 'empty'} | {type: 'sourceFile', filePath: string} | {type: 'assetFiles', filePaths: $ReadOnlyArray}; ``` -------------------------------- ### CommonJS Require Resolution with Exports Source: https://metrobundler.dev/docs/package-exports Illustrates how a CommonJS require statement ('require') is resolved by Metro when the package.json includes an 'exports' field with a 'require' condition. ```javascript const Foo = require('some-pkg'); ``` -------------------------------- ### Package.json with Exports Field Source: https://metrobundler.dev/docs/package-exports This JSON defines the 'exports' field in a package.json file, specifying different entry points for CommonJS ('require') and ES Module ('import') environments. ```json { "name": "some-pkg", "version": "1.0.0", "main": "./dist/cjs/index.js", "exports": { ".": { "import": "./dist/esm/index.mjs", "require": "./dist/cjs/index.js" } } } ``` -------------------------------- ### resolveHasteModule Source: https://metrobundler.dev/docs/resolution Resolves a Haste module name to its absolute file path. If the module is not found, it returns null. This is the primary function for resolving modules within the Haste ecosystem. ```APIDOC ## `resolveHasteModule: string => ?string` Resolves a Haste module name to an absolute path. Returns `null` if no such module exists. The default implementation of this function uses metro-file-map's `getModule` method. ```