diff --git a/packages/metro-runtime/src/polyfills/__tests__/require-test.js b/packages/metro-runtime/src/polyfills/__tests__/require-test.js index 7155da940f..ef0a2fcdfc 100644 --- a/packages/metro-runtime/src/polyfills/__tests__/require-test.js +++ b/packages/metro-runtime/src/polyfills/__tests__/require-test.js @@ -100,6 +100,7 @@ describe('require', () => { createModuleSystem(moduleSystem, false, ''); expect(moduleSystem.__r).not.toBeUndefined(); expect(moduleSystem.__d).not.toBeUndefined(); + expect(moduleSystem.__e).toBeUndefined(); const mockExports = {foo: 'bar'}; const mockFactory = jest @@ -128,6 +129,26 @@ describe('require', () => { expect(mockFactory.mock.calls[0][6]).toEqual([2, 3]); }); + test('exposes metroRequire as __e when runtime owner has already installed __r', () => { + const runtimeOwnerRequire = jest.fn(); + moduleSystem.__r = runtimeOwnerRequire; + + createModuleSystem(moduleSystem, false, ''); + + expect(moduleSystem.__r).toBe(runtimeOwnerRequire); + expect(moduleSystem.__e).not.toBeUndefined(); + expect(moduleSystem.__e).not.toBe(runtimeOwnerRequire); + }); + + test('does not overwrite __r if already provided by the runtime owner', () => { + const runtimeOwnerRequire = jest.fn(); + moduleSystem.__r = runtimeOwnerRequire; + + createModuleSystem(moduleSystem, false, ''); + + expect(moduleSystem.__r).toBe(runtimeOwnerRequire); + }); + test('properly prefixes __d with global prefix', () => { createModuleSystem(moduleSystem, false, '__metro'); expect(moduleSystem.__d).toBeUndefined(); diff --git a/packages/metro-runtime/src/polyfills/require.js b/packages/metro-runtime/src/polyfills/require.js index 660444bae6..547a0b2f53 100644 --- a/packages/metro-runtime/src/polyfills/require.js +++ b/packages/metro-runtime/src/polyfills/require.js @@ -80,7 +80,15 @@ export type DefineFn = ( type VerboseModuleNameForDev = string; type ModuleDefiner = (moduleId: ModuleID) => void; -global.__r = metroRequire as RequireFn; +if (!global.__r) { + // Entry point require function. + // Install only if the runtime owner hasn't already provided one. + global.__r = metroRequire as RequireFn; +} else { + // Install it as a separate binding. + // The runtime owner might e.g. use it to implement his own __r wrapper. + global.__e = metroRequire as RequireFn; +} global[`${__METRO_GLOBAL_PREFIX__}__d`] = define as DefineFn; global.__c = clear; global.__registerSegment = registerSegment;