diff --git a/packages/core/parcel-bundler/src/SourceMap.js b/packages/core/parcel-bundler/src/SourceMap.js index 82a3a7ba7e3..c7415aa778b 100644 --- a/packages/core/parcel-bundler/src/SourceMap.js +++ b/packages/core/parcel-bundler/src/SourceMap.js @@ -10,20 +10,20 @@ class SourceMap { purifyMappings(mappings) { if (Array.isArray(mappings)) { - return mappings.filter(mapping => { - return ( + return mappings.filter( + mapping => mapping && - mapping.source && - mapping.original && - typeof mapping.original.line === 'number' && - mapping.original.line > 0 && - typeof mapping.original.column === 'number' && + (typeof mapping.original === 'object' && + (mapping.original === null || + (typeof mapping.original.line === 'number' && + mapping.original.line > 0 && + typeof mapping.original.column === 'number' && + mapping.source))) && mapping.generated && typeof mapping.generated.line === 'number' && mapping.generated.line > 0 && typeof mapping.generated.column === 'number' - ); - }); + ); } return []; @@ -34,12 +34,14 @@ class SourceMap { return map; } map = typeof map === 'string' ? JSON.parse(map) : map; + if (map.sourceRoot) delete map.sourceRoot; return await new SourceMapConsumer(map); } async addMap(map, lineOffset = 0, columnOffset = 0) { - if (!(map instanceof SourceMap) && map.version) { + if (typeof map === 'string' || (typeof map === 'object' && map.version)) { let consumer = await this.getConsumer(map); + if (!consumer) return this; consumer.eachMapping(mapping => { this.addConsumerMapping(mapping, lineOffset, columnOffset); @@ -55,7 +57,7 @@ class SourceMap { // Only needs to happen in source-map 0.7 consumer.destroy(); } - } else { + } else if (map.mappings && map.sources) { if (!map.eachMapping) { map = new SourceMap(map.mappings, map.sources); } @@ -91,21 +93,22 @@ class SourceMap { } addConsumerMapping(mapping, lineOffset = 0, columnOffset = 0) { + let original = null; if ( - !mapping.source || - !mapping.originalLine || - (!mapping.originalColumn && mapping.originalColumn !== 0) + typeof mapping.originalLine === 'number' && + mapping.originalLine > 0 && + typeof mapping.originalColumn === 'number' ) { - return; + original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; } this.mappings.push({ - source: mapping.source, + source: original ? mapping.source : null, name: mapping.name, - original: { - line: mapping.originalLine, - column: mapping.originalColumn - }, + original, generated: { line: mapping.generatedLine + lineOffset, column: mapping.generatedColumn + columnOffset diff --git a/packages/core/parcel-bundler/test/sourcemaps.js b/packages/core/parcel-bundler/test/sourcemaps.js new file mode 100644 index 00000000000..8e6b41cbea4 --- /dev/null +++ b/packages/core/parcel-bundler/test/sourcemaps.js @@ -0,0 +1,199 @@ +const assert = require('assert'); +const fs = require('@parcel/fs'); +const SourceMap = require('../src/SourceMap'); + +describe('sourcemaps', function() { + it('should purify mappings properly', async function() { + let mappings = [ + { + source: 'index.js', + name: 'A', + original: { + line: 0, + column: 0 + }, + generated: { + line: 0, + column: 0 + } + }, + { + generated: { + line: 1, + column: 0 + }, + original: null, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: null, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 0, + column: 0 + }, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 1, + column: 0 + }, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 1, + column: 0 + }, + source: 'index.js', + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 0, + column: 0 + }, + source: 'index.js', + name: null + }, + { + source: 'index.js', + name: 'A', + original: { + line: 1, + column: 18 + }, + generated: { + line: 4, + column: 187 + } + } + ]; + + let expectedResult = [ + { + generated: { + line: 1, + column: 0 + }, + original: null, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: null, + source: null, + name: null + }, + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 1, + column: 0 + }, + source: 'index.js', + name: null + }, + { + source: 'index.js', + name: 'A', + original: { + line: 1, + column: 18 + }, + generated: { + line: 4, + column: 187 + } + } + ]; + + let sourcemap = new SourceMap(mappings, {}); + assert.deepEqual(sourcemap.mappings, expectedResult); + }); + + it('should be able to handle null mappings properly', async function() { + let mappings = [ + { + generated: { + line: 1, + column: 0 + }, + original: { + line: 1, + column: 0 + }, + source: 'input.js', + name: 'console' + }, + { + generated: { + line: 1, + column: 7 + }, + original: null, + source: null, + name: null + } + ]; + + let sources = { + 'input.js': 'console.log("hello world!");' + }; + + let sourcemap = new SourceMap(mappings, sources); + assert.equal(sourcemap.mappings.length, 2); + assert.deepEqual(sourcemap.mappings, mappings); + + let mapString = sourcemap.stringify('index.map', '/'); + let combinedSourcemap = new SourceMap(mappings, sources); + await combinedSourcemap.addMap(mapString); + + let newMapString = combinedSourcemap.stringify('index.map', '/'); + assert.equal(mapString, newMapString); + + let newSourcemap = new SourceMap([], {}); + await newSourcemap.addMap(sourcemap); + + assert.deepEqual(newSourcemap.mappings, mappings); + + newSourcemap = new SourceMap([], {}); + await newSourcemap.addMap(mapString); + + assert.deepEqual(newSourcemap.mappings, mappings); + }); +}); diff --git a/yarn.lock b/yarn.lock index 58a74374437..00f2d72ef1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1956,12 +1956,7 @@ acorn@^4.0.4, acorn@~4.0.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= -acorn@^5.0.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" - integrity sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ== - -acorn@^5.5.0: +acorn@^5.0.0, acorn@^5.5.0: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== @@ -3222,9 +3217,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000899" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000899.tgz#f66d667d507c2aa19603a4a3763d71aa89cc360f" - integrity sha512-MSCUohyoLU4/PGapapw/PLQkmQ+sFgzX6e3tM6ue8HX9HW9rBD5gRiAYKhC8r0QkvUE0pWTA8Ze6f3jrzBizVg== + version "1.0.30000946" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000946.tgz#c8fd9a53ccd23e26d87b6e22a4bdf257b7aff36c" + integrity sha512-qjpdekHW9uyy1U/VxuoR9ppn8HjoBxsR5dRTpumUeoYgL8IWUeos+QpJh9DaDdjaKitkNzgAFMXCZLDYKWWyEQ== caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000898: version "1.0.30000899" @@ -4634,7 +4629,12 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.81: +electron-to-chromium@^1.2.7: + version "1.3.115" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.115.tgz#fdaa56c19b9f7386dbf29abc1cc632ff5468ff3b" + integrity sha512-mN2qeapQWdi2B9uddxTZ4nl80y46hbyKY5Wt9Yjih+QZFQLdaujEDK4qJky35WhyxMzHF3ZY41Lgjd2BPDuBhg== + +electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.81: version "1.3.82" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.82.tgz#7d13ae4437d2a783de3f4efba96b186c540b67b1" integrity sha512-NI4nB2IWGcU4JVT1AE8kBb/dFor4zjLHMLsOROPahppeHrR0FG5uslxMmkp/thO1MvPjM2xhlKoY29/I60s0ew== @@ -6720,9 +6720,9 @@ jest-validate@^23.5.0: pretty-format "^23.6.0" js-base64@^2.1.9: - version "2.4.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" - integrity sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ== + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== js-beautify@^1.7.5: version "1.8.8"