diff --git a/packages/metro-config/src/defaults/index.js b/packages/metro-config/src/defaults/index.js index 679d1e9498..4ea6563e32 100644 --- a/packages/metro-config/src/defaults/index.js +++ b/packages/metro-config/src/defaults/index.js @@ -69,6 +69,7 @@ const getDefaultValues = (projectRoot: ?string): ConfigT => ({ customSerializer: null, isThirdPartyModule: module => /(?:^|[/\\])node_modules[/\\]/.test(module.path), + unstable_inlineDependencyMap: false, }, server: { diff --git a/packages/metro-config/src/types.js b/packages/metro-config/src/types.js index 699afc7e6b..c7b98e0d3a 100644 --- a/packages/metro-config/src/types.js +++ b/packages/metro-config/src/types.js @@ -146,6 +146,7 @@ type SerializerConfigT = { polyfillModuleNames: ReadonlyArray, processModuleFilter: (modules: Module<>) => boolean, isThirdPartyModule: (module: Readonly<{path: string, ...}>) => boolean, + unstable_inlineDependencyMap: boolean, }; type TransformerConfigT = { diff --git a/packages/metro-config/types/types.d.ts b/packages/metro-config/types/types.d.ts index fda3ce1d02..0d1af02b3b 100644 --- a/packages/metro-config/types/types.d.ts +++ b/packages/metro-config/types/types.d.ts @@ -6,7 +6,7 @@ * * @noformat * @oncall react_native - * @generated SignedSource<<3f0c3f9093e9a6eadd3a8885218f8f45>> + * @generated SignedSource<<08960eb44a59d3d45155da2e2f9173b9>> * * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js * Original file: packages/metro-config/src/types.js @@ -111,6 +111,7 @@ type SerializerConfigT = { polyfillModuleNames: ReadonlyArray; processModuleFilter: (modules: Module) => boolean; isThirdPartyModule: (module: Readonly<{path: string}>) => boolean; + unstable_inlineDependencyMap: boolean; }; type TransformerConfigT = Omit & { getTransformOptions: GetTransformOptions; diff --git a/packages/metro/src/DeltaBundler/Serializers/__tests__/baseJSBundle-test.js b/packages/metro/src/DeltaBundler/Serializers/__tests__/baseJSBundle-test.js index fcf45643f6..4a7d9a7ed4 100644 --- a/packages/metro/src/DeltaBundler/Serializers/__tests__/baseJSBundle-test.js +++ b/packages/metro/src/DeltaBundler/Serializers/__tests__/baseJSBundle-test.js @@ -549,3 +549,63 @@ test('does not add polyfills when `modulesOnly` is used', () => { } `); }); + +test('inlines module ids when unstable_inlineDependencyMap is set', () => { + const NAME = 'DEP_MAP_RESERVED'; + const ref = `${NAME}[0]`; + const fooWithRefs: Module<> = { + ...fooModule, + output: [ + { + type: 'js/module', + data: { + code: `__d(function(g,r,i,a,m,e,${NAME}){r(${ref})});`, + map: [], + lineCount: 1, + }, + }, + ], + }; + + const bundle = baseJSBundle( + '/root/foo', + [polyfill], + { + dependencies: new Map([ + ['/root/foo', fooWithRefs], + ['/root/bar', barModule], + ]), + entryPoints: new Set(['/root/foo']), + transformOptions, + }, + { + asyncRequireModulePath: '', + createModuleId: createModuleIdFactory(), + dev: false, + getRunModuleStatement, + globalPrefix: '', + includeAsyncPaths: false, + inlineSourceMap: false, + modulesOnly: false, + processModuleFilter: () => true, + projectRoot: '/root', + runBeforeMainModule: [], + runModule: true, + serverRoot: '/root', + shouldAddToIgnoreList: () => false, + sourceMapUrl: null, + sourceUrl: null, + getSourceUrl: null, + dependencyMapReservedName: NAME, + unstable_inlineDependencyMap: true, + }, + ); + + // baseJSBundle pre-assigns sequential ids in graph order: foo=0, bar=1. + // foo's DEP_MAP_RESERVED[0] resolves to its first dependency (bar => 1), + // inlined and right-padded; the dependency-map array is dropped. + expect(bundle.modules).toEqual([ + [0, `__d(function(g,r,i,a,m,e,${NAME}){r(${'1'.padEnd(ref.length)})},0);`], + [1, '__d(function() {/* code for bar */},1);'], + ]); +}); diff --git a/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js b/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js index dcfa8297dc..1eb091216c 100644 --- a/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js +++ b/packages/metro/src/DeltaBundler/Serializers/baseJSBundle.js @@ -38,6 +38,8 @@ export default function baseJSBundle( projectRoot: options.projectRoot, serverRoot: options.serverRoot, sourceUrl: options.sourceUrl, + dependencyMapReservedName: options.dependencyMapReservedName, + unstable_inlineDependencyMap: options.unstable_inlineDependencyMap, }; // Do not prepend polyfills or the require runtime when only modules are requested diff --git a/packages/metro/src/DeltaBundler/Serializers/helpers/__tests__/js-test.js b/packages/metro/src/DeltaBundler/Serializers/helpers/__tests__/js-test.js index a010a9b53c..fdaed92354 100644 --- a/packages/metro/src/DeltaBundler/Serializers/helpers/__tests__/js-test.js +++ b/packages/metro/src/DeltaBundler/Serializers/helpers/__tests__/js-test.js @@ -12,7 +12,7 @@ import type {Dependency} from '../../../types'; import CountingSet from '../../../../lib/CountingSet'; -import {wrapModule} from '../js'; +import {inlineModuleIdReferences, wrapModule} from '../js'; import {wrap as raw} from 'jest-snapshot-serializer-raw'; import createModuleIdFactory from 'metro-config/private/defaults/createModuleIdFactory'; import nullthrows from 'nullthrows'; @@ -199,3 +199,146 @@ describe('wrapModule()', () => { ); }); }); + +describe('wrapModule() with inlined module ids', () => { + const NAME = 'DEPENDENCY_MAP'; + const ref = (i: number) => `${NAME}[${i}]`; + const baseInlineOptions = { + dev: false, + includeAsyncPaths: false, + projectRoot: '/root', + serverRoot: '/root', + sourceUrl: null, + dependencyMapReservedName: NAME, + unstable_inlineDependencyMap: true, + }; + + beforeEach(() => { + // foo=0 (self), bar=1, baz=2 with a fresh sequential id factory. + myModule.output[0].data.code = `__d(function(g,r,i,a,m,e,${NAME}){r(${ref( + 0, + )});r(${ref(1)})});`; + }); + + test('inlines sync ids and drops the dependency-map array', () => { + expect( + wrapModule(myModule, { + ...baseInlineOptions, + createModuleId: createModuleIdFactory(), + }), + ).toBe( + `__d(function(g,r,i,a,m,e,${NAME}){r(${'1'.padEnd( + ref(0).length, + )});r(${'2'.padEnd(ref(1).length)})},0);`, + ); + }); + + test('keeps a placeholder slot before the verbose name in dev', () => { + expect( + wrapModule(myModule, { + ...baseInlineOptions, + dev: true, + createModuleId: createModuleIdFactory(), + }), + ).toBe( + `__d(function(g,r,i,a,m,e,${NAME}){r(${'1'.padEnd( + ref(0).length, + )});r(${'2'.padEnd(ref(1).length)})},0,[],"foo.js");`, + ); + }); + + test('passes a paths object (not the id array) for async dependencies', () => { + const dep = nullthrows(myModule.dependencies.get('bar')); + myModule.dependencies.set('bar', { + ...dep, + data: {...dep.data, data: {...dep.data.data, asyncType: 'async'}}, + }); + expect( + wrapModule(myModule, { + ...baseInlineOptions, + includeAsyncPaths: true, + sourceUrl: 'http://localhost/Main.bundle?param1=true', + createModuleId: createModuleIdFactory(), + }), + ).toBe( + `__d(function(g,r,i,a,m,e,${NAME}){r(${'1'.padEnd( + ref(0).length, + )});r(${'2'.padEnd(ref(1).length)})},0,` + + `{"paths":{"1":"/../bar.bundle?param1=true&modulesOnly=true&runModule=false"}});`, + ); + }); + + test('does not inline when the flag is off, even with a reserved name', () => { + expect( + wrapModule(myModule, { + ...baseInlineOptions, + unstable_inlineDependencyMap: false, + createModuleId: createModuleIdFactory(), + }), + ).toBe( + `__d(function(g,r,i,a,m,e,${NAME}){r(${ref(0)});r(${ref(1)})},0,[1,2]);`, + ); + }); +}); + +describe('inlineModuleIdReferences()', () => { + const NAME = 'DEP_MAP_RESERVED_NAME'; + const ref = (i: number) => `${NAME}[${i}]`; + + test('returns code unchanged when there are no dependencies', () => { + const code = ref(0); + expect(inlineModuleIdReferences(code, NAME, [])).toBe(code); + }); + + test('replaces dependency-map references with resolved ids', () => { + const code = `require(${ref(0)}); require(${ref(1)});`; + const inlined = inlineModuleIdReferences(code, NAME, [7, 42]); + expect(inlined).toBe( + `require(${'7'.padEnd(ref(0).length)}); ` + + `require(${'42'.padEnd(ref(1).length)});`, + ); + expect(inlined.length).toBe(code.length); + }); + + test('right-pads ids to preserve byte offsets / source-map columns', () => { + const code = `x=${ref(0)};y=1;`; + const inlined = inlineModuleIdReferences(code, NAME, [3]); + expect(inlined.length).toBe(code.length); + expect(inlined).toBe(`x=${'3'.padEnd(ref(0).length)};y=1;`); + // Everything after the reference keeps its original column. + expect(inlined.indexOf('y=1;')).toBe(code.indexOf('y=1;')); + }); + + test('tolerates embedded tabs and spaces inside the reference', () => { + const code = `${NAME}\t[ 1 ]`; + const inlined = inlineModuleIdReferences(code, NAME, [0, 5]); + expect(inlined).toBe('5'.padEnd(code.length)); + expect(inlined.length).toBe(code.length); + }); + + test('throws when a resolved id is wider than the available space', () => { + // Short reserved name so the resolved id cannot fit in the reference width. + expect(() => inlineModuleIdReferences('D[0]', 'D', [12345])).toThrow( + "Module ID doesn't fit in available space; add 1 more characters to " + + "'dependencyMapReservedName'.", + ); + }); + + test('throws when the reserved name is absent but deps exist', () => { + expect(() => + inlineModuleIdReferences('require(someOtherName[0]);', NAME, [1]), + ).toThrow( + 'Module has dependencies but does not use the preconfigured dependency ' + + "map name 'DEP_MAP_RESERVED_NAME'", + ); + }); + + test('ignores a missing reserved name when told to', () => { + const code = 'require(someOtherName[0]);'; + expect( + inlineModuleIdReferences(code, NAME, [1], { + ignoreMissingDependencyMapReference: true, + }), + ).toBe(code); + }); +}); diff --git a/packages/metro/src/DeltaBundler/Serializers/helpers/js.js b/packages/metro/src/DeltaBundler/Serializers/helpers/js.js index 0853f49ac7..e66c7857f5 100644 --- a/packages/metro/src/DeltaBundler/Serializers/helpers/js.js +++ b/packages/metro/src/DeltaBundler/Serializers/helpers/js.js @@ -26,6 +26,11 @@ export type Options = Readonly<{ projectRoot: string, serverRoot: string, sourceUrl: ?string, + // When set (and `unstable_inlineDependencyMap` is true), resolved module IDs are + // inlined into each module body in place of `[i]` + // references, instead of being appended as a dependency-map array argument. + dependencyMapReservedName?: ?string, + unstable_inlineDependencyMap?: boolean, ... }>; @@ -36,14 +41,39 @@ export function wrapModule(module: Module<>, options: Options): string { return output.data.code; } + if ( + options.unstable_inlineDependencyMap === true && + options.dependencyMapReservedName != null + ) { + return wrapModuleWithInlinedDependencyIds( + module, + output.data.code, + options.dependencyMapReservedName, + options, + ); + } + const params = getModuleParams(module, options); return addParamsToDefineCall(output.data.code, ...params); } -export function getModuleParams( +function getModuleVerboseName(module: Module<>, options: Options): string { + // The relative path of the module, to make debugging easier. This is mapped + // to `module.verboseName` in `require.js`. + return normalizePathSeparatorsToPosix( + path.relative(options.projectRoot, module.path), + ); +} + +function getModuleDependencies( module: Module<>, options: Options, -): Array { +): { + moduleId: number | string, + dependencyMapArray: Array, + paths: {[moduleID: number | string]: unknown}, + hasPaths: boolean, +} { const moduleId = options.createModuleId(module.path); const paths: {[moduleID: number | string]: unknown} = {}; @@ -93,6 +123,18 @@ export function getModuleParams( }, ); + return {moduleId, dependencyMapArray, paths, hasPaths}; +} + +export function getModuleParams( + module: Module<>, + options: Options, +): Array { + const {moduleId, dependencyMapArray, paths, hasPaths} = getModuleDependencies( + module, + options, + ); + const params = [ moduleId, hasPaths @@ -105,18 +147,125 @@ export function getModuleParams( ]; if (options.dev) { - // Add the relative path of the module to make debugging easier. - // This is mapped to `module.verboseName` in `require.js`. - params.push( - normalizePathSeparatorsToPosix( - path.relative(options.projectRoot, module.path), - ), - ); + params.push(getModuleVerboseName(module, options)); } return params; } +// Wraps a module after inlining resolved module IDs into its body (via +// `inlineModuleIdReferences`). Because synchronous `[i]` +// references are replaced with literal IDs, the dependency-map array argument is +// redundant and dropped. Async requires still read `.paths`, so a +// `{paths}` object is passed in the dependency-map argument slot when needed. In +// dev, an empty array keeps that slot occupied so the verbose-name argument +// stays in position. +function wrapModuleWithInlinedDependencyIds( + module: Module<>, + code: string, + dependencyMapReservedName: string, + options: Options, +): string { + const {moduleId, dependencyMapArray, paths, hasPaths} = getModuleDependencies( + module, + options, + ); + + const inlinedCode = inlineModuleIdReferences( + code, + dependencyMapReservedName, + dependencyMapArray.map(id => (id == null ? 'null' : id)), + ); + + const params: Array = [moduleId]; + if (hasPaths) { + params.push({paths}); + } else if (options.dev) { + params.push([]); + } + if (options.dev) { + params.push(getModuleVerboseName(module, options)); + } + + return addParamsToDefineCall(inlinedCode, ...params); +} + +/** + * Fast path for inlining module IDs as a cheap string operation, requiring + * neither parsing nor any adjustment to the source map. + * + * Assumptions: + * 1. `dependencyMapReservedName` is a globally reserved string; there are + * no false positives. + * 2. The longest module ID in the bundle does not exceed a length of + * `dependencyMapReservedName.length + 3`. (We assert this below.) + * 3. False negatives (failing to inline occasionally if an assumption + * isn't met) are rare to nonexistent, but safe if they do occur. + * + * Syntax definitions: + * 1. A dependency map reference is a member expression which, if parsed, + * would have the form: + * MemberExpression + * ├──object: Identifier (name = dependencyMapReservedName) + * ├──property: NumericLiteral (value = some integer) + * └──computed: true + * 2. The concrete form of a dependency map reference may contain embedded + * tabs or spaces, but no newlines (which would complicate source maps), + * parens (which would complicate detection) or comments (likewise). + * 3. The numeric literal in a dependency map reference is a base-10 + * integer printed as a simple sequence of digits. + */ +export function inlineModuleIdReferences( + code: string, + dependencyMapReservedName: string, + dependencyIds: ReadonlyArray, + { + ignoreMissingDependencyMapReference = false, + }: Readonly<{ignoreMissingDependencyMapReference?: boolean}> = {}, +): string { + if (!dependencyIds.length) { + // Nothing to inline in this module. + return code; + } + + if (!code.includes(dependencyMapReservedName)) { + if (ignoreMissingDependencyMapReference) { + return code; + } + + // If we're here, the module was probably generated by some code that + // doesn't make the dependency map name externally configurable, or a + // mock that needs to be updated. + throw new Error( + `Module has dependencies but does not use the preconfigured dependency map name '${dependencyMapReservedName}'\n` + + 'This is an internal error in Metro.', + ); + } + const WS = '[\t ]*'; + const depMapReferenceRegex = new RegExp( + escapeRegex(dependencyMapReservedName) + `${WS}\\[${WS}([0-9]+)${WS}\\]`, + 'g', + ); + const inlinedCode = code.replace(depMapReferenceRegex, (match, depIndex) => { + const idStr = dependencyIds[Number.parseInt(depIndex, 10)].toString(); + if (idStr.length > match.length) { + // Stop the build rather than silently emit an incorrect source map. + throw new Error( + `Module ID doesn't fit in available space; add ${ + idStr.length - match.length + } more characters to 'dependencyMapReservedName'.`, + ); + } + return idStr.padEnd(match.length); + }); + return inlinedCode; +} + +function escapeRegex(str: string): string { + // From http://stackoverflow.com/questions/14076210/ + return str.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); +} + export function getJsOutput( module: Readonly<{ output: ReadonlyArray, diff --git a/packages/metro/src/DeltaBundler/Serializers/helpers/processModules.js b/packages/metro/src/DeltaBundler/Serializers/helpers/processModules.js index be9bb5d3cc..3319700a88 100644 --- a/packages/metro/src/DeltaBundler/Serializers/helpers/processModules.js +++ b/packages/metro/src/DeltaBundler/Serializers/helpers/processModules.js @@ -23,6 +23,8 @@ export default function processModules( projectRoot, serverRoot, sourceUrl, + dependencyMapReservedName, + unstable_inlineDependencyMap, }: Readonly<{ filter?: (module: Module<>) => boolean, createModuleId: string => number, @@ -31,6 +33,8 @@ export default function processModules( projectRoot: string, serverRoot: string, sourceUrl: ?string, + dependencyMapReservedName?: ?string, + unstable_inlineDependencyMap?: boolean, }>, ): ReadonlyArray<[Module<>, string]> { return [...modules] @@ -45,6 +49,8 @@ export default function processModules( projectRoot, serverRoot, sourceUrl, + dependencyMapReservedName, + unstable_inlineDependencyMap, }), ]); } diff --git a/packages/metro/src/DeltaBundler/types.js b/packages/metro/src/DeltaBundler/types.js index c35a40016d..c2490adedc 100644 --- a/packages/metro/src/DeltaBundler/types.js +++ b/packages/metro/src/DeltaBundler/types.js @@ -168,6 +168,7 @@ export type DeltaResult = { export type SerializerOptions = Readonly<{ asyncRequireModulePath: string, createModuleId: string => number, + dependencyMapReservedName?: ?string, dev: boolean, getRunModuleStatement: ( moduleId: number | string, @@ -186,4 +187,5 @@ export type SerializerOptions = Readonly<{ sourceMapUrl: ?string, sourceUrl: ?string, getSourceUrl: ?(Module<>) => string, + unstable_inlineDependencyMap?: boolean, }>; diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 29f5a88f3b..42c3cbebfc 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -266,6 +266,10 @@ export default class Server { this._shouldAddModuleToIgnoreList(module), getSourceUrl: (module: Module<>) => this._getModuleSourceUrl(module, serializerOptions.sourcePaths), + dependencyMapReservedName: + this._config.transformer.unstable_dependencyMapReservedName, + unstable_inlineDependencyMap: + this._config.serializer.unstable_inlineDependencyMap, }; let bundleCode = null; let bundleMap = null; @@ -412,6 +416,10 @@ export default class Server { this._shouldAddModuleToIgnoreList(module), getSourceUrl: (module: Module<>) => this._getModuleSourceUrl(module, serializerOptions.sourcePaths), + dependencyMapReservedName: + this._config.transformer.unstable_dependencyMapReservedName, + unstable_inlineDependencyMap: + this._config.serializer.unstable_inlineDependencyMap, }); } @@ -1158,6 +1166,10 @@ export default class Server { this._shouldAddModuleToIgnoreList(module), getSourceUrl: (module: Module<>) => this._getModuleSourceUrl(module, serializerOptions.sourcePaths), + dependencyMapReservedName: + this._config.transformer.unstable_dependencyMapReservedName, + unstable_inlineDependencyMap: + this._config.serializer.unstable_inlineDependencyMap, }, ); bundlePerfLogger.point('serializingBundle_end'); diff --git a/packages/metro/types/DeltaBundler/Serializers/helpers/js.d.ts b/packages/metro/types/DeltaBundler/Serializers/helpers/js.d.ts index b3ea436de3..c4110448c2 100644 --- a/packages/metro/types/DeltaBundler/Serializers/helpers/js.d.ts +++ b/packages/metro/types/DeltaBundler/Serializers/helpers/js.d.ts @@ -6,13 +6,13 @@ * * @noformat * @oncall react_native - * @generated SignedSource<> + * @generated SignedSource<> * * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js * Original file: packages/metro/src/DeltaBundler/Serializers/helpers/js.js * To regenerate, run: * js1 build metro-ts-defs (internal) OR - * yarn run build-ts-defs (OSS) + * yarn run build-ts-defs (OSS) */ import type {MixedOutput, Module} from '../../types'; @@ -27,8 +27,41 @@ export type Options = Readonly<{ projectRoot: string; serverRoot: string; sourceUrl: null | undefined | string; + dependencyMapReservedName?: null | undefined | string; + unstable_inlineDependencyMap?: boolean; }>; export declare function wrapModule(module: Module, options: Options): string; export declare function getModuleParams(module: Module, options: Options): Array; +/** + * Fast path for inlining module IDs as a cheap string operation, requiring + * neither parsing nor any adjustment to the source map. + * + * Assumptions: + * 1. `dependencyMapReservedName` is a globally reserved string; there are + * no false positives. + * 2. The longest module ID in the bundle does not exceed a length of + * `dependencyMapReservedName.length + 3`. (We assert this below.) + * 3. False negatives (failing to inline occasionally if an assumption + * isn't met) are rare to nonexistent, but safe if they do occur. + * + * Syntax definitions: + * 1. A dependency map reference is a member expression which, if parsed, + * would have the form: + * MemberExpression + * ├──object: Identifier (name = dependencyMapReservedName) + * ├──property: NumericLiteral (value = some integer) + * └──computed: true + * 2. The concrete form of a dependency map reference may contain embedded + * tabs or spaces, but no newlines (which would complicate source maps), + * parens (which would complicate detection) or comments (likewise). + * 3. The numeric literal in a dependency map reference is a base-10 + * integer printed as a simple sequence of digits. + */ +export declare function inlineModuleIdReferences( + code: string, + dependencyMapReservedName: string, + dependencyIds: ReadonlyArray, + $$PARAM_3$$?: Readonly<{ignoreMissingDependencyMapReference?: boolean}>, +): string; export declare function getJsOutput(module: Readonly<{output: ReadonlyArray; path?: string}>): JsOutput; export declare function isJsModule(module: Module): boolean; diff --git a/packages/metro/types/DeltaBundler/Serializers/helpers/processModules.d.ts b/packages/metro/types/DeltaBundler/Serializers/helpers/processModules.d.ts index c6ac12639b..d22a42b174 100644 --- a/packages/metro/types/DeltaBundler/Serializers/helpers/processModules.d.ts +++ b/packages/metro/types/DeltaBundler/Serializers/helpers/processModules.d.ts @@ -6,7 +6,7 @@ * * @noformat * @oncall react_native - * @generated SignedSource<<1c5fe56fba9dbedcde1dbaeb5a486467>> + * @generated SignedSource<<9225c6d36e106c7936277e8158e90dc0>> * * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js * Original file: packages/metro/src/DeltaBundler/Serializers/helpers/processModules.js @@ -27,6 +27,8 @@ declare function processModules( projectRoot: string; serverRoot: string; sourceUrl: null | undefined | string; + dependencyMapReservedName?: null | undefined | string; + unstable_inlineDependencyMap?: boolean; }>, ): ReadonlyArray<[Module, string]>; export default processModules; diff --git a/packages/metro/types/DeltaBundler/types.d.ts b/packages/metro/types/DeltaBundler/types.d.ts index ffd1307eed..379747808d 100644 --- a/packages/metro/types/DeltaBundler/types.d.ts +++ b/packages/metro/types/DeltaBundler/types.d.ts @@ -6,7 +6,7 @@ * * @noformat * @oncall react_native - * @generated SignedSource<<295faf3dbcdeffd6b15b9fa949b501cb>> + * @generated SignedSource<<1e7de4a3bc2a47dfb8f5031657e74bb6>> * * This file was translated from Flow by scripts/generateTypeScriptDefinitions.js * Original file: packages/metro/src/DeltaBundler/types.js @@ -126,6 +126,7 @@ export type DeltaResult = { export type SerializerOptions = Readonly<{ asyncRequireModulePath: string; createModuleId: ($$PARAM_0$$: string) => number; + dependencyMapReservedName?: null | undefined | string; dev: boolean; getRunModuleStatement: (moduleId: number | string, globalPrefix: string) => string; globalPrefix: string; @@ -141,4 +142,5 @@ export type SerializerOptions = Readonly<{ sourceMapUrl: null | undefined | string; sourceUrl: null | undefined | string; getSourceUrl: null | undefined | (($$PARAM_0$$: Module) => string); + unstable_inlineDependencyMap?: boolean; }>;