diff --git a/src/assets/JSAsset.js b/src/assets/JSAsset.js index c9e6c1422b3..3e089da0924 100644 --- a/src/assets/JSAsset.js +++ b/src/assets/JSAsset.js @@ -119,23 +119,57 @@ class JSAsset extends Asset { let dataURLMatch = url.match(DATA_URL_RE); try { - let json; + let json, filename; if (dataURLMatch) { + filename = this.name; json = new Buffer(dataURLMatch[1], 'base64').toString(); } else { - json = await fs.readFile( - path.join(path.dirname(this.name), url), - 'utf8' - ); + filename = path.join(path.dirname(this.name), url); + json = await fs.readFile(filename, 'utf8'); + + // Add as a dep so we watch the source map for changes. + this.addDependency(filename, {includedInParent: true}); } this.sourceMap = JSON.parse(json); - // Add as a dep so we watch the source map for changes. - this.addDependency(match[1], {includedInParent: true}); + // Attempt to read missing source contents + if (!this.sourceMap.sourcesContent) { + this.sourceMap.sourcesContent = []; + } + + let missingSources = this.sourceMap.sources.slice( + this.sourceMap.sourcesContent.length + ); + if (missingSources.length) { + let contents = await Promise.all( + missingSources.map(async source => { + try { + let sourceFile = path.join( + path.dirname(filename), + this.sourceMap.sourceRoot || '', + source + ); + let result = await fs.readFile(sourceFile, 'utf8'); + this.addDependency(sourceFile, {includedInParent: true}); + return result; + } catch (err) { + logger.warn( + `Could not load source file "${source}" in source map of "${ + this.relativeName + }".` + ); + } + }) + ); + + this.sourceMap.sourcesContent = this.sourceMap.sourcesContent.concat( + contents + ); + } } catch (e) { logger.warn( - `Could not load existing sourcemap of ${this.relativeName}.` + `Could not load existing sourcemap of "${this.relativeName}".` ); } } diff --git a/test/integration/sourcemap-external-contents/index.js b/test/integration/sourcemap-external-contents/index.js new file mode 100644 index 00000000000..66b67d1dbc5 --- /dev/null +++ b/test/integration/sourcemap-external-contents/index.js @@ -0,0 +1,5 @@ +const sum = require('./sum'); + +module.exports = function() { + return sum(1, 2); +} \ No newline at end of file diff --git a/test/integration/sourcemap-external-contents/sum.coffee b/test/integration/sourcemap-external-contents/sum.coffee new file mode 100644 index 00000000000..e84213f385f --- /dev/null +++ b/test/integration/sourcemap-external-contents/sum.coffee @@ -0,0 +1 @@ +module.exports = (a, b) => a + b diff --git a/test/integration/sourcemap-external-contents/sum.js b/test/integration/sourcemap-external-contents/sum.js new file mode 100644 index 00000000000..00d08409ec2 --- /dev/null +++ b/test/integration/sourcemap-external-contents/sum.js @@ -0,0 +1,11 @@ +// Generated by CoffeeScript 1.12.6 +(function() { + module.exports = (function(_this) { + return function(a, b) { + return a + b; + }; + })(this); + +}).call(this); + +//# sourceMappingURL=sum.map diff --git a/test/integration/sourcemap-external-contents/sum.map b/test/integration/sourcemap-external-contents/sum.map new file mode 100644 index 00000000000..87b0481c875 --- /dev/null +++ b/test/integration/sourcemap-external-contents/sum.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "file": "sum.js", + "sourceRoot": "", + "sources": [ + "sum.coffee" + ], + "names": [], + "mappings": ";AAAA;EAAA,MAAM,CAAC,OAAP,GAAiB,CAAA,SAAA,KAAA;WAAA,SAAC,CAAD,EAAI,CAAJ;aAAU,CAAA,GAAI;IAAd;EAAA,CAAA,CAAA,CAAA,IAAA;AAAjB" +} diff --git a/test/sourcemaps.js b/test/sourcemaps.js index c8bb5f51a88..be8b1223ad0 100644 --- a/test/sourcemaps.js +++ b/test/sourcemaps.js @@ -274,4 +274,40 @@ describe('sourcemaps', function() { ); mapValidator(jsOutput, map); }); + + it('should load referenced contents of sourcemaps', async function() { + let b = await bundle( + __dirname + '/integration/sourcemap-external-contents/index.js' + ); + + assertBundleTree(b, { + name: 'index.js', + assets: ['index.js', 'sum.js'], + childBundles: [ + { + type: 'map' + } + ] + }); + + let jsOutput = await fs.readFile(b.name, 'utf8'); + + let sourcemapReference = path.join( + __dirname, + '/dist/', + jsOutput.substring(jsOutput.lastIndexOf('//# sourceMappingURL') + 22) + ); + + assert( + await fs.exists(path.join(sourcemapReference)), + 'referenced sourcemap should exist' + ); + + let map = await fs.readFile(path.join(sourcemapReference), 'utf8'); + assert( + map.indexOf('module.exports = (a, b) => a + b') > -1, + 'Sourcemap should contain the existing sourcemap' + ); + mapValidator(jsOutput, map); + }); });