JJ Gerrish
JJ Gerrish

Reputation: 882

Autoprefixer is causing node-sass source map to point to the wrong files

I built a custom Node script that does all of my SCSS processing manually in JS rather than through the command line or with webpack.

The process is as follows:

  1. Watch .scss files for changes.
  2. On change, compile the SCSS to CSS with node-sass and generate a source map with node-sass at the same time.
  3. Write the screen.css and screen.css.map file using `fs.writeFile()
  4. For the screen.css file, I then re-read it with fs.readFile to get the buffer, and run the CSS contents through postcss using the autoprefixer plugin to autoprefix all of the CSS. I then re-write this using fs.writeFile again and finally upload it to the server using jsftp. At the same time, the process for the screen.css.map file is the exact same, except that I don't run it through postcss, I just re-read it and upload it to the server after the initial writing.

My problem

If I include the autoprefixer plugin when using postcss, e.g:

postcss([autoprefixer]).process(buffer, {
    from: "assets/css/screen.css",
    to: "assets/css/screen.css"
}).then(result => {...})

the sourcemap is completely wrong when inspecting in the browser and points to not only the wrong lines but also the wrong files.

For example, the SCSS for the page banner is in _banner.scss, but the sourcemap tells me it is all in _calendar.scss.

However if I keep all of the code the exact same but leave out autoprefixer, e.g:

postcss([]).process(buffer, {
    from: "assets/css/screen.css",
    to: "assets/css/screen.css"
}).then(result => {...})

The sourcemap works perfectly, pointing me correctly to _banner.scss for all the banner styles.

Has anyone got any idea how I can fix this and get my SCSS sourcemaps working whilst still using autoprefixer?

Link to full sourcecode for the SCSS processing node script here, ignore the horrible nesting, this is just an early version :) https://github.com/JJGerrish/twk-boilerplate/blob/master/template/style.js

Upvotes: 1

Views: 1322

Answers (1)

JJ Gerrish
JJ Gerrish

Reputation: 882

For anyone who needs it I found a fix.

Basically, postcss has an option to detect a previous source map and use it for it's own source map instead of generating a new one.

I found this solution on a GitHub issue that did the trick for me, basically, you have to get the node-sass generated source map, stringify it, and then pass it to the postcss map option object.

https://github.com/postcss/postcss/issues/222#issuecomment-318136962

Code below incase link disappears:

postcss([autoprefixer])
    .process(result.css, {
        from: "assets/css/screen.css",
        to: "assets/css/screen.css",
        map: {
            prev: result.map.toString(),
            inline: false,
        },
    })
    .then(result => {...})

Upvotes: 2

Related Questions