Skip to content

Instantly share code, notes, and snippets.

@JohnLouderback
Created March 3, 2023 23:37
Show Gist options
  • Save JohnLouderback/b06db42bfa418e13b51d56ebef662dd0 to your computer and use it in GitHub Desktop.
Save JohnLouderback/b06db42bfa418e13b51d56ebef662dd0 to your computer and use it in GitHub Desktop.
An example of editing source maps through a Webpack loader.
sourceMap.sources.forEach((sourceFile, i) => {
// Get the source code for the current source file.
const source = sourceMap.sourcesContent[i];
// Keep track of the number of blank lines that have been encountered.
let currentBlankLineCount = 0;
// Split the source into lines so we can adjust the line numbers. For each line, we'll
// need count the number of "blank" lines that preceded it.
const sourceFileLineDetails = source.split('\n').map((line) => {
// Generate an object to store the line information.
const lineInfo = {
numberOfPrecedingBlankLines: currentBlankLineCount,
lineText: line
};
// If the line is blank, increment the blank line count.
if (line.trim().length === 0) {
currentBlankLineCount += 1;
}
return lineInfo;
});
// Iterate over each mapping in the source map, so we can adjust the line numbers. The
// line numbers require adjustment because the source map is generated from the SWC and
// in Next 12, the SWC is configured to remove blank lines. This means that the line
// numbers in the source map are off by the number of blank lines that were removed.
parsedSourceMap.eachMapping((mapping) => {
const newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
},
original:
mapping.originalLine === null
? null
: {
line:
// Adjust the line number by the number of blank lines that preceded it.
mapping.originalLine -
sourceFileLineDetails[mapping.originalLine - 1]
.numberOfPrecedingBlankLines,
column: mapping.originalColumn
},
source: mapping.originalLine === null ? null : mapping.source
};
// Add the modified mapping to the new source map generator
newSourceMap.addMapping(newMapping);
});
});
// Convert the new source map generator to a string and set it as the mappings for the
// original source map.
const newSourceMapRaw = JSON.stringify(newSourceMap.toString());
sourceMap.mappings = newSourceMapRaw.mappings;
return sourceMap;
};
/**
* The actual Webpack loader function.
* @type import('webpack').LoaderDefinition
*/
const loader = function (source, map, meta) {
this.callback(null, source, adjustSourceMaps(map), meta);
};
module.exports = loader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment