postcss is injecting generated .css file into source list #907

Open
airdrummingfool opened this Issue Oct 27, 2016 · 18 comments

Projects

None yet

3 participants

@airdrummingfool

Using gulp and gulp-usemin, I compile a set of LESS files into one generated main.css file. When including postcss (without any plugins) in the pipeline, the sourcemaps include this generated main.css file in the sources list.

Simplified version of main.css.map file without postcss:

{
"version":3,
"sources":["app/styles/less/common.less","app/styles/less/custom.less","app/styles/less/login.less","app/styles/less/admin.less"],
"names":[],
"mappings":"...",
"file":"main.css",
"sourcesContent":["..."]
}

Simplified version of main.css.map with postcss (without any plugins):

{
"version":3,
"sources":["app/styles/less/common.less","styles/main.css","app/styles/less/custom.less","app/styles/less/login.less","app/styles/less/admin.less"],
"names":[],
"mappings":"...",
"file":"main.css",
"sourcesContent":["..."]
}

How can I prevent postcss from adding "styles/main.css" to the sourcemap sources? I've tried various permutations of the from, to, and map options listed on the postcss and sourcemaps page, but I can't figure it out.

@ai
Member
ai commented Oct 28, 2016

I think problem is that not all symbols has mappings in Less source map (for example, whitespaces). So when PostCSS create mappings for all symbols, some of them connect with Less’s mapping, but some have no connections.

Honestly, I don’t know best solution right here. And do we really need to spend time to fix it? ;)

If you really want to fix it, you can use source-map-visualization to see differences between PostCSS and Less mappings. If this mappings was really strange feel free to open new issue or send a PR.

@ai ai closed this Oct 28, 2016
@erquhart
erquhart commented Nov 4, 2016 edited

@ai

And do we really need to spend time to fix it? ;)

I think so.

The resulting sourcemap causes the browser to look for a file that doesn't exist, and bad data is a problem when anyone wants to use the postcss api for anything serious, such as a tool that provides a wrapper.

In my case, I'm copying the sources files to dest, and have no reliable way to determine which entry in the sources array is the bogus one. PostCSS reliably adds it and shouldn't.

Does this at least merit remaining open? I'm currently blocked by this and am unsure how to proceed. Maybe if it's open someone will eventually have time to look into it.

@ai
Member
ai commented Nov 5, 2016

@erquhart I think you should not always be sure in sources. What if some other tool will miss mapping for some a{}? In this case PostCSS anyway will use .css file mapping.

Sometimes PostCSS plugins developers write bad code and miss Node#input. In this case PostCSS set <no source> source (it helps to find this mistakes).

So you should write:

if (fs.exists(source)) {
  doMagic(source)
}
@ai
Member
ai commented Nov 5, 2016

Of course, if you have time for investigation I will accept PR.

As I told you should start from source-map-visualization to see differences between PostCSS and Less mappings. Maybe you will find, that Less miss mappings for some symbols or whitespaces. Or maybe it could be a small PostCSS mistake.

@erquhart
erquhart commented Nov 5, 2016

@ai right, but what if a source's path is bad for some other reason? I'd like to warn the user and maybe even error out. But due to this issue, my only route currently is to silently fail as you're suggesting. I'm not able to improve the user experience by providing useful warnings that may be meaningful.

@ai
Member
ai commented Nov 5, 2016

@erquhart it is good that you try to provide a better UI for users :).

OK, show me a that strange mappings (you can see it by source-map-visualization). Then I will tell you how we can fix it.

@ai
Member
ai commented Nov 5, 2016

Strange. I didn’t see a .css mapping there O_o. Maybe we don’t clean sources?

Could you show result.map._mappings? (set map: { inline: false } to get result.map)

@erquhart
erquhart commented Nov 5, 2016

That is the map from result. I don't use inline maps.

@ai
Member
ai commented Nov 5, 2016

@erquhart sure, just show me a ._mappings inside this result.map.

@erquhart
erquhart commented Nov 5, 2016

Ah, didn't even realize the map itself isn't provided in the visualization. Below is the entire map produced by postCSS, prettified. Let me know if you need the input map as well.

{
  "version": 3,
  "sources": [
    "src/test/imports/import.less",
    "less.less",
    "src/import.less",
    "src/test/less.less"
  ],
  "names": [],
  "mappings": "AAAA,KACE,eAAA,CCCD,ACFD,KACE,WAAA,ACMA,UAAA,CFFD",
  "file": "less.less"
}
@ai
Member
ai commented Nov 5, 2016

I need a PostCSS map mappings. Not a PostCSS map JSON, but result.map._mappings.

result is that thing from postcss(plugins).process(css) //=> result (when you use low-level JS API). _mappings is a private method from sourceMap.SourceMapGenerator, which show decrypted mapping.

(Or just create a simple test project, I could look at it on next weekend.)

@erquhart
erquhart commented Nov 5, 2016

Gotcha:

MappingList {
  _array:
   [ { generatedLine: 1,
       generatedColumn: 0,
       originalLine: 1,
       originalColumn: 0,
       source: 'src/test/imports/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 5,
       originalLine: 2,
       originalColumn: 2,
       source: 'src/test/imports/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 20,
       originalLine: 2,
       originalColumn: 2,
       source: 'src/test/imports/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 21,
       originalLine: 3,
       originalColumn: 1,
       source: 'less.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 21,
       originalLine: 1,
       originalColumn: 0,
       source: 'src/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 26,
       originalLine: 2,
       originalColumn: 2,
       source: 'src/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 37,
       originalLine: 2,
       originalColumn: 2,
       source: 'src/import.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 37,
       originalLine: 8,
       originalColumn: 2,
       source: 'src/test/less.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 47,
       originalLine: 8,
       originalColumn: 2,
       source: 'src/test/less.less',
       name: null },
     { generatedLine: 1,
       generatedColumn: 48,
       originalLine: 6,
       originalColumn: 1,
       source: 'less.less',
       name: null } ],
  _sorted: true,
  _last:
   { generatedLine: 1,
     generatedColumn: 48,
     originalLine: 6,
     originalColumn: 1,
     source: 'less.less',
     name: null } }
@ai
Member
ai commented Nov 5, 2016

Sure, seems like we have a PostCSS issue here. sources are not cleaned.

@ai ai reopened this Nov 5, 2016
@erquhart
erquhart commented Nov 5, 2016

Cool. Looks like PostCSS is mapping the closing brackets?

@ai
Member
ai commented Nov 5, 2016

I need to go to bed right now. Could you create a small test project?

@erquhart
erquhart commented Nov 5, 2016

I'll get one together soon. Thanks for your help, have a great night.

@airdrummingfool

Here's a simple example project: https://github.com/airdrummingfool/postcss-issue-907

If you remove the empty postcss task (postcss([])) from the usemin less build pipeline, styles/main.css does not show up in the sources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment