Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source map line numbers off by two with no plugins #926

Closed
alexturpin opened this issue Dec 2, 2016 · 23 comments
Closed

Source map line numbers off by two with no plugins #926

alexturpin opened this issue Dec 2, 2016 · 23 comments

Comments

@alexturpin
Copy link

Hey all,

I've encountered a bit of an issue with sourcemaps. My workflow is that I first compile my SASS code down to CSS, and then use PostCSS on the resulting code / source maps.

My problem is that even with no plugins, after going through PostCSS, source map line numbers are off by 2 (they point to 2 lines before the actual line).

This is the input CSS and input source map generated from SASS:

p{color:red}a{color:green}

/*# sourceMappingURL=before.css.map */
{
	"version": 3,
	"file": "styles.css",
	"sources": [
		"styles.scss"
	],
	"sourcesContent": [
		"p {\n\tcolor: red;\n}\n\na {\n\tcolor: green;\n}\n"
	],
	"mappings": "AAAA,AAAA,CAAC,AAAC,CACD,KAAK,CAAE,GAAI,CACX,AAED,AAAA,CAAC,AAAC,CACD,KAAK,CAAE,KAAM,CACb",
	"names": []
}

As can be seen on source-map-visualization everything is still linked properly.

Now running them through PostCSS without plugins with this code:

var postcss = require('postcss');
var fs = require('fs');
var path = require('path');

var beforeStyles = fs.readFileSync('before.css', 'utf-8');
var beforeMap = fs.readFileSync('before.css.map', 'utf-8');

postcss([])
	.process(beforeStyles, { from: 'before.css', to: 'after.css', map: { inline: false, prev: beforeMap } })
	.then(function(result) {
		fs.writeFileSync('after.css', result.css);
		fs.writeFileSync('after.css.map', result.map);
	}, function(err) {
		console.log(err);
	});

Results in the following output:

p{color:red}a{color:green}
/*# sourceMappingURL=after.css.map */
{"version":3,"sources":["styles.scss"],"names":[],"mappings":"AAAA,EACC,SAAW,CACX,EAGA,WAAa,CACb","file":"after.css","sourcesContent":["p {\n\tcolor: red;\n}\n\na {\n\tcolor: green;\n}\n"]}

Which, we can observe on source-map-visualization, is broken. The a selector has no corresponding line number.

@ai
Copy link
Member

ai commented Dec 2, 2016

Thanks for investigation. Yeap, a selector mapping is broken.

Right now I am preparing for conference and will be free after Dec 11. Could it wait until this date? Maybe I will have time on next week.

@alexturpin
Copy link
Author

@ai Yep that's fine, just wanted to make sure that it was logged somewhere.

@alexturpin
Copy link
Author

Hello!

Just wondering if there have been any updates on this? :)

@ai
Copy link
Member

ai commented Jan 4, 2017

Sorry, I am in other project. Because we had no other reports and problem is not critical this issue is low priority right now.

Do you want to try to fix it by your own? I will help you.

@alexturpin
Copy link
Author

No worries. It's not critical enough for me right now to focus time on fixing it, but if I ever come around to it I'll hit you up to ask for tips on where to look to fix it :)

Thanks

@GaryJones
Copy link

FWIW, I can see evidence of this too.

@ai
Copy link
Member

ai commented Feb 8, 2017

Be prepare that this issue will not be fixed for few months:

  1. I am preparing for React London with talk about Logux.
  2. Result is not critical.
  3. It doesn’t happen on pure PostCSS stack 😛

@ai
Copy link
Member

ai commented Feb 8, 2017

I am always open for PR ;)

@alexturpin
Copy link
Author

@ai What do you mean by pure PostCSS stack? Weback plugin?

@ai
Copy link
Member

ai commented Feb 8, 2017

I mean do all CSS work inside PostCSS: linting, preprocessing, prefixes, postprocessing

@alexturpin
Copy link
Author

alexturpin commented Feb 8, 2017

Ah so it's a result of incompatibility between other sourcemaps and PostCSS' sourcemaps then?

@ai
Copy link
Member

ai commented Feb 8, 2017

Yeap this issue happen when you have previous source map

@ai
Copy link
Member

ai commented Feb 8, 2017

Of course, it is a error and I will fix it. PostCSS should update others source map.

@alexturpin
Copy link
Author

No worries! Just trying to understand better :)

@subicura
Copy link

+1

@ai
Copy link
Member

ai commented Mar 16, 2017

@subicura I will look into it again after React London (March 28)

@subicura
Copy link

@ai Thanks!!

@ai
Copy link
Member

ai commented Apr 14, 2017

I tried few changes but had no success.

PostCSS source maps are good. Sass source maps are good. Problem comes from mozilla’s source-map, when it try to merge source maps.

Since Sass compatibility is not goal for PostCSS, I will close this issue (anyway I don’t know solution right now).

Possible solutions:

  • Short-term: use postcss-based preprocessors like PreCSS or cssnext. In this case you will get 100% compatibility with other postcss-based tools like Autoprefixer or Stylelint.
  • Long-term: when we move selector and value parser inside core, we will split CSS into smaller chunks. Source maps may be fixed by it. Integrate value & selector parsing into PostCSS core. #754

@x-yuri
Copy link

x-yuri commented Jan 26, 2018

@ai Could you please help me reproduce the issue without postcss?

1.scss:

body {
    background: #ddd;
}
div {
    width: 100px;
    height: 100px;
    margin: auto;
    background: #666;
}
$ yarn add node-sass postcss-cli
$ rm 1.css*; ./node_modules/.bin/node-sass --output-style compressed --source-map true --source-map-contents 1.scss 1.css
$ rm 2.css*; ./node_modules/.bin/postcss 1.css --output 2.css

node-sass produces the following mappings:

AAAA,AAAA,IAAI,AAAC,CACD,UAAU,CAAE,IAAI,CACnB,AACD,AAAA,GAAG,AAAC,CACA,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,IAAI,CACnB

But after postcss I get:

AAAA,KACI,eAAgB,CACnB,IAEG,YACA,aACA,YACA,eAAgB,CACnB

I want to file a bug to source-map package regarding the issue. Or at least try to figure out why the mappings change. So I'd like to have a test case with source-map package alone.

Well, my case might be a little off compared to this issue, but certainly related.

@ai
Copy link
Member

ai commented Jan 26, 2018

What is a problem with this mapping? PostCSS generates less nodes, so result mapping is smaller

@x-yuri
Copy link

x-yuri commented Jan 26, 2018

Let the author speak for himself:

Ruby sass sourcemaps are lacking a lot according to previous discussions with am11. I decided to do better than that and therefore libsass has much more detailed source-maps than ruby sass does (not sure if this is still true, since those discussion are over a year old).

Also, I'm curious what makes source-map package change source maps when no code changes.

P.S. I'm going to check if OP's issue still holds.

@x-yuri
Copy link

x-yuri commented Jan 26, 2018

...By the way, it might be the root cause of this issue.

@x-yuri
Copy link

x-yuri commented Jan 31, 2018

I now see. Regarding OP's test case. IMO nothing is broken in the "after" source map (as well as in the "before" one). source-map-vizualization doesn't have the last word in it. It's just another consumer. Which happens to be a visualization tool, and not the best one if you ask me. The whole issue with source maps comes from—correct me if I'm wrong—non-strict spec. source-map package doesn't do anything wrong, it just follows another interpretation of the spec. Not that I'm trying to put the blame on the spec, it probably has its reasons.

Then, these days the issue can't be reproduced (line numbers off by two). Or line numbers are simply off by one consistently across the whole stylesheet. At least in Chromium 63.0.3239.132. From what I can see, Chromium takes the first mapping after the opening curly bracket.

Regarding my test case, I was wondering why so much less mappings was left after postcss. So, postcss parses the css code, which results in AST with line/column numbers. No processing is done. Then source map is generated based on the AST. After which original source map is applied.

Now then, what does "apply" here mean again? We have source code (A), source code A after processing with sass (B), and source code B after processing with postcss (C, nothing has changed). And we have two source maps: B -> A, C -> B. When applying, source-map package takes a mapping from C -> B source map, its original position (B) and maps it using B -> A source map to original original position (A). That gives us as many mappings as was generated by postcss, but there could be less (when adjacent mappings point to the same position).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants