Skip to content

Source map content from previous processing step is ignored #134

Closed
@mems

Description

@mems

Bug report

When css-minimizer-webpack-plugin is used, source map content from previous step is ignore and completely replaced and not merge with the one that came from minification.

Actual Behavior

In debug mode, you can inspect the DOM elements in the browsers devtool and see the original source of applied rulesets.
In release mode, due css-minimizer-webpack-plugin apply minification, you only see the source before minification, not the original one.

Expected Behavior

When you inspect DOM elements in the browsers devtool you can see the original source of applied rulesets in any mode (release, debug, etc.)

How Do We Reproduce?

Compile styles with a preprocessor (sass, less, stylus, etc.) with sourcemap without css-minimizer-webpack-plugin (or disabled with debug mode), inspect the extracted source map with devtool or source-map-visualization.
Do it again but with css-minimizer-webpack-plugin, then it inspect again.

Reproducible test: webpack-source-map-merge-test

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: Windows 8.1 6.3.9600
    CPU: (4) x64 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
    Memory: 6.94 GB / 31.88 GB
  Binaries:
    Node: 14.17.4 - C:\Program Files\nodejs\node.EXE
    npm: 6.14.14 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 95.0.4638.69
    Internet Explorer: 11.0.9600.19036
  Packages:
    webpack: ^5.61.0 => 5.62.2
    webpack-cli: ^4.9.1 => 4.9.1

Possible solutions

Each minimizer has it's own option/solution:

It's also possible to not provide previous source map to the minimizer but instead manually merge source maps:

const { SourceMapGenerator } = require('source-map/lib/source-map-generator.js');
const { SourceMapConsumer } = require('source-map/lib/source-map-consumer.js');

const mergedSourceMap = await SourceMapConsumer.with(resultSourceMap, null, async (resultConsumer) =>
  SourceMapConsumer.with(inputSourceMap, null, inputConsumer => {
    const generator = SourceMapGenerator.fromSourceMap(resultConsumer);
    generator.applySourceMap(inputConsumer, filename);
    return generator.toJSON();
  }));

Example of implementation with cssnano:

diff --git a/src/utils.jst b/src/utils.js
index 08829e0..19b90f3 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -116,7 +116,10 @@ async function cssnanoMinify(
   }

   if (inputSourceMap) {
-    postcssOptions.map = { annotation: false };
+    postcssOptions.map = {
+      annotation: false,
+      prev: inputSourceMap,
+    };
   }

   // eslint-disable-next-line global-require

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions