diff --git a/lib/loader.js b/lib/loader.js index b64a7709..19313ffc 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -11,8 +11,6 @@ const { getOptions, isUrlRequest, urlToRequest, - getRemainingRequest, - getCurrentRequest, stringifyRequest, } = require('loader-utils'); @@ -40,7 +38,6 @@ module.exports = function loader(content, map) { if (map.sources) { map.sources = map.sources.map((source) => source.replace(/\\/g, '/')); - map.sourceRoot = ''; } } } else { @@ -100,15 +97,30 @@ module.exports = function loader(content, map) { plugins.push(icssParser(parserOptions)); + /** + * > To ensure that PostCSS generates source maps and displays better syntax + * > errors, runners must specify the from and to options. If your runner + * > does not handle writing to disk (for example, a gulp transform), you + * > should set both options to point to the same file + * @see postcss [PostCSS Runner Guidelines]{@link https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#21-set-from-and-to-processing-options} + * + * `css-loader` isn't responsible for writing the map, so it doesn't have to + * worry about updating the map with a transformation that changes locations + * (suchs as map.file or map.sources). + * + * Changing the file extension counts as changing the location because it + * changes the path. + * + * PostCSS's `from` and `to` arguments are only concerned with the file + * system. They don't know about, care about, or understand the webpack + * loader's current request or remaining request. + */ + const { resourcePath } = this; + postcss(plugins) .process(content, { - // we need a prefix to avoid path rewriting of PostCSS - from: `/css-loader!${getRemainingRequest(this) - .split('!') - .pop()}`, - to: getCurrentRequest(this) - .split('!') - .pop(), + from: resourcePath, + to: resourcePath, map: options.sourceMap ? { prev: map, @@ -241,31 +253,7 @@ module.exports = function loader(content, map) { if (exportCode) { exportCode = `exports.locals = ${exportCode};`; } - - let newMap = result.map; - - if (sourceMap && newMap) { - // Add a SourceMap - newMap = newMap.toJSON(); - - if (newMap.sources) { - newMap.sources = newMap.sources.map( - (source) => - source - .split('!') - .pop() - .replace(/\\/g, '/'), - this - ); - newMap.sourceRoot = ''; - } - - newMap.file = newMap.file - .split('!') - .pop() - .replace(/\\/g, '/'); - newMap = JSON.stringify(newMap); - } + const newMap = result.map; const runtimeCode = `exports = module.exports = require(${stringifyRequest( this, diff --git a/test/__snapshots__/sourceMap-option.test.js.snap b/test/__snapshots__/sourceMap-option.test.js.snap index bac0b795..e2904345 100644 --- a/test/__snapshots__/sourceMap-option.test.js.snap +++ b/test/__snapshots__/sourceMap-option.test.js.snap @@ -100,7 +100,6 @@ Array [ "file": "basic.css", "mappings": "AAAA;EACE,WAAW;CACZ", "names": Array [], - "sourceRoot": "", "sources": Array [ "/replaced/original/path/", ], @@ -133,7 +132,6 @@ Array [ "file": "basic.css", "mappings": "AAAA;EACE,WAAW;CACZ", "names": Array [], - "sourceRoot": "", "sources": Array [ "/replaced/original/path/", ], @@ -166,7 +164,6 @@ Array [ "file": "basic.css", "mappings": "AAAA;ECCE,WAAW;CACZ", "names": Array [], - "sourceRoot": "", "sources": Array [ "/replaced/original/path/", "/replaced/original/path/", @@ -201,7 +198,6 @@ Array [ "file": "basic.css", "mappings": "AAAA;ECCE,WAAW;CACZ", "names": Array [], - "sourceRoot": "", "sources": Array [ "/replaced/original/path/", "/replaced/original/path/", @@ -236,7 +232,6 @@ Array [ "file": "basic.css", "mappings": "AAAA;EACE,WAAW;CACZ", "names": Array [], - "sourceRoot": "", "sources": Array [ "/replaced/original/path/", ], diff --git a/test/helpers.js b/test/helpers.js index 8bfaf3d7..b01de145 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -154,7 +154,9 @@ function compile(fixture, config = {}, options = {}) { // eslint-disable-next-line no-param-reassign config = { mode: 'development', - devtool: config.devtool || 'sourcemap', + + // Account for valid `false` values for devtool + devtool: config.devtool != null ? config.devtool : 'source-map', context: path.resolve(__dirname, 'fixtures'), entry: path.resolve(__dirname, 'fixtures', fixture), output: outputConfig(config),