PSA: Don't use cssnano from within postcss-loader

While redesigning this site, I ran into an odd problem: my build pipeline was generating CSS source maps but they were somehow getting messed up. Definitions were pointing to incorrect lines, and sometimes the wrong file altogether.

I employed the old developer standby of turning off all the possible causes one by one, and tracked the problem down to one line in my PostCSS config:

module.exports = {
  plugins: {
    'postcss-import': {},
    'postcss-preset-env': {},
    cssnano: {} // 👈 remove this line and source maps behave again
  }
}

At the time of writing the documentation for PostCSS1 and cssnano2 both seem to suggest the two should play nicely together. However, it turns out that according this Github issue the developers of cssnano actually don’t recommend loading cssnano with postcss-loader anymore:

Don’t use cssnano in postcss-loader […] using on postcss-loader makes impossible same optimization, also css-loader can rewrite some css stuff

The issue mentions a plugin called optimize-cssnano-plugin but that seems to be unmaintained - a much better alternative seems to be cssnano-webpack-plugin:

const CssnanoPlugin = require('cssnano-webpack-plugin')

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  },
  plugins: [
    new CssnanoPlugin({
      sourceMap: true
    })
  ]
}

Voilà - CSS compression without mangled source maps.


Footnotes

  1. Source: postcss-loader README (v3.0.0) ↩︎

  2. Source: Getting started guide - cssnano (v4.1.10) ↩︎


Loading comments...