postcss-clean icon indicating copy to clipboard operation
postcss-clean copied to clipboard

Source mapping is lost

Open vphantom opened this issue 8 years ago • 4 comments

Hello,

Right now, I'm running postcss first, then clean-css-cli on its result, and using a map file which inlines sources, I manage to trace which files/lines each rule comes from in Chrome dev tools.

For sake of cleanliness though, I tried postcss-clean to see if I could make these 2 steps into a single one. Unfortunately I can't, which I thought you might like to know. Here's what my postcss.config.js looks like at the moment:

module.exports = {
  map: {
    inline: false,
    sourcesContent: true
  },
  plugins: [
    require('postcss-import')({
      path: [
        './css/',
        './fontello/css/'
      ]
    }),
    require('postcss-assets')({}),
    require('autoprefixer')({}),
    require('postcss-image-inliner')({}),
    require('postcss-clean')({
      rebase: false,
      sourceMapInlineSources: true,
      processImport: false
    })
  ]
};

This is the best I can do: the map file contains the CSS it refers to, but it always contains exactly one single source called <input css 1>. No original file names. Disabling postcss-clean restores proper behavior, so it is really at this stage that references to original files are lost.

So for now I'm back to using the two steps, but it'd be neat if we could eventually figure out why this plugin mangles source references.

vphantom avatar Mar 24 '17 16:03 vphantom

I'm investigating.

Some points.

The main source of the issue is the missing from options (doc) in the postcss.parse() call (doc).

Then we have to ask ourselfs whether the sourcemap generation is responsibility of the postcss engine or we can delegate it to the clean-css optimizer.

Both are able to generate source maps but the two scenarios are pretty divergent.

In the first case (postcss responsibility), at the moment I came to the following observations:

the clean-css tool should be passive, we have to give him each source separately, so it can minify their css strings one at time, it shouldn't inline @import statements itself, and return the minified styles so to leave to the postcss engine the responsibility to join the various roots. It will then generate automatically the sourcemap.

I have still to think about the 2nd scenario.

Anyway, since the time is spare, discussions, ideas, help, or PRs are welcome! Thanks.

leodido avatar Sep 25 '17 11:09 leodido

Because in theory clean-css could be inserted anywhere in the chain and not necessarily last, it'd make sense if postcss remained responsible for generating source maps. Parsing files individually and ignoring imports sounds prudent to me. (I handle imports earlier in the plugin chain anyway.)

However, clean-css would lose part of its appeal: it's great for merging and eliminating redundancies across rules and presumably across files, an ability which would be crippled if handling files separately. Delegating source map generation to it would create a big exception to how postcss is structured, but would solve that. Perhaps if that special delegation had to be explicit in one's postcss.config.js, it could be an acceptable way to go…

vphantom avatar Sep 25 '17 12:09 vphantom

I have hit this problem too, however, I don't understand why it touches the sourcesContent at all, this need to remain to match the original source files.

Example file:

html, body {
	height: 100%;
	width: 100%;
}

/*.row {
	display:flex;
	flex-direction: row;
}
.column {
	display: flex;
	flex-direction: column;
}*/
.sticky {
	position: sticky;
}

Source Map with postcss-clean in the chain:

{
  "version": 3,
  "sources": [
    "<input css 1>"
  ],
  "names": [],
  "mappings": "AAAA,UAAU,YAAY,UAAU,CAAC,QAAQ,eAAe,CAAC",
  "file": "cache/modd/style/test.scss-out.css",
  "sourcesContent": [
    "body,html{height:100%;width:100%}.sticky{position:sticky}"
  ]
}

and without it

{
  "version": 3,
  "sources": [
    "cache/modd/style/test.scss"
  ],
  "names": [],
  "mappings": "AAAA;EACC,aAAY;EACZ,YAAW,EACX;;AAED;;;;;;;GAOG;AACH;EACC,iBAAgB,EAChB",
  "file": "cache/modd/style/test.scss-out.css",
  "sourcesContent": [
    "html, body {\r\n\theight: 100%;\r\n\twidth: 100%;\r\n}\r\n\r\n/*.row {\r\n\tdisplay:flex;\r\n\tflex-direction: row;\r\n}\r\n.column {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}*/\r\n.sticky {\r\n\tposition: sticky;\r\n}\r\n"
  ]
}

It appears that clean css is not just cleaning the output, but also manipulating the source map in such a way, that makes it unreadable. I have tried adjusting sourceMap settings, with no success.

cseufert avatar Oct 10 '17 05:10 cseufert

Used with gulp-postscss The same issue <input css 2> Config

{
  rebase: false,
  format: {
    breaks: {
      afterRuleEnds: true
    }
  }
}

maxval1 avatar Oct 17 '18 06:10 maxval1