Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ExtractTextPlugin and postCSS - autoprefixer not working

I'm trying to setup webpack to have a compilation pass where it scans all css files in one file tree and then generates a css files with all the styles bundled, autoprefixed and minimised.

I can't get autoprefixer plugin to work.

Here is the relevant webpack config part:

const webpack = require('webpack')
const path = require('path')
const glob = require('glob')
const ExtractTextPlugin = require('extract-text-webpack-plugin');

// postCSS plugins
const autoprefixer = require('autoprefixer')

module.exports = [
{
  // another compilation pass
},
{
  name: 'static-css',
  entry: {
    vendor: glob.sync(path.join(__dirname, 'assets/stylesheets/vendor/**/*.css')),
    styles: glob.sync(path.join(__dirname, 'assets/stylesheets/src/**/*.css'))
  },
  devtool: 'source-map',
  output: {
    path: path.join(__dirname, 'assets/stylesheets/build/'),
    filename: 'bundle.js',
  },
  module: {
    loaders: [
      // css loader for custom css
      {
        test: /\.css$/,
        include: path.join(__dirname, 'assets/stylesheets/src'),
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
      },
      // css loader for vendor css
      {
        test: /\.css$/,
        include: path.join(__dirname, 'assets/stylesheets/vendor'),
        loader: 'style-loader!css-loader'
      },
      // other loaders for images, fonts, and svgs
      {
        test: /\.png$/,
        loader: 'url-loader?limit=100000'
      },
      {
        test: /\.jpg$/,
        loader: 'file-loader'
      },
      {
        test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url?limit=10000&mimetype=application/font-woff'
      },
      {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url?limit=10000&mimetype=application/octet-stream'
      },
      {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'file'
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader: 'url?limit=10000&mimetype=image/svg+xml'
      }
    ],
    postcss: function() {
      return [
        autoprefixer
      ]
    }
  },
  plugins: [
    // extract css in a .css file
    new ExtractTextPlugin('[name].css')
  ]
}
];

When I run webpack, I get all the files compressed in the bundle.js and correctly extracted in a separate styles.css file. But the vendor prefixes are not applied.

I'm using this class to test the prefixes:

.autoprefixer-test {
  display: flex;
  transition: all .5s;
  background: linear-gradient(to bottom, white, black);
  user-select: none;
}

I've tried to change the call to ExtractTextPlugin.extract like ExtractTextPlugin.extract('style-loader', ['css-loader', 'postcss-loader']) as seen in other posts, but it doesn't help at all.

Any ideas?

like image 904
Héctor Avatar asked Aug 18 '16 10:08

Héctor


1 Answers

It seems like you've misplaced the postcss parameters. According to the documentation at https://github.com/postcss/postcss-loader the following code should be placed at the top level of your configuration and not under the module section:

postcss: function() {
  return [
    autoprefixer
  ]
}

Update.

In fact there is a lot more configuration to be written for this integration of postcss and webpack to work. Thanks to the following thread I've found the solution https://github.com/postcss/postcss-loader/issues/8

First, in order for postcss to be able for work on @import'ed files, postcss-import plugin needs to be used. To integrate this plugin with webpack (eg. enable file watching for hot reloading or rebuilding), special parameter taken from initializer's function arguments is passed as an argument to postcssImport like this:

var autoprefixer = require('autoprefixer');
var postcssImport = require('postcss-import');
....
postcss: function(webpack) {
  return [
    postcssImport({ addDependencyTo: webpack }), // should be first
    autoprefixer
  ];
]

Sadly, this breaks asset loading through webpack when using url(...) with relative paths. This happens because postcss-import merges all @import'ed files into one, but paths remain relative to files initial directories. In order to rewrite relative paths, postcss-url plugin should be used and configuration now looks like this:

var autoprefixer = require('autoprefixer');
var postcssImport = require('postcss-import');
var postcssUrl = require('postcss-url');
....
postcss: function(webpack) {
  return [
    postcssImport({ addDependencyTo: webpack }),
    postcssUrl(),
    autoprefixer
  ];
]
like image 177
Andrew Starostin Avatar answered Sep 21 '22 15:09

Andrew Starostin