diff --git a/lib/reporter.js b/lib/reporter.js index a674e1ed8..34a85879b 100644 --- a/lib/reporter.js +++ b/lib/reporter.js @@ -3,6 +3,7 @@ var log = require('./logger').create('reporter'); var MultiReporter = require('./reporters/multi'); var baseReporterDecoratorFactory = require('./reporters/base').decoratorFactory; var SourceMapConsumer = require('source-map').SourceMapConsumer; +var memoizeWeak = require('memoizee/weak'); var createErrorFormatter = function(basePath, emitter, SourceMapConsumer) { var lastServedFiles = []; @@ -30,6 +31,10 @@ var createErrorFormatter = function(basePath, emitter, SourceMapConsumer) { '(\\:(\\d+))?' + // column '', 'g'); + var getSourceMapConsumer = memoizeWeak(function(sourceMap) { + return new SourceMapConsumer(sourceMap); + }); + return function(msg, indentation) { // remove domain and timestamp from source files // and resolve base path / absolute path urls into absolute path @@ -45,9 +50,9 @@ var createErrorFormatter = function(basePath, emitter, SourceMapConsumer) { line = parseInt(line || '0', 10); column = parseInt(column || '0', 10); - var smc = new SourceMapConsumer(file.sourceMap); try { - var original = smc.originalPositionFor({line: line, column: column}); + var original = getSourceMapConsumer(file.sourceMap) + .originalPositionFor({line: line, column: column}); return util.format('%s:%d:%d <- %s:%d:%d', path, line, column, original.source, original.line, original.column); diff --git a/package.json b/package.json index 009bc9c6e..62b932f44 100644 --- a/package.json +++ b/package.json @@ -179,7 +179,8 @@ "useragent": "~2.0.4", "graceful-fs": "~2.0.1", "connect": "~2.26.0", - "source-map": "~0.1.31" + "source-map": "~0.1.31", + "memoizee": "~0.3.8" }, "devDependencies": { "LiveScript": "^1.3.0", diff --git a/test/unit/reporter.spec.coffee b/test/unit/reporter.spec.coffee index c4016cb47..02a9b3541 100644 --- a/test/unit/reporter.spec.coffee +++ b/test/unit/reporter.spec.coffee @@ -76,7 +76,7 @@ describe 'reporter', -> class MockSourceMapConsumer constructor: (sourceMap) -> - @source = sourceMap.replace 'SOURCE MAP ', '/original/' + @source = sourceMap.content.replace 'SOURCE MAP ', '/original/' originalPositionFor: (position) -> if position.line == 0 throw new TypeError('Line must be greater than or equal to 1, got 0') @@ -88,8 +88,8 @@ describe 'reporter', -> it 'should rewrite stack traces', (done) -> formatError = m.createErrorFormatter '/some/base', emitter, MockSourceMapConsumer servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] - servedFiles[0].sourceMap = 'SOURCE MAP a.js' - servedFiles[1].sourceMap = 'SOURCE MAP b.js' + servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} + servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit 'file_list_modified', q(served: servedFiles) @@ -118,7 +118,7 @@ describe 'reporter', -> beforeEach -> formatError = m.createErrorFormatter '/some/base', emitter, MockSourceMapConsumer servedFiles = [new File('C:/a/b/c.js')] - servedFiles[0].sourceMap = 'SOURCE MAP b.js' + servedFiles[0].sourceMap = {content: 'SOURCE MAP b.js'} it 'should correct rewrite stack traces without sha', (done) -> emitter.emit 'file_list_modified', q(served: servedFiles)