Rich-Harris / sorcery

Resolve a chain of sourcemaps back to the original source, like magic

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Source maps do not preserve history

eventualbuddha opened this issue · comments

I have been trying to use sorcery to combine source maps for transformation steps in decaffeinate and ran into what I believe to be a bug in sorcery. I still have a somewhat weak understanding of source maps so I may simply be wrong, but I thought I'd ask.

Here's a file that, when saved as bug.js and run with node bug.js after npm install sorcery to install sorcery, will illustrate the issue:

var sorcery = require('sorcery');

// output from babel
var firstMap = {
  "version":3,
  "sources":["index.js"],
  "names":[],
  "mappings":"AAAA,IAAI,IAAI,CAAJ;;AAEJ,SAAS,CAAT",
  "file":"index.babel.js",
  "sourcesContent":["let a = 1\n\nexport { a };\n"]
};

// This is the result of `magicString.insert(0, '// FOO!\n')`.
var secondMap = {
  version: 3,
  file: null,
  sources: [ 'index.babel.js' ],
  sourcesContent: [ 'var a = 1;\n\nexport { a };\n\n//# sourceMappingURL=index.babel.js.map' ],
  names: [],
  mappings: ';AAAA;;;'
};

var chain = sorcery.loadSync('index.babel.comment.js', {
  content: {
    'index.js':  'let a = 1\n\nexport { a };\n',
    'index.babel.js': 'var a = 1;\n\nexport { a };\n\n//# sourceMappingURL=index.babel.js.map',
    'index.babel.comment.js': '// FOO!\nvar a = 1;\n\nexport { a };\n\n//# sourceMappingURL=index.babel.js.map'
  },
  sourcemaps: {
    'index.babel.js': firstMap,
    'index.babel.comment.js': secondMap
  }
});
console.log(chain.apply());
/*
 Outputs:
  { version: 3,
    file: 'index.babel.comment.js',
    sources: [ 'index.js' ],
    sourcesContent: [ 'let a = 1\n\nexport { a };\n' ],
    names: [],
    mappings: ';AAAA;;;' }
*/

So we can see that the output map has lost all the mappings from the babel map and instead simply uses the mappings from the second map as-is. I would expect that the output should be essentially the same as the babel mappings but shifted by one line, so essentially ;AAAA,IAAI,IAAI,CAAJ;;AAEJ,SAAS,CAAT.

This is a HUGE bug. Thanks for pointing it out. I'll be giving it a shot in my own fork.

edit: Actually, I bet @Rich-Harris is aware of this, but I think sorcery ought to support it. :)

The applySourceMap method in Mozilla's source-map library has the same problem.

I've got a solution on the way. Writing some tests, currently. 🙂

Any news on this one?