Skip to content

Commit

Permalink
Ongoing work with:
Browse files Browse the repository at this point in the history
* creating sourcemap from scratch (no input sourcemap)
* writing unit tests
  • Loading branch information
tsufiev committed Apr 16, 2018
1 parent 50e34e8 commit 9a9978b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 19 deletions.
12 changes: 7 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ module.exports = function(source, inputSourceMap) {
this.cacheable && this.cacheable();

const callback = this.async(),
sourceMapsEnabled = Boolean(this.options.devtool),
options = Object.assign({}, this.options.bemLoader, loaderUtils.getOptions(this)),
levelsMap = options.levels || bemConfig.levelMapSync(),
levels = Array.isArray(levelsMap) ? levelsMap : Object.keys(levelsMap),
Expand Down Expand Up @@ -50,7 +49,7 @@ module.exports = function(source, inputSourceMap) {
const parserOptions = {
ecmaVersion : 8,
sourceType : 'module',
locations : sourceMapsEnabled
locations : this.sourceMap
};
const result = falafel(source, parserOptions, node => {
// match `require('b:button')`
Expand Down Expand Up @@ -169,9 +168,12 @@ module.exports = function(source, inputSourceMap) {

Promise.all(allPromises)
.then(() => {
const updatedSourceMap = sourceMapsEnabled && inputSourceMap ?
updateSourceMapOffsets(inputSourceMap, modifiedNodes) : inputSourceMap;
callback(null, result.toString(), updatedSourceMap);
const sourceMap = this.sourceMap ?
updateSourceMapOffsets.call(this, source, inputSourceMap, modifiedNodes) : undefined;
//if(inputSourceMap.file === 'AttributesButton.js') {
// console.log('\n', source, '\n', result.toString(), '\n');
//}
callback(null, result.toString(), sourceMap);
})
.catch(callback);
};
66 changes: 52 additions & 14 deletions source-map-utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const SourceMapConsumer = require('source-map').SourceMapConsumer,
SourceMapGenerator = require('source-map').SourceMapGenerator;
SourceMapGenerator = require('source-map').SourceMapGenerator,
loaderUtils = require('loader-utils'),
path = require('path');

// NOTE: taken from source-map/util.js
/**
Expand Down Expand Up @@ -47,15 +49,29 @@ function relative(aRoot, aPath) {
* Take a raw source map from previous loader and apply adjustments related to the modifications
* made to `modifiedNodes`. Each node in `modifiedNodes` is expected to have 'loc' entry containing
* the original source's coordinates, while the transformed source is retrieved via node.source().
* @param {string} source
* @param {Object} inputSourceMap
* @param {Array} modifiedNodes
* @returns {Object}
*/
function updateSourceMapOffsets(inputSourceMap, modifiedNodes) {
const sourceMapConsumer = new SourceMapConsumer(inputSourceMap);
const sourceRoot = sourceMapConsumer.sourceRoot;
function updateSourceMapOffsets(source, inputSourceMap, modifiedNodes) {
const webpackRemainingChain = loaderUtils.getRemainingRequest(this).split('!');
const filename = webpackRemainingChain[webpackRemainingChain.length - 1];
let sourceMapConsumer, sourceRoot, sourceFile, sourcesContent;

if(inputSourceMap) {
sourceMapConsumer = new SourceMapConsumer(inputSourceMap);
sourceRoot = sourceMapConsumer.sourceRoot;
sourceFile = sourceMapConsumer.file;
sourcesContent = inputSourceMap.sourcesContent;
} else {
sourceFile = path.basename(filename);
sourceRoot = process.cwd();
sourcesContent = [source];
}

const sourceMapGenerator = new SourceMapGenerator({
file : sourceMapConsumer.file,
file : sourceFile,
sourceRoot : sourceRoot
});

Expand Down Expand Up @@ -100,23 +116,45 @@ function updateSourceMapOffsets(inputSourceMap, modifiedNodes) {
let lineOffset = 0;
let currentNode = modifiedNodes.shift();

sourceMapConsumer.eachMapping((inputMapping) => {
copyMapping(inputMapping, lineOffset);
if(currentNode && currentNode.loc.start.line === inputMapping.generatedLine) {
// When one-line require() is expanded into N require()-s, each new generated line
// should point to the original one-liner. We don't care about column transformations
// since there is one import/require per line.
if(sourceMapConsumer) {
sourceMapConsumer.eachMapping((inputMapping) => {
copyMapping(inputMapping, lineOffset);
if(currentNode && currentNode.loc.start.line === inputMapping.generatedLine) {
// When one-line require() is expanded into N require()-s, each new generated line
// should point to the original one-liner. We don't care about column transformations
// since there is one import/require per line.
let additionalLines = currentNode.source().split('\n').length - 1;
while(additionalLines > 0) {
lineOffset++;
copyMapping(inputMapping, lineOffset);
additionalLines--;
}
currentNode = modifiedNodes.shift();
}
});
} else {
while(currentNode) {
let additionalLines = currentNode.source().split('\n').length - 1;
while(additionalLines > 0) {
lineOffset++;
copyMapping(inputMapping, lineOffset);
sourceMapGenerator.addMapping({
original : {
line : currentNode.loc.start.line,
column : currentNode.loc.start.column
},
generated : {
line : currentNode.loc.start.line + lineOffset,
column : currentNode.loc.start.column
},
source : relative(sourceRoot, filename)
});
additionalLines--;
}
currentNode = modifiedNodes.shift();
}
});
}

return Object.assign({}, sourceMapGenerator.toJSON(), { sourcesContent : inputSourceMap.sourcesContent });
return Object.assign({}, sourceMapGenerator.toJSON(), { sourcesContent : sourcesContent });
}

module.exports = updateSourceMapOffsets;

0 comments on commit 9a9978b

Please sign in to comment.