Resolve sources relative to the source map

Source Map Revision 3: Resolving Sources
If the sources are not absolute URLs after prepending of the
“sourceRoot”, the sources are resolved relative to the SourceMap (like
resolving script src in a html document).
This commit is contained in:
Florian Reiterer 2013-03-18 23:43:02 +01:00
parent 5be2906874
commit 161be66adc
2 changed files with 31 additions and 24 deletions

View File

@ -19,13 +19,19 @@ function mapSourcePosition(cache, position) {
if (fs.existsSync(sourceMappingURL)) {
var sourceMapData = fs.readFileSync(sourceMappingURL, 'utf8');
try {
sourceMap = new SourceMapConsumer(sourceMapData);
sourceMap = [sourceMappingURL, new SourceMapConsumer(sourceMapData)];
cache[position.source] = sourceMap;
} catch (e) {
}
}
}
return sourceMap ? sourceMap.originalPositionFor(position) : position;
if (sourceMap) {
var originalPosition = sourceMap[1].originalPositionFor(position);
originalPosition.source = path.resolve(path.dirname(sourceMap[0]), originalPosition.source)
return originalPosition
} else {
return position
}
}
// Parses code generated by FormatEvalOrigin(), a function inside V8:

45
test.js
View File

@ -4,6 +4,7 @@ var SourceMapGenerator = require('source-map').SourceMapGenerator;
var child_process = require('child_process');
var assert = require('assert');
var fs = require('fs');
var path = require('path');
function compareStackTrace(source, expected) {
var sourceMap = new SourceMapGenerator({
@ -64,7 +65,7 @@ it('normal throw', function() {
'throw new Error("test");'
], [
'Error: test',
' at Object.exports.test (./line1.js:1001:101)'
' at Object.exports.test ('+path.join(process.cwd(),'line1.js')+':1001:101)'
]);
});
@ -76,8 +77,8 @@ it('throw inside function', function() {
'foo();'
], [
'Error: test',
' at foo (./line2.js:1002:102)',
' at Object.exports.test (./line4.js:1004:104)'
' at foo ('+path.join(process.cwd(),'line2.js')+':1002:102)',
' at Object.exports.test ('+path.join(process.cwd(),'line4.js')+':1004:104)'
]);
});
@ -92,9 +93,9 @@ it('throw inside function inside function', function() {
'foo();'
], [
'Error: test',
' at bar (./line3.js:1003:103)',
' at foo (./line5.js:1005:105)',
' at Object.exports.test (./line7.js:1007:107)'
' at bar ('+path.join(process.cwd(),'line3.js')+':1003:103)',
' at foo ('+path.join(process.cwd(),'line5.js')+':1005:105)',
' at Object.exports.test ('+path.join(process.cwd(),'line7.js')+':1007:107)'
]);
});
@ -103,8 +104,8 @@ it('eval', function() {
'eval("throw new Error(\'test\')");'
], [
'Error: test',
' at Object.eval (eval at <anonymous> (./line1.js:1001:101))',
' at Object.exports.test (./line1.js:1001:101)'
' at Object.eval (eval at <anonymous> ('+path.join(process.cwd(),'line1.js')+':1001:101))',
' at Object.exports.test ('+path.join(process.cwd(),'line1.js')+':1001:101)'
]);
});
@ -113,9 +114,9 @@ it('eval inside eval', function() {
'eval("eval(\'throw new Error(\\"test\\")\')");'
], [
'Error: test',
' at Object.eval (eval at <anonymous> (eval at <anonymous> (./line1.js:1001:101)))',
' at Object.eval (eval at <anonymous> (./line1.js:1001:101))',
' at Object.exports.test (./line1.js:1001:101)'
' at Object.eval (eval at <anonymous> (eval at <anonymous> ('+path.join(process.cwd(),'line1.js')+':1001:101)))',
' at Object.eval (eval at <anonymous> ('+path.join(process.cwd(),'line1.js')+':1001:101))',
' at Object.exports.test ('+path.join(process.cwd(),'line1.js')+':1001:101)'
]);
});
@ -127,9 +128,9 @@ it('eval inside function', function() {
'foo();'
], [
'Error: test',
' at eval (eval at foo (./line2.js:1002:102))',
' at foo (./line2.js:1002:102)',
' at Object.exports.test (./line4.js:1004:104)'
' at eval (eval at foo ('+path.join(process.cwd(),'line2.js')+':1002:102))',
' at foo ('+path.join(process.cwd(),'line2.js')+':1002:102)',
' at Object.exports.test ('+path.join(process.cwd(),'line4.js')+':1004:104)'
]);
});
@ -139,7 +140,7 @@ it('eval with sourceURL', function() {
], [
'Error: test',
' at Object.eval (sourceURL.js:1:7)',
' at Object.exports.test (./line1.js:1001:101)'
' at Object.exports.test ('+path.join(process.cwd(),'line1.js')+':1001:101)'
]);
});
@ -149,8 +150,8 @@ it('eval with sourceURL inside eval', function() {
], [
'Error: test',
' at Object.eval (sourceURL.js:1:7)',
' at Object.eval (eval at <anonymous> (./line1.js:1001:101))',
' at Object.exports.test (./line1.js:1001:101)'
' at Object.eval (eval at <anonymous> ('+path.join(process.cwd(),'line1.js')+':1001:101))',
' at Object.exports.test ('+path.join(process.cwd(),'line1.js')+':1001:101)'
]);
});
@ -163,11 +164,11 @@ it('default options', function(done) {
'process.nextTick(function() { process.exit(1); });'
], [
'',
'./.original.js:1',
path.join(process.cwd(),'.original.js')+':1',
'this is the original code',
'^',
'Error: this is the error',
' at foo (./.original.js:1:1)'
' at foo ('+path.join(process.cwd(),'.original.js')+':1:1)'
]);
});
@ -179,11 +180,11 @@ it('handleUncaughtExceptions is true', function(done) {
'process.nextTick(foo);'
], [
'',
'./.original.js:1',
path.join(process.cwd(),'.original.js')+':1',
'this is the original code',
'^',
'Error: this is the error',
' at foo (./.original.js:1:1)'
' at foo ('+path.join(process.cwd(),'.original.js')+':1:1)'
]);
});
@ -199,6 +200,6 @@ it('handleUncaughtExceptions is false', function(done) {
'function foo() { throw new Error("this is the error"); }',
' ^',
'Error: this is the error',
' at foo (./.original.js:1:1)'
' at foo ('+path.join(process.cwd(),'.original.js')+':1:1)'
]);
});