diff --git a/lib/index.js b/lib/index.js index 0f64271..8ca6031 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,12 +3,18 @@ const estraverse = require('estraverse') const genCode = require('escodegen') const genId = require('./gen-id') -module.exports = function(contents) { +const sourceMap = require('source-map') +const SourceMapConsumer = sourceMap.SourceMapConsumer +const SourceMapGenerator = sourceMap.SourceMapGenerator + +module.exports = function(contents, sourcemap) { const id = genId(this.resourcePath) let hasComponent = false const ast = acorn.parse(contents, { - sourceType: 'module' + sourceType: 'module', + locations: true, + sourceFile: this.resourcePath }) const res = estraverse.replace(ast, { @@ -39,8 +45,30 @@ module.exports = function(contents) { } }) - return genCode.generate(res) - + (hasComponent ? genHotReload(id) : '') + if (hasComponent) { + if (sourcemap) { + const generatedContents = genCode.generate(res, { + sourceMap: this.resourcePath, + sourceMapWithCode: true, + sourceContent: contents + }) + + // apply the original sourcemap to the sourcemap generated by escodegen. + const sourceMapGenerator = generatedContents.map + + const originalSmc = new SourceMapConsumer(sourcemap) + sourceMapGenerator.applySourceMap(originalSmc) + const outSourcemap = sourceMapGenerator.toJSON() + + this.callback(null, generatedContents.code + genHotReload(id), outSourcemap) + } else { + const generatedContents = genCode.generate(res) + + this.callback(null, generatedContents + genHotReload(id)) + } + } else { + this.callback(null, contents, sourcemap) + } } function genHotReload (id) { diff --git a/test/specs/index.spec.js b/test/specs/index.spec.js index 9f82a97..71e0e17 100644 --- a/test/specs/index.spec.js +++ b/test/specs/index.spec.js @@ -1,13 +1,18 @@ const path = require('path') const fs = require('fs') -const loader = require('../../lib/index') +const DefaultLoader = require('../../lib/index') + +class Loader extends DefaultLoader { + callback(err, contents, sourcemap) { this.callbackAnswer = { err, contents, sourcemap } } +} function test (name) { const src = fs.readFileSync(path.resolve(__dirname, '../fixtures', name), 'utf8') const expected = fs.readFileSync(path.resolve(__dirname, '../expects', name), 'utf8') it(name, () => { - expect(loader(src).replace(/if \(module\.hot\)[\s\S]*$/, '').trim()).toBe(expected.trim()) + const loader = new Loader(src) + expect(loader.callbackAnswer.contents.replace(/if \(module\.hot\)[\s\S]*$/, '').trim()).toBe(expected.trim()) }) }