Pranesh Ravi
Pranesh Ravi

Reputation: 19113

Using autoprefixer with postcss in webpack 2.x

How to use autoprefixer with webpack 2.x.

Previously, it used to be something like this...

...

module: {
  loaders: [
     {
       test: /\.scss$/,
        loader: 'style!css!sass!postcss'
     }
   ]
},
postcss: () => {
  return [autoprefixer]
},

...

But, it's not working anymore.

How to rewrite it to [email protected]?

Upvotes: 23

Views: 18445

Answers (4)

clhenrick
clhenrick

Reputation: 1137

As of July 20, 2017 to set up Autoprefixer with Webpack v2.4.1 I did the following:

Install necessary loaders:

yarn add -D postcss-loader autoprefixer style-loader sass-loader css-loader

create a postcss.config.js file in the root directory of your project:

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
};

In your root level package.json specify browsers you want to support:

"browserslist": ["defaults", "not ie < 11"]

In your webpack.config.js file's module.rules specify your loaders with the postcss-loader following the css-loader (I'm also using scss):

  {
    test: /\.scss$/,
    use: [
      {
        loader: 'style-loader' // Adds CSS to the DOM by injecting a <style> tag
      },
      {
        loader: 'css-loader' //  interprets @import and url() like import/require() and will resolve them.
      },
      {
        loader: 'postcss-loader', // postcss loader so we can use autoprefixer
        options: {
          config: {
            path: 'postcss.config.js'
          }
        }
      },
      {
        loader: 'sass-loader' // compiles Sass to CSS
      }
    ],
  },

Upvotes: 18

kreig
kreig

Reputation: 990

There is no more need to use LoaderOptionsPlugin. Now you can pass options directly to the loader declaration.

const autoprefixer = require('autoprefixer');

let settings = {
    /*...*/
    module: {
        rules: [{
            test: /\.css$/,
            use: [
                /*...other loaders...*/
                {
                    loader: 'postcss-loader',
                    options: {
                        plugins: function () {
                            return [autoprefixer]
                        }
                    }
                }
                /*...other loaders...*/
            ]
        }]}         
    }
    /*...*/
};

In case if you need to provide specific compatibility configuration, you can pass it as argument to autoprefixer function:

options: {
    plugins: function () {
        return [autoprefixer('last 2 versions', 'ie 10')]
    }
}

Upvotes: 26

svnm
svnm

Reputation: 24308

Current webpack.config.js for using autoprefixer and postcss with webpack 2.1.0-beta.27

const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer')

module.exports = {
  entry: './index.js',
  devtool: 'inline-source-map',
  output: { filename: 'bundle.js', publicPath: '' },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { modules: true, importLoaders: 1 } },
          { loader: 'postcss-loader' },
        ]
      },
      {
        test: /\.js$/,
        use: [ { loader: 'babel-loader', options: { presets: ['es2015', 'react', 'stage-2'] } } ],
        exclude: /node_modules/,
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({ title: 'Example', template: './index.html' }),
    new webpack.LoaderOptionsPlugin({ options: { postcss: [ autoprefixer ] } })
  ],
}

Note: The LoaderOptionsPlugin is a 'polyfill' required in webpack =< 2.1.0-beta.24. I will update this answer when I work out the new syntax.

Running it:

Have the following relevant packages in package.json:

"dependencies": {
  "autoprefixer": "^6.5.4",
  "babel-core": "^6.7.6",
  "babel-loader": "^6.2.4",
  "babel-preset-es2015": "^6.6.0",
  "babel-preset-react": "^6.5.0",
  "babel-preset-stage-2": "^6.5.0",
  "babel-register": "^6.7.2",
  "babel-runtime": "^6.6.1",
  "css-loader": "^0.26.1",
  "postcss-loader": "^1.2.1",
  "style-loader": "^0.13.1",
  "webpack": "2.1.0-beta.27",
  "webpack-dev-server": "2.1.0-beta.12"
}

And the following relevant script in package.json:

"scripts": {
  "dev": "NODE_ENV=dev webpack-dev-server --port 3000 --inline --hot"
},

And run it with

yarn install
npm run dev

Upvotes: 3

Pranesh Ravi
Pranesh Ravi

Reputation: 19113

Webpack 2.x.x is a killer and a build breaker

webpack 2.x.x introduced webpack.LoaderOptionsPlugin() plugin where you need to define all the loader option plugins. Like, autoprefixer is a plugin for postcss-loader. So, it has to go here.

And

  • module.rules replaces module.loaders
  • All the loaders should have explicitly say that they are a loader. Ex. loader: 'style!css' should be loader: 'style-loader!css-loader'

The new config will look something like this...

...

module: {
  rules: [
     {
       test: /\.scss$/,
       loaders: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']
     }
   ]
},

plugins: [
  new webpack.LoaderOptionsPlugin({
    options: {
      postcss: [
        autoprefixer(),
      ]
     }
  })
],

...

Hope this helps everyone.

Upvotes: 26

Related Questions