Search code examples
webpacksasspostcsssass-loaderpostcss-loader

How to use postcss-loader with sass-loader in webpack


I'm trying to build a webpack config that transpiles my sass and utilizes the postcss autoprefixer plugin.

Having researched and tried out various solutions to this, I have come up with the following setup:

webpack.config.js:

...
{
    test:  /\.(sa|sc|c)ss$/,
    exclude: [/node_modules/, /css/],
    use: [
        MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            options: {
                importLoaders: 1,
                url: false,
            }
        },
        {
            loader: 'postcss-loader',
            options: {
                config: {
                    path: 'postcss.config.js'
                }
            }
        },
        'sass-loader',
    ]
}
...

postcss.config.js:

module.exports = {
    plugins: [
        require('autoprefixer')({
            overrideBrowserslist: ['last 2 versions']
        })
    ]
}

When i run this, I receive the following error:

ERROR in ./themes/kredslob/scss/main.scss 1:0
Module parse failed: Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> @import "partials/mixins";
| @import "footer";
| @import "header";

This makes sense, as postcss is not configured with a plugin to properly handle imports. I then tried changing the order of postcss-loader and sass-loader, to have the sass loader handle imports and other non standard css features, before postcss loader handles vendor prefixes. So my setup was changed to:

...
'sass-loader',
{
    loader: 'postcss-loader',
    options: {
        config: {
            path: 'postcss.config.js'
        }
    }
},
...

But then I still receive the same error as described before.

How do I properly configure this setup?


Solution

  • I am not sure how much of what I say here is going to help you, as I have never used the postcss autoprefixer plugin. But here it goes:

    The module property from my webpack config usually looks like the following:

    module: {
            rules: [
                {
                    test: /\.s?css$/i,
                    use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader','sass-loader']
                },
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: "babel-loader"
                }
            ]
        },
    

    Then, I tend to have a separate postcss config file:

    module.exports = {
        plugins: ['postcss-preset-env']
    }
    

    And one .browserslistrc too:

    last 2 versions
    > 0.5%
    IE 10
    

    If I am not mistaken, postcss-loader looks for a config file by default. No need to add option with path pointing to it. Also, postcss preset env includes autoprefixer to some extent.

    Now, it's worth it to know that broswerslist introducudes a bug - it prevents auto reloading. In order to still take advantage of it, you can only set it up for when you build for production.