Skip to content

How to include PostCSS

Jamie Spittal edited this page Feb 10, 2016 · 9 revisions

Overview

We want to be able to use any and all PostCSS plugins to process our styles and then apply those styles to components using view encapsulation.

It's been mentioned in the including SCSS wiki article that you need to use the raw-loader. The reason for that is, when Webpack requires styles the css-loader or sass-loader will return a Javascript object that is meant to be parsed by something like the style-loader. However, this is not ideal when using Angular2 as it's become a very popular pattern to scope your styles with view encapsulation using syntax like this:

@Component({
  selector: 'test-component',
  template: require('./template.html'),
  styles: [
    require('./styles.css') //<-- Including the style
  ]
})
export class TestComponent {
  
}

The raw-loader solves this by interpreting the styles required as a string. We can now safely pass styles from the css-loader or scss-loader into the raw loader, and it will spit out a string that we can give to the component's styles array.

So what about PostCSS

The postCSS-loader is quite a bit different. When passing results from it to the raw-loader you end up with a string like this:

exports = module.exports = require("./../../node_modules/css-loader/lib/css-base.js")();
// imports


// module
exports.push([module.id, ":root {\n  background-color: blue;\n}\n", ""]);

// exports

Obviously not ideal, it seems like the PostCSS loader is doing some magic importing that the raw-loader is interpreting as a string. Luckily there's a webpack plugin called to-string-loader designed to take the Webpack styles object and cast it to a string. Let's take a look at how to configure that.

Step by Step OR TL:DR

  • Install postcss-loader, css-loader, to-string-loader and desired postCSS plugins (in this example cssnext)
npm install --save-dev postcss-loader css-loader to-string-loader postcss-cssnext
  • Create loader configuration for PostCSS. As part of your loaders array in webpack.config.js and webpack.prod.config.js add:
[
    //...
    { test: /\.css$/,   loader: 'raw-loader!css-loader!postcss-loader'},
    //...
]
  • Add in any postCSS plugin. As part of your module.exports object in webpack.config.js and webpack.prod.config.js add:
module.exports = {
    //...
    postcss: [
        require('postcss-cssnext')({
            browsers: ['ie >= 9', 'last 2 versions']
        })
    ],
    //...
}

Success

We can now include postCSS into our project and still keep the great scoping that Angular 2 provides.

Clone this wiki locally