There are multiple ways to specify Webpack loaders. If you haven't seen them all, Webpack configs may be confusing.

Webpack 2 won't help the situation - it adds still one more way to specify loaders.

To explain these different approaches, I'll show you 7 ways to write the same exact loader configuration.

This particular configuration passes .css files through the postcss-loader, then the css-loader, then the style-loader.

So here they are - seven equivalent, but different, webpack loader configs:

1. Loaders Array

My favorite way - the most readable and the most explicit.

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

2. Loaders Array - Short Version

The -loader part is optional. You can leave it off.

{
  test: /\.css$/,
  loaders: ['style', 'css', 'postcss']
}

3. Loader String

Instead of an array, you can specify an exclamation-point-delimited string. Note that the property name must be 'loader' NOT 'loaders'.

{
  test: /\.css$/,
  loader: 'style-loader!css-loader!postcss-loader'
}

4. Loader String - Short Version

Similarly to the array, with the string you can leave the -loader part off.

{
  test: /\.css$/,
  loader: 'style!css!postcss'
}

5. Combination Short and Long Version

With the string or the array you can use a combination of the long and the short version.

{
  test: /\.css$/,
  loader: 'style!css-loader!postcss'
}

6. require() string

You can leave the loaders out of your config file entirely and specify them in your require statement like this:

// ES6 
import 'style!css!postcss!./main.css';
// ES5 
require('style!css!postcss!./main.css');

This one is usually not recommended because the loaders have to be specified repeatedly in each import.

7. Webpack 2: Loader Objects

Webpack 2 maintains compatibility with the old loader configuration styles, and adds a new one:

{
  test: /\.css$/,
  loaders: [
    {
      loader: 'style',
    },
    {
      loader: 'css',
    },
    {
      loader: 'postcss',
    },
  ],
}

The Webpack 2 documentation doesn't appear to exist yet, but you can read about the above configuration in this post by the creator of Webpack.

But Why?

Why? Good question. This is one of the reasons so many people have trouble with Webpack configs.

At least you can rest assured that this particular gotcha won't get you anymore.

I am personally a big Webpack fan, despite some of the confusing gotchas. But the above might make one consider the alternatives: brunch, rollup, or systemjs.