Running PostCSS on webpack output

Tomasz Sodzawiczny
2 min readJan 6, 2019

--

Image source: https://postcss.org/

PostCSS is a great way to enhance your CSS. The standard way of running it when using webpack is using the postcss-loader. It’s OK in most cases, but has one flaw — postcss is run on every input CSS file separately, rather than once on the output CSS file.

So can you run postcss on output rather than input? The answer is yes — and actually there is a big chance you are already doing it without knowing.

Using Optimize CSSAssetsWebpackPlugin

The common way of minifying your CSS is the optimize-css-assets-webpack-plugin. It works by applying configured processor on the output CSS files. By default it uses cssnano, which in turn is built on top of PostCSS.

The config of OptimizeCSSAssetsPlugin lets you replace cssnano with any other processor that has a compatible API. We can leverage that to plug postcss in there with any plugins we want. No adapter required, as — again — cssnano is actually a PostCSS plugin.

PostCSSAssetsPlugin

The above solution works perfectly fine, but using OptimizeCSSAssetsPlugin for something else than optimisation feels a bit hacky (even if it’s just because of the naming). Luckily for us there is a webpack plugin meant for processing any CSS with PostCSS: PostCSSAssetsPlugin.

Our final webpack config gets even slightly simpler:

This way you can run any selection of PostCSS plugins on the final output bundle instead of on per-file basis. 🎉

Just remember, you have to include cssnano (or another minifier) manually or your output bundle will not be minified.

But… why?

There are 2 primary reasons why just using postcss-loader can be insufficient in some cases:

  • Some plugins might be more effective this way: the best example is cssnano itself — it can perform better when run on the whole output bundle rather than on files separately
  • CSS Modules. If you’re using css-loader to handle the modules, the variables imported with @value x from 'some-file'; syntax are not resolved yet at webpack loader level, so you may run into trouble when using them with other plugins.

--

--

Tomasz Sodzawiczny

Software engineer (mostly front-end). Passionate about building long-lasting solutions. In love with React.