diff --git a/packages/metro/src/DeltaBundler/Serializers/__tests__/sourceMapString-test.js b/packages/metro/src/DeltaBundler/Serializers/__tests__/sourceMapString-test.js index baa902b3af..592e7928dd 100644 --- a/packages/metro/src/DeltaBundler/Serializers/__tests__/sourceMapString-test.js +++ b/packages/metro/src/DeltaBundler/Serializers/__tests__/sourceMapString-test.js @@ -15,7 +15,10 @@ import type {Module} from '../../types.flow'; import CountingSet from '../../../lib/CountingSet'; -const sourceMapString = require('../sourceMapString'); +const { + sourceMapString, + sourceMapStringNonBlocking, +} = require('../sourceMapString'); const polyfill: Module<> = { path: '/root/pre.js', @@ -77,102 +80,119 @@ const barModule: Module<> = { ], }; -it('should serialize a very simple bundle', () => { - expect( - JSON.parse( - sourceMapString([polyfill, fooModule, barModule], { - excludeSource: false, - processModuleFilter: module => true, - shouldAddToIgnoreList: module => false, - getSourceUrl: null, - }), - ), - ).toEqual({ - version: 3, - sources: ['/root/pre.js', '/root/foo.js', '/root/bar.js'], - sourcesContent: ['source pre', 'source foo', 'source bar'], - x_facebook_sources: [null, [{names: [''], mappings: 'AAA'}], null], - names: [], - mappings: '', - }); -}); +describe.each([sourceMapString, sourceMapStringNonBlocking])( + '%p', + sourceMapStringImpl => { + test('should serialize a very simple bundle', async () => { + expect( + JSON.parse( + await sourceMapStringImpl([polyfill, fooModule, barModule], { + excludeSource: false, + processModuleFilter: module => true, + shouldAddToIgnoreList: module => false, + getSourceUrl: null, + }), + ), + ).toEqual({ + version: 3, + sources: ['/root/pre.js', '/root/foo.js', '/root/bar.js'], + sourcesContent: ['source pre', 'source foo', 'source bar'], + x_facebook_sources: [ + null, + [{names: [''], mappings: 'AAA'}], + null, + ], + names: [], + mappings: '', + }); + }); -it('modules should appear in their original order', () => { - expect( - JSON.parse( - sourceMapString([polyfill, barModule, fooModule], { - excludeSource: false, - processModuleFilter: module => true, - shouldAddToIgnoreList: module => false, - getSourceUrl: null, - }), - ), - ).toEqual({ - version: 3, - sources: ['/root/pre.js', '/root/bar.js', '/root/foo.js'], - sourcesContent: ['source pre', 'source bar', 'source foo'], - x_facebook_sources: [null, null, [{names: [''], mappings: 'AAA'}]], - names: [], - mappings: '', - }); -}); + test('modules should appear in their original order', async () => { + expect( + JSON.parse( + await sourceMapStringImpl([polyfill, barModule, fooModule], { + excludeSource: false, + processModuleFilter: module => true, + shouldAddToIgnoreList: module => false, + getSourceUrl: null, + }), + ), + ).toEqual({ + version: 3, + sources: ['/root/pre.js', '/root/bar.js', '/root/foo.js'], + sourcesContent: ['source pre', 'source bar', 'source foo'], + x_facebook_sources: [ + null, + null, + [{names: [''], mappings: 'AAA'}], + ], + names: [], + mappings: '', + }); + }); -it('should not include the source of an asset', () => { - const assetModule: Module<> = { - path: '/root/asset.jpg', - dependencies: new Map(), - inverseDependencies: new CountingSet(), - getSource: () => { - throw new Error('should not read the source of an asset'); - }, - output: [ - { - type: 'js/module/asset', - data: { - code: '__d(function() {/* code for bar */});', - lineCount: 1, - map: [], + test('should not include the source of an asset', async () => { + const assetModule: Module<> = { + path: '/root/asset.jpg', + dependencies: new Map(), + inverseDependencies: new CountingSet(), + getSource: () => { + throw new Error('should not read the source of an asset'); }, - }, - ], - }; + output: [ + { + type: 'js/module/asset', + data: { + code: '__d(function() {/* code for bar */});', + lineCount: 1, + map: [], + }, + }, + ], + }; - expect( - JSON.parse( - sourceMapString([fooModule, assetModule], { - excludeSource: false, - processModuleFilter: module => true, - shouldAddToIgnoreList: module => false, - getSourceUrl: null, - }), - ), - ).toEqual({ - version: 3, - sources: ['/root/foo.js', '/root/asset.jpg'], - sourcesContent: ['source foo', ''], - x_facebook_sources: [[{names: [''], mappings: 'AAA'}], null], - names: [], - mappings: '', - }); -}); + expect( + JSON.parse( + await sourceMapStringImpl([fooModule, assetModule], { + excludeSource: false, + processModuleFilter: module => true, + shouldAddToIgnoreList: module => false, + getSourceUrl: null, + }), + ), + ).toEqual({ + version: 3, + sources: ['/root/foo.js', '/root/asset.jpg'], + sourcesContent: ['source foo', ''], + x_facebook_sources: [[{names: [''], mappings: 'AAA'}], null], + names: [], + mappings: '', + }); + }); -it('should emit x_google_ignoreList based on shouldAddToIgnoreList', () => { - expect( - JSON.parse( - sourceMapString([polyfill, fooModule, barModule], { - excludeSource: false, - processModuleFilter: module => true, - shouldAddToIgnoreList: module => true, - getSourceUrl: null, - }), - ), - ).toEqual({ - version: 3, - sources: ['/root/pre.js', '/root/foo.js', '/root/bar.js'], - sourcesContent: ['source pre', 'source foo', 'source bar'], - x_facebook_sources: [null, [{names: [''], mappings: 'AAA'}], null], - names: [], - mappings: '', - x_google_ignoreList: [0, 1, 2], - }); -}); + test('should emit x_google_ignoreList based on shouldAddToIgnoreList', async () => { + expect( + JSON.parse( + await sourceMapStringImpl([polyfill, fooModule, barModule], { + excludeSource: false, + processModuleFilter: module => true, + shouldAddToIgnoreList: module => true, + getSourceUrl: null, + }), + ), + ).toEqual({ + version: 3, + sources: ['/root/pre.js', '/root/foo.js', '/root/bar.js'], + sourcesContent: ['source pre', 'source foo', 'source bar'], + x_facebook_sources: [ + null, + [{names: [''], mappings: 'AAA'}], + null, + ], + names: [], + mappings: '', + x_google_ignoreList: [0, 1, 2], + }); + }); + }, +); diff --git a/packages/metro/src/DeltaBundler/Serializers/sourceMapString.js b/packages/metro/src/DeltaBundler/Serializers/sourceMapString.js index ee6c9dfab7..d755a0599d 100644 --- a/packages/metro/src/DeltaBundler/Serializers/sourceMapString.js +++ b/packages/metro/src/DeltaBundler/Serializers/sourceMapString.js @@ -14,7 +14,10 @@ import type {Module} from '../types.flow'; import type {SourceMapGeneratorOptions} from './sourceMapGenerator'; -const {sourceMapGenerator} = require('./sourceMapGenerator'); +const { + sourceMapGenerator, + sourceMapGeneratorNonBlocking, +} = require('./sourceMapGenerator'); function sourceMapString( modules: $ReadOnlyArray>, @@ -25,4 +28,17 @@ function sourceMapString( }); } -module.exports = sourceMapString; +async function sourceMapStringNonBlocking( + modules: $ReadOnlyArray>, + options: SourceMapGeneratorOptions, +): Promise { + const generator = await sourceMapGeneratorNonBlocking(modules, options); + return generator.toString(undefined, { + excludeSource: options.excludeSource, + }); +} + +module.exports = { + sourceMapString, + sourceMapStringNonBlocking, +}; diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 3db4fe62ff..ce94a10fe9 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -53,7 +53,9 @@ const { getExplodedSourceMap, } = require('./DeltaBundler/Serializers/getExplodedSourceMap'); const getRamBundleInfo = require('./DeltaBundler/Serializers/getRamBundleInfo'); -const sourceMapString = require('./DeltaBundler/Serializers/sourceMapString'); +const { + sourceMapStringNonBlocking, +} = require('./DeltaBundler/Serializers/sourceMapString'); const IncrementalBundler = require('./IncrementalBundler'); const ResourceNotFoundError = require('./IncrementalBundler/ResourceNotFoundError'); const bundleToString = require('./lib/bundleToString'); @@ -288,7 +290,7 @@ class Server { ).code; } if (!bundleMap) { - bundleMap = sourceMapString( + bundleMap = await sourceMapStringNonBlocking( [...prepend, ...this._getSortedModules(graph)], { excludeSource: serializerOptions.excludeSource, @@ -1151,14 +1153,17 @@ class Server { prepend = []; } - return sourceMapString([...prepend, ...this._getSortedModules(graph)], { - excludeSource: serializerOptions.excludeSource, - processModuleFilter: this._config.serializer.processModuleFilter, - shouldAddToIgnoreList: (module: Module<>) => - this._shouldAddModuleToIgnoreList(module), - getSourceUrl: (module: Module<>) => - this._getModuleSourceUrl(module, serializerOptions.sourcePaths), - }); + return await sourceMapStringNonBlocking( + [...prepend, ...this._getSortedModules(graph)], + { + excludeSource: serializerOptions.excludeSource, + processModuleFilter: this._config.serializer.processModuleFilter, + shouldAddToIgnoreList: (module: Module<>) => + this._shouldAddModuleToIgnoreList(module), + getSourceUrl: (module: Module<>) => + this._getModuleSourceUrl(module, serializerOptions.sourcePaths), + }, + ); }, finish({mres, result}) { mres.setHeader('Content-Type', 'application/json'); diff --git a/packages/metro/src/lib/getAppendScripts.js b/packages/metro/src/lib/getAppendScripts.js index 730486dbdb..4e7ea7bc29 100644 --- a/packages/metro/src/lib/getAppendScripts.js +++ b/packages/metro/src/lib/getAppendScripts.js @@ -16,7 +16,9 @@ import type {Dependency} from '../DeltaBundler/types.flow'; import CountingSet from './CountingSet'; const getInlineSourceMappingURL = require('../DeltaBundler/Serializers/helpers/getInlineSourceMappingURL'); -const sourceMapString = require('../DeltaBundler/Serializers/sourceMapString'); +const { + sourceMapString, +} = require('../DeltaBundler/Serializers/sourceMapString'); const countLines = require('./countLines'); const nullthrows = require('nullthrows');