Skip to content

Commit

Permalink
fix: source maps generation (#886)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Sep 3, 2020
1 parent 53592da commit 8327d55
Show file tree
Hide file tree
Showing 4 changed files with 596 additions and 74 deletions.
27 changes: 6 additions & 21 deletions src/index.js
Expand Up @@ -9,7 +9,7 @@ import {
getSassOptions,
getWebpackImporter,
getRenderFunctionFromSassImplementation,
absolutifySourceMapSource,
normalizeSourceMap,
} from './utils';
import SassError from './SassError';

Expand Down Expand Up @@ -66,33 +66,18 @@ function loader(content) {
return;
}

let map = result.map ? JSON.parse(result.map) : null;

// Modify source paths only for webpack, otherwise we do nothing
if (result.map && useSourceMap) {
// eslint-disable-next-line no-param-reassign
result.map = JSON.parse(result.map);

// result.map.file is an optional property that provides the output filename.
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
// eslint-disable-next-line no-param-reassign
delete result.map.file;

// eslint-disable-next-line no-param-reassign
result.sourceRoot = '';

// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
// This fixes an error on windows where the source-map module cannot resolve the source maps.
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
// eslint-disable-next-line no-param-reassign
result.map.sources = result.map.sources.map((source) =>
absolutifySourceMapSource(this.rootContext, source)
);
if (map && useSourceMap) {
map = normalizeSourceMap(map, this.rootContext);
}

result.stats.includedFiles.forEach((includedFile) => {
this.addDependency(path.normalize(includedFile));
});

callback(null, result.css.toString(), result.map);
callback(null, result.css.toString(), map);
});
}

Expand Down
35 changes: 26 additions & 9 deletions src/utils.js
Expand Up @@ -159,7 +159,6 @@ function getSassOptions(
// Pretty complicated... :(
options.sourceMap = true;
options.outFile = path.join(loaderContext.rootContext, 'style.css.map');
// options.sourceMapRoot = process.cwd();
options.sourceMapContents = true;
options.omitSourceMapUrl = true;
options.sourceMapEmbed = false;
Expand Down Expand Up @@ -507,15 +506,33 @@ function getURLType(source) {
return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative';
}

function absolutifySourceMapSource(sourceRoot, source) {
const sourceType = getURLType(source);
function normalizeSourceMap(map, rootContext) {
const newMap = map;

// Do no touch `scheme-relative`, `path-absolute` and `absolute` types
if (sourceType === 'path-relative') {
return path.resolve(sourceRoot, path.normalize(source));
}
// result.map.file is an optional property that provides the output filename.
// Since we don't know the final filename in the webpack build chain yet, it makes no sense to have it.
// eslint-disable-next-line no-param-reassign
delete newMap.file;

// eslint-disable-next-line no-param-reassign
newMap.sourceRoot = '';

// node-sass returns POSIX paths, that's why we need to transform them back to native paths.
// This fixes an error on windows where the source-map module cannot resolve the source maps.
// @see https://github.com/webpack-contrib/sass-loader/issues/366#issuecomment-279460722
// eslint-disable-next-line no-param-reassign
newMap.sources = newMap.sources.map((source) => {
const sourceType = getURLType(source);

// Do no touch `scheme-relative`, `path-absolute` and `absolute` types
if (sourceType === 'path-relative') {
return path.resolve(rootContext, path.normalize(source));
}

return source;
});

return source;
return newMap;
}

export {
Expand All @@ -524,5 +541,5 @@ export {
getWebpackResolver,
getWebpackImporter,
getRenderFunctionFromSassImplementation,
absolutifySourceMapSource,
normalizeSourceMap,
};

0 comments on commit 8327d55

Please sign in to comment.