0
# Require System Polyfill
1
2
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.
3
4
## Capabilities
5
6
### Core Require Function
7
8
The main module loading function that handles both numeric module IDs and verbose module names.
9
10
```javascript { .api }
11
/**
12
* Metro's core require function for loading modules
13
* @param moduleId - Numeric module ID, verbose name, or null for optional dependencies
14
* @param maybeNameForDev - Optional name for better error messages in development
15
* @returns The module's exports
16
*/
17
function metroRequire(
18
moduleId: ModuleID | VerboseModuleNameForDev | null,
19
maybeNameForDev?: string
20
): Exports;
21
22
type ModuleID = number;
23
type VerboseModuleNameForDev = string;
24
type Exports = any;
25
type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;
26
```
27
28
**Usage Examples:**
29
30
```javascript
31
// Basic module loading (typically done automatically by Metro)
32
const utils = metroRequire(42);
33
const component = metroRequire(100, "MyComponent");
34
35
// Development mode with verbose names (DEV only)
36
if (__DEV__) {
37
const debugModule = metroRequire("src/debug/logger.js");
38
}
39
```
40
41
### Module Definition
42
43
Function for defining modules in the Metro module system.
44
45
```javascript { .api }
46
/**
47
* Defines a module in the Metro module system
48
* @param factory - Function that initializes the module
49
* @param moduleId - Numeric identifier for the module
50
* @param dependencyMap - Mapping of dependency module IDs
51
* @param verboseName - Human-readable name for development
52
* @param inverseDependencies - Modules that depend on this module (for HMR)
53
*/
54
function define(
55
factory: FactoryFn,
56
moduleId: number,
57
dependencyMap?: DependencyMap,
58
verboseName?: string,
59
inverseDependencies?: InverseDependencyMap
60
): void;
61
62
type FactoryFn = (
63
global: Object,
64
require: RequireFn,
65
metroImportDefault: RequireFn,
66
metroImportAll: RequireFn,
67
moduleObject: {exports: {...}, ...},
68
exports: {...},
69
dependencyMap: ?DependencyMap,
70
) => void;
71
72
type DependencyMap = $ReadOnly<
73
ArrayIndexable<ModuleID> & {
74
paths?: {[id: ModuleID]: string},
75
}
76
>;
77
78
type InverseDependencyMap = {[key: ModuleID]: Array<ModuleID>, ...};
79
```
80
81
**Usage Examples:**
82
83
```javascript
84
// Module definition (typically generated by Metro bundler)
85
define(
86
function(global, require, metroImportDefault, metroImportAll, moduleObject, exports, dependencyMap) {
87
"use strict";
88
89
// Module code here
90
const dependency = require(42);
91
92
function myFunction() {
93
return "Hello from module";
94
}
95
96
exports.myFunction = myFunction;
97
},
98
123, // module ID
99
[42], // dependencies
100
"src/myModule.js" // verbose name for development
101
);
102
```
103
104
### Import Functions
105
106
Enhanced import functions for ES module compatibility.
107
108
```javascript { .api }
109
/**
110
* Imports the default export from a module
111
* @param moduleId - Module ID or verbose name
112
* @returns The default export or the entire module if not ES module
113
*/
114
metroRequire.importDefault = function metroImportDefault(
115
moduleId: ModuleID | VerboseModuleNameForDev
116
): any | Exports;
117
118
/**
119
* Imports all exports from a module (namespace import)
120
* @param moduleId - Module ID or verbose name
121
* @returns Object containing all exports
122
*/
123
metroRequire.importAll = function metroImportAll(
124
moduleId: ModuleID | VerboseModuleNameForDev
125
): any | Exports | {[string]: any};
126
127
/**
128
* Experimental require.context function (throws if not enabled)
129
* @throws Error when feature is not enabled in Metro configuration
130
*/
131
metroRequire.context = function fallbackRequireContext(): never;
132
133
/**
134
* Compile-time primitive for weak requires (throws if called dynamically)
135
* @throws Error when called at runtime
136
*/
137
metroRequire.resolveWeak = function fallbackRequireResolveWeak(): never;
138
```
139
140
**Usage Examples:**
141
142
```javascript
143
// ES module default import
144
const MyComponent = metroRequire.importDefault(150);
145
146
// ES module namespace import
147
const * as utils = metroRequire.importAll(200);
148
149
// CommonJS compatibility
150
const lodash = metroRequire.importAll(300); // Gets { default: lodashModule, ...lodashExports }
151
152
// Note: context and resolveWeak are compile-time features
153
// They cannot be called dynamically and will throw errors if attempted
154
```
155
156
### Module ID Utilities
157
158
Utilities for working with packed module IDs in segmented bundles.
159
160
```javascript { .api }
161
/**
162
* Unpacks a module ID into segment and local components
163
* @param moduleId - Packed module ID
164
* @returns Object with segmentId and localId
165
*/
166
metroRequire.unpackModuleId = function unpackModuleId(
167
moduleId: ModuleID
168
): {localId: number, segmentId: number};
169
170
/**
171
* Packs segment and local IDs into a single module ID
172
* @param value - Object with segmentId and localId
173
* @returns Packed module ID
174
*/
175
metroRequire.packModuleId = function packModuleId(
176
value: {localId: number, segmentId: number}
177
): ModuleID;
178
```
179
180
**Usage Examples:**
181
182
```javascript
183
// Working with segmented bundles
184
const packedId = 0x00420029; // Example packed ID
185
const { segmentId, localId } = metroRequire.unpackModuleId(packedId);
186
console.log(`Module in segment ${segmentId}, local ID ${localId}`);
187
188
// Creating packed IDs
189
const newPackedId = metroRequire.packModuleId({
190
segmentId: 2,
191
localId: 100
192
});
193
```
194
195
### Bundle Segmentation
196
197
Functions for managing bundle segments and dynamic loading.
198
199
```javascript { .api }
200
/**
201
* Registers a bundle segment with its module definer
202
* @param segmentId - Numeric identifier for the segment
203
* @param moduleDefiner - Function that defines modules in this segment
204
* @param moduleIds - Array of module IDs contained in this segment
205
*/
206
function registerSegment(
207
segmentId: number,
208
moduleDefiner: ModuleDefiner,
209
moduleIds: ?$ReadOnlyArray<ModuleID>
210
): void;
211
212
type ModuleDefiner = (moduleId: ModuleID) => void;
213
```
214
215
**Usage Examples:**
216
217
```javascript
218
// Register a bundle segment (typically done by Metro)
219
registerSegment(
220
1, // segment ID
221
(moduleId) => {
222
// Define modules in this segment
223
if (moduleId === 200) {
224
define(/* factory for module 200 */, 200);
225
}
226
},
227
[200, 201, 202] // modules in this segment
228
);
229
```
230
231
## Development Features
232
233
### Module Registry Access
234
235
Development-only utilities for inspecting the module system.
236
237
```javascript { .api }
238
// Development mode only (__DEV__ === true)
239
/**
240
* Gets the internal module registry (DEV only)
241
* @returns Map of all registered modules
242
*/
243
metroRequire.getModules = function(): ModuleList;
244
245
type ModuleList = Map<number, ModuleDefinition>;
246
247
type ModuleDefinition = {
248
dependencyMap: ?DependencyMap,
249
error?: any,
250
factory: FactoryFn,
251
hasError: boolean,
252
hot?: HotModuleReloadingData,
253
importedAll: any,
254
importedDefault: any,
255
isInitialized: boolean,
256
path?: string,
257
publicModule: Module,
258
verboseName?: string,
259
};
260
```
261
262
### Hot Module Replacement Support
263
264
Development-time HMR functionality integrated into the require system.
265
266
```javascript { .api }
267
// HMR support types (DEV only)
268
type HotModuleReloadingData = {
269
_acceptCallback: ?HotModuleReloadingCallback,
270
_disposeCallback: ?HotModuleReloadingCallback,
271
_didAccept: boolean,
272
accept: (callback?: HotModuleReloadingCallback) => void,
273
dispose: (callback?: HotModuleReloadingCallback) => void,
274
};
275
276
type HotModuleReloadingCallback = () => void;
277
278
// Global HMR function
279
global.__accept = function(
280
id: ModuleID,
281
factory: FactoryFn,
282
dependencyMap: DependencyMap,
283
inverseDependencies: InverseDependencyMap
284
): void;
285
```
286
287
**Usage Examples:**
288
289
```javascript
290
// HMR module boundary (in your module code)
291
if (__DEV__ && module.hot) {
292
module.hot.accept(() => {
293
console.log("Module hot reloaded");
294
});
295
296
module.hot.dispose(() => {
297
console.log("Module being disposed");
298
// Cleanup code here
299
});
300
}
301
302
// Inspecting module registry in development
303
if (__DEV__) {
304
const modules = metroRequire.getModules();
305
console.log(`Loaded ${modules.size} modules`);
306
307
modules.forEach((module, id) => {
308
if (module.verboseName) {
309
console.log(`Module ${id}: ${module.verboseName}`);
310
}
311
});
312
}
313
```
314
315
### Tracing and Debugging
316
317
Development utilities for performance tracing and debugging.
318
319
```javascript { .api }
320
// Development tracing support (DEV only)
321
metroRequire.Systrace = {
322
beginEvent: (eventName: string) => void,
323
endEvent: () => void,
324
};
325
326
// React Refresh integration (DEV only)
327
metroRequire.Refresh = ReactRefreshRuntime;
328
```
329
330
## Error Handling
331
332
The require system includes comprehensive error handling:
333
334
```javascript
335
// Module not found errors
336
try {
337
const module = metroRequire(999);
338
} catch (error) {
339
console.error(error.message); // "Requiring unknown module '999'"
340
}
341
342
// Circular dependency warnings (DEV only)
343
// Automatically logged when circular dependencies are detected
344
345
// Module initialization errors
346
// Handled by global.ErrorUtils if available
347
```
348
349
## Development Features
350
351
### Module Registry Access
352
353
Development-only utilities for inspecting the module system.
354
355
```javascript { .api }
356
// Development mode only (__DEV__ === true)
357
/**
358
* Gets the internal module registry (DEV only)
359
* @returns Map of all registered modules
360
*/
361
metroRequire.getModules = function(): ModuleList;
362
363
type ModuleList = Map<number, ModuleDefinition>;
364
365
type ModuleDefinition = {
366
dependencyMap: ?DependencyMap,
367
error?: any,
368
factory: FactoryFn,
369
hasError: boolean,
370
hot?: HotModuleReloadingData,
371
importedAll: any,
372
importedDefault: any,
373
isInitialized: boolean,
374
path?: string,
375
publicModule: Module,
376
verboseName?: string,
377
};
378
```
379
380
### Hot Module Replacement Support
381
382
Development-time HMR functionality integrated into the require system.
383
384
```javascript { .api }
385
// HMR support types (DEV only)
386
type HotModuleReloadingData = {
387
_acceptCallback: ?HotModuleReloadingCallback,
388
_disposeCallback: ?HotModuleReloadingCallback,
389
_didAccept: boolean,
390
accept: (callback?: HotModuleReloadingCallback) => void,
391
dispose: (callback?: HotModuleReloadingCallback) => void,
392
};
393
394
type HotModuleReloadingCallback = () => void;
395
396
// Global HMR function
397
global.__accept = function(
398
id: ModuleID,
399
factory: FactoryFn,
400
dependencyMap: DependencyMap,
401
inverseDependencies: InverseDependencyMap
402
): void;
403
```
404
405
**Usage Examples:**
406
407
```javascript
408
// HMR module boundary (in your module code)
409
if (__DEV__ && module.hot) {
410
module.hot.accept(() => {
411
console.log("Module hot reloaded");
412
});
413
414
module.hot.dispose(() => {
415
console.log("Module being disposed");
416
// Cleanup code here
417
});
418
}
419
420
// Inspecting module registry in development
421
if (__DEV__) {
422
const modules = metroRequire.getModules();
423
console.log(`Loaded ${modules.size} modules`);
424
425
modules.forEach((module, id) => {
426
if (module.verboseName) {
427
console.log(`Module ${id}: ${module.verboseName}`);
428
}
429
});
430
}
431
```
432
433
### Tracing and Debugging
434
435
Development utilities for performance tracing and debugging.
436
437
```javascript { .api }
438
// Development tracing support (DEV only)
439
metroRequire.Systrace = {
440
beginEvent: (eventName: string) => void,
441
endEvent: () => void,
442
};
443
444
// React Refresh integration (DEV only)
445
metroRequire.Refresh = ReactRefreshRuntime;
446
```
447
448
## Global Integration
449
450
The require polyfill integrates with global Metro variables:
451
452
```javascript { .api }
453
// Global exports set by the polyfill
454
global.__r = metroRequire;
455
global[__METRO_GLOBAL_PREFIX__ + '__d'] = define;
456
global.__c = clear; // Clear module registry
457
global.__registerSegment = registerSegment;
458
459
// React Fast Refresh globals (DEV only)
460
global.$RefreshReg$ = (type, id) => void;
461
global.$RefreshSig$ = (signature) => (type) => type;
462
```
463
464
## Module System Constants
465
466
Key constants used throughout the module system:
467
468
```javascript { .api }
469
const ID_MASK_SHIFT = 16;
470
const LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT;
471
472
// Special marker objects
473
const EMPTY = {}; // Marker for uninitialized imports
474
const CYCLE_DETECTED = {}; // Thrown for dependency cycles
475
```
476
477
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.