CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metro-runtime

Module required for evaluating Metro bundles with async loading and HMR support.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

require-polyfill.mddocs/

Require System Polyfill

Core Metro require system implementation with module loading, HMR support, and development utilities. This polyfill provides cross-platform module resolution and loading, enabling Metro bundles to run across different JavaScript environments.

Capabilities

Core Require Function

The main module loading function that handles both numeric module IDs and verbose module names.

/**
 * Metro's core require function for loading modules
 * @param moduleId - Numeric module ID, verbose name, or null for optional dependencies
 * @param maybeNameForDev - Optional name for better error messages in development
 * @returns The module's exports
 */
function metroRequire(
  moduleId: ModuleID | VerboseModuleNameForDev | null,
  maybeNameForDev?: string
): Exports;

type ModuleID = number;
type VerboseModuleNameForDev = string;
type Exports = any;
type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;

Usage Examples:

// Basic module loading (typically done automatically by Metro)
const utils = metroRequire(42);
const component = metroRequire(100, "MyComponent");

// Development mode with verbose names (DEV only)
if (__DEV__) {
  const debugModule = metroRequire("src/debug/logger.js");
}

Module Definition

Function for defining modules in the Metro module system.

/**
 * Defines a module in the Metro module system
 * @param factory - Function that initializes the module
 * @param moduleId - Numeric identifier for the module
 * @param dependencyMap - Mapping of dependency module IDs
 * @param verboseName - Human-readable name for development
 * @param inverseDependencies - Modules that depend on this module (for HMR)
 */
function define(
  factory: FactoryFn,
  moduleId: number,
  dependencyMap?: DependencyMap,
  verboseName?: string,
  inverseDependencies?: InverseDependencyMap
): void;

type FactoryFn = (
  global: Object,
  require: RequireFn,
  metroImportDefault: RequireFn,
  metroImportAll: RequireFn,
  moduleObject: {exports: {...}, ...},
  exports: {...},
  dependencyMap: ?DependencyMap,
) => void;

type DependencyMap = $ReadOnly<
  ArrayIndexable<ModuleID> & {
    paths?: {[id: ModuleID]: string},
  }
>;

type InverseDependencyMap = {[key: ModuleID]: Array<ModuleID>, ...};

Usage Examples:

// Module definition (typically generated by Metro bundler)
define(
  function(global, require, metroImportDefault, metroImportAll, moduleObject, exports, dependencyMap) {
    "use strict";
    
    // Module code here
    const dependency = require(42);
    
    function myFunction() {
      return "Hello from module";
    }
    
    exports.myFunction = myFunction;
  },
  123, // module ID
  [42], // dependencies
  "src/myModule.js" // verbose name for development
);

Import Functions

Enhanced import functions for ES module compatibility.

/**
 * Imports the default export from a module
 * @param moduleId - Module ID or verbose name
 * @returns The default export or the entire module if not ES module
 */
metroRequire.importDefault = function metroImportDefault(
  moduleId: ModuleID | VerboseModuleNameForDev
): any | Exports;

/**
 * Imports all exports from a module (namespace import)
 * @param moduleId - Module ID or verbose name  
 * @returns Object containing all exports
 */
metroRequire.importAll = function metroImportAll(
  moduleId: ModuleID | VerboseModuleNameForDev
): any | Exports | {[string]: any};

/**
 * Experimental require.context function (throws if not enabled)
 * @throws Error when feature is not enabled in Metro configuration
 */
metroRequire.context = function fallbackRequireContext(): never;

/**
 * Compile-time primitive for weak requires (throws if called dynamically)
 * @throws Error when called at runtime
 */
metroRequire.resolveWeak = function fallbackRequireResolveWeak(): never;

Usage Examples:

// ES module default import
const MyComponent = metroRequire.importDefault(150);

// ES module namespace import
const * as utils = metroRequire.importAll(200);

// CommonJS compatibility
const lodash = metroRequire.importAll(300); // Gets { default: lodashModule, ...lodashExports }

// Note: context and resolveWeak are compile-time features
// They cannot be called dynamically and will throw errors if attempted

Module ID Utilities

Utilities for working with packed module IDs in segmented bundles.

/**
 * Unpacks a module ID into segment and local components
 * @param moduleId - Packed module ID
 * @returns Object with segmentId and localId
 */
metroRequire.unpackModuleId = function unpackModuleId(
  moduleId: ModuleID
): {localId: number, segmentId: number};

/**
 * Packs segment and local IDs into a single module ID
 * @param value - Object with segmentId and localId
 * @returns Packed module ID
 */
metroRequire.packModuleId = function packModuleId(
  value: {localId: number, segmentId: number}
): ModuleID;

Usage Examples:

// Working with segmented bundles
const packedId = 0x00420029; // Example packed ID
const { segmentId, localId } = metroRequire.unpackModuleId(packedId);
console.log(`Module in segment ${segmentId}, local ID ${localId}`);

// Creating packed IDs
const newPackedId = metroRequire.packModuleId({
  segmentId: 2,
  localId: 100
});

Bundle Segmentation

Functions for managing bundle segments and dynamic loading.

/**
 * Registers a bundle segment with its module definer
 * @param segmentId - Numeric identifier for the segment
 * @param moduleDefiner - Function that defines modules in this segment
 * @param moduleIds - Array of module IDs contained in this segment
 */
function registerSegment(
  segmentId: number,
  moduleDefiner: ModuleDefiner,
  moduleIds: ?$ReadOnlyArray<ModuleID>
): void;

type ModuleDefiner = (moduleId: ModuleID) => void;

Usage Examples:

// Register a bundle segment (typically done by Metro)
registerSegment(
  1, // segment ID
  (moduleId) => {
    // Define modules in this segment
    if (moduleId === 200) {
      define(/* factory for module 200 */, 200);
    }
  },
  [200, 201, 202] // modules in this segment
);

Development Features

Module Registry Access

Development-only utilities for inspecting the module system.

// Development mode only (__DEV__ === true)
/**
 * Gets the internal module registry (DEV only)
 * @returns Map of all registered modules
 */
metroRequire.getModules = function(): ModuleList;

type ModuleList = Map<number, ModuleDefinition>;

type ModuleDefinition = {
  dependencyMap: ?DependencyMap,
  error?: any,
  factory: FactoryFn,
  hasError: boolean,
  hot?: HotModuleReloadingData,
  importedAll: any,
  importedDefault: any,
  isInitialized: boolean,
  path?: string,
  publicModule: Module,
  verboseName?: string,
};

Hot Module Replacement Support

Development-time HMR functionality integrated into the require system.

// HMR support types (DEV only)
type HotModuleReloadingData = {
  _acceptCallback: ?HotModuleReloadingCallback,
  _disposeCallback: ?HotModuleReloadingCallback,
  _didAccept: boolean,
  accept: (callback?: HotModuleReloadingCallback) => void,
  dispose: (callback?: HotModuleReloadingCallback) => void,
};

type HotModuleReloadingCallback = () => void;

// Global HMR function
global.__accept = function(
  id: ModuleID,
  factory: FactoryFn,
  dependencyMap: DependencyMap,
  inverseDependencies: InverseDependencyMap
): void;

Usage Examples:

// HMR module boundary (in your module code)
if (__DEV__ && module.hot) {
  module.hot.accept(() => {
    console.log("Module hot reloaded");
  });
  
  module.hot.dispose(() => {
    console.log("Module being disposed");
    // Cleanup code here
  });
}

// Inspecting module registry in development
if (__DEV__) {
  const modules = metroRequire.getModules();
  console.log(`Loaded ${modules.size} modules`);
  
  modules.forEach((module, id) => {
    if (module.verboseName) {
      console.log(`Module ${id}: ${module.verboseName}`);
    }
  });
}

Tracing and Debugging

Development utilities for performance tracing and debugging.

// Development tracing support (DEV only)
metroRequire.Systrace = {
  beginEvent: (eventName: string) => void,
  endEvent: () => void,
};

// React Refresh integration (DEV only)
metroRequire.Refresh = ReactRefreshRuntime;

Error Handling

The require system includes comprehensive error handling:

// Module not found errors
try {
  const module = metroRequire(999);
} catch (error) {
  console.error(error.message); // "Requiring unknown module '999'"
}

// Circular dependency warnings (DEV only)
// Automatically logged when circular dependencies are detected

// Module initialization errors
// Handled by global.ErrorUtils if available

Development Features

Module Registry Access

Development-only utilities for inspecting the module system.

// Development mode only (__DEV__ === true)
/**
 * Gets the internal module registry (DEV only)
 * @returns Map of all registered modules
 */
metroRequire.getModules = function(): ModuleList;

type ModuleList = Map<number, ModuleDefinition>;

type ModuleDefinition = {
  dependencyMap: ?DependencyMap,
  error?: any,
  factory: FactoryFn,
  hasError: boolean,
  hot?: HotModuleReloadingData,
  importedAll: any,
  importedDefault: any,
  isInitialized: boolean,
  path?: string,
  publicModule: Module,
  verboseName?: string,
};

Hot Module Replacement Support

Development-time HMR functionality integrated into the require system.

// HMR support types (DEV only)
type HotModuleReloadingData = {
  _acceptCallback: ?HotModuleReloadingCallback,
  _disposeCallback: ?HotModuleReloadingCallback,
  _didAccept: boolean,
  accept: (callback?: HotModuleReloadingCallback) => void,
  dispose: (callback?: HotModuleReloadingCallback) => void,
};

type HotModuleReloadingCallback = () => void;

// Global HMR function
global.__accept = function(
  id: ModuleID,
  factory: FactoryFn,
  dependencyMap: DependencyMap,
  inverseDependencies: InverseDependencyMap
): void;

Usage Examples:

// HMR module boundary (in your module code)
if (__DEV__ && module.hot) {
  module.hot.accept(() => {
    console.log("Module hot reloaded");
  });
  
  module.hot.dispose(() => {
    console.log("Module being disposed");
    // Cleanup code here
  });
}

// Inspecting module registry in development
if (__DEV__) {
  const modules = metroRequire.getModules();
  console.log(`Loaded ${modules.size} modules`);
  
  modules.forEach((module, id) => {
    if (module.verboseName) {
      console.log(`Module ${id}: ${module.verboseName}`);
    }
  });
}

Tracing and Debugging

Development utilities for performance tracing and debugging.

// Development tracing support (DEV only)
metroRequire.Systrace = {
  beginEvent: (eventName: string) => void,
  endEvent: () => void,
};

// React Refresh integration (DEV only)
metroRequire.Refresh = ReactRefreshRuntime;

Global Integration

The require polyfill integrates with global Metro variables:

// Global exports set by the polyfill
global.__r = metroRequire;
global[__METRO_GLOBAL_PREFIX__ + '__d'] = define;
global.__c = clear; // Clear module registry
global.__registerSegment = registerSegment;

// React Fast Refresh globals (DEV only)
global.$RefreshReg$ = (type, id) => void;
global.$RefreshSig$ = (signature) => (type) => type;

Module System Constants

Key constants used throughout the module system:

const ID_MASK_SHIFT = 16;
const LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT;

// Special marker objects
const EMPTY = {}; // Marker for uninitialized imports
const CYCLE_DETECTED = {}; // Thrown for dependency cycles

This polyfill enables Metro bundles to run consistently across web browsers, React Native, and Node.js environments while providing comprehensive development tooling and HMR support.

docs

async-loading.md

hmr-client.md

index.md

require-polyfill.md

tile.json