f7ba1c56e2
- Now event sources with content in source map should be resolved with absolute path
152 lines
5.5 KiB
JavaScript
152 lines
5.5 KiB
JavaScript
/*
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
Author Tobias Koppers @sokra
|
|
*/
|
|
var fs = require("fs");
|
|
var path = require("path");
|
|
var async = require("async");
|
|
var loaderUtils = require("loader-utils");
|
|
|
|
var separatorRegex = /[/\\]/;
|
|
|
|
// Matches only the last occurrence of sourceMappingURL
|
|
var baseRegex = "\\s*[@#]\\s*sourceMappingURL\\s*=\\s*([^\\s]*)(?![\\S\\s]*sourceMappingURL)",
|
|
// Matches /* ... */ comments
|
|
regex1 = new RegExp("/\\*" + baseRegex + "\\s*\\*/"),
|
|
// Matches // .... comments
|
|
regex2 = new RegExp("//" + baseRegex + "($|\n|\r\n?)"),
|
|
// Matches DataUrls
|
|
regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/;
|
|
|
|
module.exports = function (input, inputMap) {
|
|
this.cacheable && this.cacheable();
|
|
var resolve = this.resolve;
|
|
var addDependency = this.addDependency;
|
|
var emitWarning = this.emitWarning || function () {
|
|
};
|
|
var match = input.match(regex1) || input.match(regex2);
|
|
if (match) {
|
|
var url = match[1];
|
|
var dataUrlMatch = regexDataUrl.exec(url);
|
|
var callback = this.async();
|
|
if (dataUrlMatch) {
|
|
var mapBase64 = dataUrlMatch[1];
|
|
var mapStr = (new Buffer(mapBase64, "base64")).toString();
|
|
var map;
|
|
try {
|
|
map = JSON.parse(mapStr)
|
|
}
|
|
catch (e) {
|
|
emitWarning("Cannot parse inline SourceMap '" + mapBase64.substr(0, 50) + "': " + e);
|
|
return untouched();
|
|
}
|
|
processMap(map, this.context, callback);
|
|
}
|
|
else {
|
|
resolve(this.context, loaderUtils.urlToRequest(url, true), function (err, result) {
|
|
if (err) {
|
|
emitWarning("Cannot find SourceMap '" + url + "': " + err);
|
|
return untouched();
|
|
}
|
|
addDependency(result);
|
|
fs.readFile(result, "utf-8", function (err, content) {
|
|
if (err) {
|
|
emitWarning("Cannot open SourceMap '" + result + "': " + err);
|
|
return untouched();
|
|
}
|
|
var map;
|
|
try {
|
|
map = JSON.parse(content);
|
|
}
|
|
catch (e) {
|
|
emitWarning("Cannot parse SourceMap '" + url + "': " + e);
|
|
return untouched();
|
|
}
|
|
processMap(map, path.dirname(result), callback);
|
|
});
|
|
}.bind(this));
|
|
|
|
}
|
|
}
|
|
else {
|
|
var callback = this.callback;
|
|
return untouched();
|
|
}
|
|
|
|
function untouched() {
|
|
callback(null, input, inputMap);
|
|
}
|
|
|
|
function resize(arr, size, defval) {
|
|
while (arr.length > size) {
|
|
arr.pop();
|
|
}
|
|
while (arr.length < size) {
|
|
arr.push(defval);
|
|
}
|
|
}
|
|
|
|
function processMap(map, context, callback) {
|
|
function setResult(map) {
|
|
callback(null, input.replace(match[0], ''), map);
|
|
}
|
|
|
|
var sourcesWithoutContent = [];
|
|
map.sourcesContent = map.sourcesContent || [];
|
|
resize(map.sourcesContent, map.sources.length, null);
|
|
map.sourcesContent.forEach(function (sourceContent, i) {
|
|
if (!sourceContent) {
|
|
sourcesWithoutContent.push({source: map.sources[i], index: i})
|
|
}
|
|
else {
|
|
var source = map.sources[i];
|
|
if (separatorRegex.test(source) && !path.isAbsolute(source)) {
|
|
map.sources[i] = path.resolve(context, source);
|
|
}
|
|
}
|
|
});
|
|
|
|
if (sourcesWithoutContent.length == 0) {
|
|
setResult(map)
|
|
}
|
|
else {
|
|
var sourcePrefix = map.sourceRoot ? map.sourceRoot + "/" : "";
|
|
async.map(sourcesWithoutContent, function (item, callback) {
|
|
var source = sourcePrefix + item.source;
|
|
map.sources = map.sources.map(function (s) {
|
|
return sourcePrefix + s;
|
|
});
|
|
delete map.sourceRoot;
|
|
resolve(context, loaderUtils.urlToRequest(source, true), function (err, result) {
|
|
if (err) {
|
|
// TODO(ilgonmic): Not all JS files have sources content, and we don't extract sources from jar,
|
|
// so there is no content for these files
|
|
// emitWarning("Cannot find source file '" + source + "': " + err);
|
|
return callback(null, null);
|
|
}
|
|
addDependency(result);
|
|
fs.readFile(result, "utf-8", function (err, content) {
|
|
if (err) {
|
|
emitWarning("Cannot open source file '" + result + "': " + err);
|
|
return callback(null, null);
|
|
}
|
|
callback(null, {
|
|
index: item.index,
|
|
source: result,
|
|
content: content
|
|
});
|
|
});
|
|
});
|
|
}, function (err, info) {
|
|
info.forEach(function (item) {
|
|
if (item) {
|
|
map.sources[item.index] = item.source;
|
|
map.sourcesContent[item.index] = item.content;
|
|
}
|
|
});
|
|
setResult(map);
|
|
});
|
|
}
|
|
}
|
|
};
|