### Install Metro with npm Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Install Metro and metro-core as development dependencies using npm. ```bash npm install --save-dev metro metro-core ``` -------------------------------- ### Start Development Server Source: https://github.com/react/metro/blob/main/website/README.md Starts the local development server for the Metro website. Access the site at http://localhost:3000. Changes are automatically updated on refresh. ```bash npm start ``` -------------------------------- ### Install Metro with yarn Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Install Metro and metro-core as development dependencies using yarn. ```bash yarn add --dev metro metro-core ``` -------------------------------- ### Install Dependencies Source: https://github.com/react/metro/blob/main/CONTRIBUTING.md Install project dependencies using Yarn. ```sh yarn ``` -------------------------------- ### Example Source Map with Metadata Tuple Source: https://github.com/react/metro/blob/main/docs/SourceMapFormat.md A complete source map example for a single JavaScript file, including the 'x_facebook_sources' field for metadata tuples and a function map. ```json { "version": 3, "sources": ["file.js"], "sourcesContent": ["function a(){} function b(){}"], "mappings": "AAAA", // NOTE: Simplified "x_facebook_sources": [ // Metadata tuple for source #0 (file.js) [ // Metadata item #0.0 = function map for source #0 (file.js) { // a from 1:0 // from 1:14 // b from 1:15 // (See detailed decoding procedure below.) "mappings": "AAA,cC,CC", "names": [ "a", "", "b", ] } ] ] } ``` -------------------------------- ### Enable Metro Debug Logging Source: https://github.com/react/metro/blob/main/docs/LocalDevelopment.md Set the `DEBUG` environment variable before starting Metro to enable logs matching the specified pattern. This example shows how to match all Metro-defined messages. ```sh DEBUG='Metro:*' yarn metro serve ``` -------------------------------- ### Run Metro and hook into HTTP server Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Load configuration, run Metro, and create an HTTP server using its processRequest method. This example shows how to integrate Metro with a standard Node.js HTTP server. ```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); }); ``` -------------------------------- ### Basic Metro Configuration Structure Source: https://github.com/react/metro/blob/main/docs/Configuration.md A foundational example of a Metro configuration file, illustrating the placement of general options and specific configurations for resolver, transformer, serializer, server, and watcher. ```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; ``` -------------------------------- ### Metro.runServer Source: https://github.com/react/metro/blob/main/docs/API.md Starts a full Metro HTTP server that can be queried for bundles. Supports HTTPS with secure server options. ```APIDOC ## Metro.runServer(config, ) ### Description Starts a full Metro HTTP server. It will listen on the specified `host:port`, and can then be queried to retrieve bundles for various entry points. If the `secureServerOptions` family of options are present, the server will be exposed over HTTPS. `secure`, `secureKey`, `secureCert` are now deprecated and will be removed in a later release. The presence of `secureServerOptions`, along with its options will make Metro run over https. ### Method Asynchronous function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options **Basic options:** `host`, `port`, `secureServerOptions`, `secure (DEPRECATED)`, `secureKey (DEPRECATED)`, `secureCert (DEPRECATED)` ``` -------------------------------- ### Importing from node_modules Source: https://github.com/react/metro/blob/main/docs/Resolution.md Example of importing a module from the node_modules directory. Metro resolves this to the module's entry point, typically index.js. ```javascript // src/App.js import {View} from 'react-native'; // ... ``` -------------------------------- ### Run Metro Server with Watch Mode Source: https://github.com/react/metro/blob/main/docs/API.md Starts a Metro server that watches the filesystem for changes and automatically rebuilds bundles. Load configuration before running. ```javascript const config = await Metro.loadConfig(); await Metro.runServer(config); ``` -------------------------------- ### Importing local modules Source: https://github.com/react/metro/blob/main/docs/Resolution.md Example of importing a local module using a relative path. Metro resolves this to the specified file, e.g., src/Component.js. ```javascript // src/App.js import Comp from './Component'; // ... ``` -------------------------------- ### createConnectMiddleware(config) Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Creates a Connect middleware that can be plugged into custom servers to handle bundle requests. This is an alternative to creating a full Metro server and allows for more flexibility in server setup. ```APIDOC ## Method `createConnectMiddleware(config)` ### Description Creates a Connect middleware that can be plugged into custom servers to handle bundle requests. This is an alternative to creating a full Metro server and allows for more flexibility in server setup. ### Method Signature `createConnectMiddleware(config)` #### Options * `port` (number): Port for the Connect middleware (only for logging purposes). ### Request Example ```js 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); }); ``` ``` -------------------------------- ### Package JSON with Exports Configuration Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Example of a package.json file defining the 'exports' field to map a subpath to a specific JavaScript file. ```json { "name": "some-pkg", "exports": { "./FooComponent": "./src/FooComponent.js" } } ``` -------------------------------- ### Configure Metro with FileStore Cache Source: https://github.com/react/metro/blob/main/docs/Caching.md Example of configuring Metro to use a local file-based cache. This snippet demonstrates how to import and instantiate `FileStore` within the `metro.config.js` file, specifying a temporary directory for cache storage. ```javascript const os = require('node:os'); const path = require('node:path'); module.exports = { cacheStores: ({ FileStore }) => [ new FileStore({ root: path.join(os.tmpdir(), 'metro-cache'), }), ], }; ``` -------------------------------- ### Run Metro server with onClose callback Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Start a Metro development server and log a message when 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')}); ``` -------------------------------- ### Merge Multiple Metro Configurations Source: https://github.com/react/metro/blob/main/docs/Configuration.md Use `mergeConfig` to combine default configurations with custom settings. This example demonstrates merging by extending `additionalExts` and setting a `minifierPath`. Functions can be used to dynamically extend configurations based on previous merges. ```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']}, }), ); ``` -------------------------------- ### Create Connect Middleware for Metro Source: https://github.com/react/metro/blob/main/docs/API.md Integrates Metro's bundling capabilities into an existing Express server using Connect middleware. This allows for custom server setups and Hot Module Replacement (HMR). ```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); }); ``` -------------------------------- ### Run Metro in Target Project Source: https://github.com/react/metro/blob/main/docs/LocalDevelopment.md Start Metro within your target React Native project after linking packages and configuring `metro.config.js`. Remember to restart this command if you change `metro` code or the target project's `metro.config.js`. ```sh yarn react-native start ``` -------------------------------- ### Configure TLS Options for HTTPS Server Source: https://github.com/react/metro/blob/main/docs/Configuration.md When provided as an object, these TLS options enable Metro to start an HTTPS server with WSS WebSocket endpoints. The options include certificate authority, server certificate, private key, and certificate request settings. ```typescript ca?: string | Buffer, cert?: string | Buffer, key?: string | Buffer, requestCert?: boolean, ``` -------------------------------- ### Run a Metro Build Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Use `runBuild` to create a bundle from a configuration. 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' }); ``` -------------------------------- ### Metro.runBuild Source: https://github.com/react/metro/blob/main/docs/API.md Bundles an entry file to an output file, with options for development, minification, platform, and source maps. ```APIDOC ## Metro.runBuild(config, ) ### Description Bundles `entry` for the given `platform`, and saves it to location `out`. If `sourceMap` is set, also generates a source map. The source map will be inlined, unless `sourceMapUrl` is also defined. In the latter case, a new file will be generated with the basename of the `sourceMapUrl` parameter. If `assets` is `true`, an array of `AssetData` will be generated and returned in the `assets` property of the result object. ### Method Asynchronous function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options **Required options:** `entry`, `out` **Basic options:** `dev`, `minify`, `platform`, `sourceMap`, `sourceMapUrl`, `assets` ``` -------------------------------- ### Publish Website to Fork Source: https://github.com/react/metro/blob/main/website/README.md Deploys the Metro website to your personal fork of the repository. Replace placeholders with your GitHub username. ```bash DEPLOY_USER=YOUR_GITHUB_USERNAME GIT_USER=YOUR_GITHUB_USERNAME CIRCLE_PROJECT_USERNAME=YOUR_GITHUB_USERNAME CIRCLE_PROJECT_REPONAME=metro npm run gh-pages ``` -------------------------------- ### runBuild(config, options) Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Builds a JavaScript bundle given a configuration and options. It returns a Promise that resolves to an object containing the bundle code, source map, and optionally assets. This method is primarily useful during the build process. ```APIDOC ## Method `runBuild(config, options)` ### Description Builds a JavaScript bundle given a configuration and options. It returns a Promise that resolves to an object containing the bundle code, source map, and optionally assets. This method is primarily useful during the build process. ### Method Signature `runBuild(config, options)` ### 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 ```js const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', platform: 'ios', minify: true, out: '/Users/Metro/metro-ios.js' }); ``` ``` -------------------------------- ### Basic require() usage Source: https://github.com/react/metro/blob/main/docs/ModuleAPI.md Demonstrates how to use require() to import local modules, assets, JSON files, and components from react-native. ```javascript const localModule = require('./path/module'); const asset = require('./path/asset.png'); const jsonData = require('./path/data.json'); const {View} = require('react-native'); ``` -------------------------------- ### Compile a File with Metro Source: https://github.com/react/metro/blob/main/docs/API.md Use this snippet to compile a single entry file into a bundle. Ensure Metro configuration is loaded first. ```javascript const config = await Metro.loadConfig(); await Metro.runBuild(config, { entry: 'index.js', out: 'bundle.js', }); ``` -------------------------------- ### Metro.createConnectMiddleware Source: https://github.com/react/metro/blob/main/docs/API.md Creates a Connect middleware for handling bundle requests, which can be plugged into an existing server. Optionally accepts a callback for bundle build events. ```APIDOC ## Metro.createConnectMiddleware(config, ) ### Description Instead of creating the full server, creates a Connect middleware that answers to bundle requests. This middleware can then be plugged into your own servers. The `port` parameter is optional and only used for logging purposes. The `onBundleBuilt` function is optional, is passed the bundle name, and is called when the server has finishing creating the bundle. ### Method Asynchronous function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options **Basic options:** `port`, `onBundleBuilt` ``` -------------------------------- ### Define Package Exports with Specific Entry Points Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Explicitly define entry points for your package, including specific file extensions. This ensures a well-defined public API and matches existing user expectations. ```json { "exports": { ".": "./src/index.js", "./FooComponent": "./src/FooComponent.js", "./FooComponent.js": "./src/FooComponent.js" } } ``` -------------------------------- ### Dynamic require() at runtime Source: https://github.com/react/metro/blob/main/docs/ModuleAPI.md Shows how to use require() with a module ID obtained from require.resolveWeak() to bypass the restriction on non-constant require() arguments. ```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 ``` -------------------------------- ### Clone Repo and Create Branch Source: https://github.com/react/metro/blob/main/CONTRIBUTING.md Clone the Metro repository and create a new branch for your contributions from the main branch. ```sh git clone https://github.com/facebook/metro cd metro git checkout -b my_branch ``` -------------------------------- ### Run Metro server with HTTPS options Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Configure and run a Metro development server over HTTPS using custom certificate and key files. The secureServerOptions object is used for this purpose. ```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'), } }); ``` -------------------------------- ### Publish Website Source: https://github.com/react/metro/blob/main/website/README.md Deploys the Metro website to GitHub pages. This command is typically run by CircleCI but can be executed manually by a Git user with write permissions. ```bash DEPLOY_USER=facebook GIT_USER=metro-bot CIRCLE_PROJECT_USERNAME=facebook CIRCLE_PROJECT_REPONAME=metro npm run gh-pages ``` -------------------------------- ### Importing with Exact Subpath Match Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Demonstrates how importing a file with an explicit '.js' extension fails if the 'exports' field in package.json only maps the extensionless subpath. ```javascript import FooComponent from 'some-pkg/FooComponent.js'; // Inaccessible unless the package had also listed "./FooComponent.js" // as an "exports" key ``` -------------------------------- ### Metro.loadConfig Source: https://github.com/react/metro/blob/main/docs/API.md Loads the Metro configuration, either from options or by traversing the directory hierarchy. Returns a normalized and merged configuration. ```APIDOC ## Metro.loadConfig() ### Description Load the Metro configuration, either from `config` in options if specified, or by traversing the directory hierarchy from `cwd` to the root until it finds a file (by default `metro.config.js`). The returned configuration will have been normalized and merged with Metro's default values. ### Method Asynchronous function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options **Basic options:** `config`, `cwd` ``` -------------------------------- ### Configure Metro Watch Folders Source: https://github.com/react/metro/blob/main/docs/LocalDevelopment.md Update your `metro.config.js` to include `watchFolders` pointing to your linked Metro packages. This is necessary because `yarn link` includes files outside the immediate project folder. ```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'), ], ... }; ``` -------------------------------- ### Decoding Source Map Function Map Mappings Source: https://github.com/react/metro/blob/main/docs/SourceMapFormat.md Illustrates the step-by-step decoding procedure for the 'mappings' field of a function map, showing how VLQ encoded values are translated into column, name index, and line information. ```javascript const decoded = []; const names = ['a', '', 'b']; // From the function map let column = 0, nameIndex = 0, line = 1; column += 0 /* A */; nameIndex += 0 /* A */; line += 0 /* A */; dedecoded.push({column, name: names[nameIndex] /* 'a' */, line}); column += 14 /* c */; nameIndex += 1 /* C */; // no line delta dedecoded.push({column, name: names[nameIndex] /* '' */, line}); column += 1 /* C */; nameIndex += 1 /* C */; // no line delta dedecoded.push({column, name: names[nameIndex] /* 'b' */, line}); /* decoded = [ {column: 0, name: 'a', line: 1}, {column: 14, name: '', line: 1}, {column: 15, name: 'b', line: 1}, ] */ ``` -------------------------------- ### Define Package Exports with Subpath Patterns Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Use subpath patterns to map multiple subpaths. Only one '*' is permitted per side of a subpath pattern, and it does not permit path expansion beyond substring replacement. ```json { "exports": { ".": "./index.js", "./utils/*": "./utils/*.js" } } ``` -------------------------------- ### Require Metro module Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Begin by requiring the Metro module in your JavaScript file. ```javascript const Metro = require('metro'); ``` -------------------------------- ### Register Local Metro Packages Source: https://github.com/react/metro/blob/main/docs/LocalDevelopment.md Use `yarn link` within your Metro clone to register local packages. This command registers all packages in the Metro repo for later linking into a target project. ```sh npm exec --workspaces -- yarn link ``` -------------------------------- ### Indexed RAM Bundle Structure Source: https://github.com/react/metro/blob/main/docs/Bundling.md Visual representation of the Indexed RAM bundle's binary file structure, detailing the magic number, offset table, and module code layout. This format is optimal for environments that 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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` -------------------------------- ### Link Metro Packages in Target Project Source: https://github.com/react/metro/blob/main/docs/LocalDevelopment.md From 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. ```sh yarn link metro metro-config metro-runtime ``` -------------------------------- ### Handling Platform-Specific Code with Platform.select Source: https://github.com/react/metro/blob/main/docs/PackageExports.md When replacing platform-specific extensions in subpaths, use the `Platform.select()` API within your JavaScript files to conditionally require platform-specific modules. ```json { "exports": { "./FooComponent": "./src/FooComponent.js" } } ``` ```javascript // src/FooComponent.js const FooComponent = Platform.select({ android: require('./FooComponentAndroid.js'), ios: require('FooComponentIOS.js'), }); export default FooComponent; ``` -------------------------------- ### No-op PerfLoggerFactory Implementation Source: https://github.com/react/metro/blob/main/docs/Configuration.md Provides a no-operation implementation for `unstable_perfLoggerFactory`. This is useful when performance insights are not required, preventing unnecessary overhead. ```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(); }; ``` -------------------------------- ### Customizing Module Resolution with resolveRequest Source: https://github.com/react/metro/blob/main/docs/Configuration.md Override Metro's default module resolution algorithm. Use this for custom protocols or aliasing. Ensure to either resolve the module or chain to the default resolver. Throw an error if resolution fails. ```javascript resolveRequest: (context, moduleName, platform) => { if (moduleName.startsWith('my-custom-resolver:')) { // Logic to resolve the module name to a file path... // NOTE: Throw an error if there is no resolution. return { filePath: 'path/to/file', type: 'sourceFile', }; } // Optionally, chain to the standard Metro resolver. return context.resolveRequest(context, moduleName, platform); } ``` -------------------------------- ### Package JSON with Exports Field Source: https://github.com/react/metro/blob/main/docs/PackageExports.md This JSON defines a package with both 'main' and 'exports' fields. The 'exports' field specifies different entry points for 'import' and 'require' conditions. ```json { "name": "some-pkg", "version": "1.0.0", "main": "./dist/cjs/index.js", "exports": { ".": { "import": "./dist/esm/index.mjs", "require": "./dist/cjs/index.js" } } } ``` -------------------------------- ### Haste Implementation Signature Source: https://github.com/react/metro/blob/main/docs/Configuration.md Defines the expected signature for a custom Haste implementation module. The `getHasteName` function should return a unique name for a given file path or null if it should not be exposed via Haste. ```flow module.exports = { getHasteName(filePath: string): ?string { // ... }, }; ``` -------------------------------- ### Exporting Asset Files with Subpath Patterns Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Use subpath patterns in the 'exports' field of your package.json to export multiple asset files. It is recommended to specify asset subpaths with their file extension. ```json { "exports": { "./assets/*.png": "./dist/assets/*.png" } } ``` -------------------------------- ### Enhance Metro Middleware with Custom Connect Middleware Source: https://github.com/react/metro/blob/main/docs/Configuration.md Use this function to attach custom connect middleware to Metro. It allows extending the base metroMiddleware and mounting additional handlers for custom endpoints. ```typescript enhanceMiddleware: (metroMiddleware: Middleware, metroServer: MetroServer) => { return connect() .use(metroMiddleware) .use('/custom-endpoint', customEndpointMiddleware()); }, ``` -------------------------------- ### Integrate Metro with Express middleware Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Use Metro's processRequest method as middleware in an Express application to handle bundling requests. ```javascript const express = require('express'); const app = express(); app.use( metroBundlerServer.processRequest.bind(metroBundlerServer), ); app.listen(8081); ``` -------------------------------- ### CacheStores Type Definition Source: https://github.com/react/metro/blob/main/docs/Configuration.md Defines the structure for `CacheStores`, which is a list of storage adapters for Metro's transformer cache. It can be an array of cache stores or a function that returns an array of cache stores. ```flow type CacheStores = | Array> | ((MetroCache) => Array< CacheStore >); // The exports of 'metro-cache' type MetroCache = { FileStore, AutoCleanFileStore, HttpStore, HttpGetStore, ... }; type JsonSerializable = /* Any JSON-serializable value */; ``` -------------------------------- ### Importing a Package with Exports Source: https://github.com/react/metro/blob/main/docs/PackageExports.md When using 'import' syntax, Metro applies the 'import' condition from the 'exports' field in package.json. ```javascript import Foo from 'some-pkg'; ``` -------------------------------- ### getTransformOptions Signature Source: https://github.com/react/metro/blob/main/docs/Configuration.md Defines the expected signature for the `getTransformOptions` function, which Metro uses to calculate transformer and serializer options. ```flow function getTransformOptions( entryPoints: $ReadOnlyArray, options: { dev: boolean, hot: boolean, platform: ?string, }, getDependenciesOf: (path: string) => Promise>, ): Promise { // ... } ``` -------------------------------- ### ExtraTransformOptions Type Definition Source: https://github.com/react/metro/blob/main/docs/Configuration.md Defines the structure of the `ExtraTransformOptions` object that `getTransformOptions` should return, specifying module preloading and RAM bundle configurations. ```flow type ExtraTransformOptions = { preloadedModules?: {[path: string]: true} | false, ramGroups?: Array, transform?: { inlineRequires?: {blockList: {[string]: true}} | boolean, nonInlinedRequires?: $ReadOnlyArray, }, }; ``` -------------------------------- ### Lenient Package Encapsulation Warning Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Metro logs a warning when a module is imported that is not explicitly listed in the 'exports' field of its package.json, falling back to old resolution behavior. ```shell 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. ``` -------------------------------- ### Handle unhandled requests in HTTP server Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Extend an HTTP server to handle requests that Metro cannot process. The third callback parameter in processRequest is invoked for such cases. ```javascript const httpServer = http.createServer((req, res) => { metroBundlerServer.processRequest(req, res, () => { // Metro does not know how to handle the request. }); }); ``` -------------------------------- ### Reset Metro Cache via Configuration Source: https://github.com/react/metro/blob/main/docs/Troubleshooting.md Alternatively, reset Metro's cache by setting `resetCache: true` within your Metro configuration file. This achieves the same result as the CLI flag. ```javascript { // ... other Metro configurations resetCache: true } ``` -------------------------------- ### Reset Metro Cache via CLI Source: https://github.com/react/metro/blob/main/docs/Troubleshooting.md Pass the `--reset-cache` flag to the Metro command to clear its internal cache. This is often necessary after configuration changes or when encountering unexpected bundling behavior. ```bash metro --reset-cache ``` -------------------------------- ### Legacy Package Resolution (No Exports) Source: https://github.com/react/metro/blob/main/docs/PackageExports.md When a package.json lacks an 'exports' field, Metro attempts to resolve modules by checking platform-specific extensions, native extensions, and standard JavaScript extensions. ```javascript import FooComponent from 'some-pkg/FooComponent'; // Tries .[platform].js, .native.js, .js (+ TypeScript variants) ``` -------------------------------- ### Dependency Descriptor Type Source: https://github.com/react/metro/blob/main/docs/Resolution.md Describes the structure of a `Dependency` object, used for diagnostic purposes to represent a module dependency. ```flow type Dependency = { // The literal name provided to a require or import call. For example 'foo' in // case of `require('foo')`. name: string, data: { // A locally unique key for this dependency within the origin module. key: string, // Source locations from the Babel AST, relative to the origin module, where // this dependency was encountered. This may be an empty array. locs: $ReadOnlyArray, asyncType: 'async' | 'prefetch' | 'weak' | null, // Other properties are considered internal and may change in the future. ... }; }; ``` -------------------------------- ### Babel Integration for JavaScript Transformation Source: https://github.com/react/metro/blob/main/docs/GettingStarted.md Integrates Babel into the JavaScript transformer to transpile code. This method uses `@babel/core` to transform the source code, allowing for Babel options to be applied. ```javascript const {transformSync} = require('@babel/core'); module.exports.transform = file => { return transformSync(file.src, { // Babel options... }); }; ``` -------------------------------- ### Custom Resolver for Package Exports Source: https://github.com/react/metro/blob/main/docs/PackageExports.md Configure a custom resolver in metro.config.js to handle package export conditions, such as using the 'browser' condition for specific packages. This can help resolve ESM incompatibilities. ```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); ```