[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
<div align="center">
<img width="180" height="180" hspace="10"
alt="PostCSS Logo"
src="https://api.postcss.org/logo.svg">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" hspace="10"
src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon.svg">
</a>
<div align="center">
<a href="https://evilmartians.com/?utm_source=postcss">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54" vspace="10">
</a>
</div>
<h1>PostCSS Loader</h1>
<p>Loader for <a href="https://webpack.js.org/">webpack</a> to process CSS with <a href="https://postcss.org/">PostCSS</a></p>
</div>
<h2 align="center">Install</h2>
```bash
npm i -D postcss-loader
```
<h2 align="center">Usage</h2>
### `Configuration`
**`postcss.config.js`**
```js
module.exports = {
parser: 'sugarss',
plugins: {
'postcss-import': {},
'postcss-preset-env': {},
'cssnano': {}
}
}
```
You can read more about common PostCSS Config [here](https://github.com/michael-ciniawsky/postcss-load-config).
### `Config Cascade`
You can use different `postcss.config.js` files in different directories.
Config lookup starts from `path.dirname(file)` and walks the file tree upwards until a config file is found.
```
|– components
| |– component
| | |– index.js
| | |– index.png
| | |– style.css (1)
| | |– postcss.config.js (1)
| |– component
| | |– index.js
| | |– image.png
| | |– style.css (2)
|
|– postcss.config.js (1 && 2 (recommended))
|– webpack.config.js
|
|– package.json
```
After setting up your `postcss.config.js`, add `postcss-loader` to your `webpack.config.js`. You can use it standalone or in conjunction with `css-loader` (recommended). Use it **after** `css-loader` and `style-loader`, but **before** other preprocessor loaders like e.g `sass|less|stylus-loader`, if you use any.
**`webpack.config.js`**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'postcss-loader' ]
}
]
}
}
```
> ⚠️ When `postcss-loader` is used standalone (without `css-loader`) don't use `@import` in your CSS, since this can lead to quite bloated bundles
**`webpack.config.js` (recommended)**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader'
]
}
]
}
}
```
<h2 align="center">Options</h2>
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|[`exec`](#exec)|`{Boolean}`|`undefined`|Enable PostCSS Parser support in `CSS-in-JS`|
|[`parser`](#syntaxes)|`{String\|Object}`|`undefined`|Set PostCSS Parser|
|[`syntax`](#syntaxes)|`{String\|Object}`|`undefined`|Set PostCSS Syntax|
|[`stringifier`](#syntaxes)|`{String\|Object}`|`undefined`|Set PostCSS Stringifier|
|[`config`](#config)|`{Object}`|`undefined`|Set `postcss.config.js` config path && `ctx`|
|[`plugins`](#plugins)|`{Array\|Function}`|`[]`|Set PostCSS Plugins|
|[`sourceMap`](#sourcemap)|`{String\|Boolean}`|`false`|Enable Source Maps|
### `Exec`
If you use JS styles without the [`postcss-js`][postcss-js] parser, add the `exec` option.
**`webpack.config.js`**
```js
{
test: /\.style.js$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
{ loader: 'postcss-loader', options: { parser: 'sugarss', exec: true } }
]
}
```
### `Config`
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|[`path`](#path)|`{String}`|`undefined`|PostCSS Config Directory|
|[`context`](#context)|`{Object}`|`undefined`|PostCSS Config Context|
#### `Path`
You can manually specify the path to search for your config (`postcss.config.js`) with the `config.path` option. This is needed if you store your config in a separate e.g `./config || ./.config` folder.
> ⚠️ Otherwise it is **unnecessary** to set this option and is **not** recommended
> ⚠️ Note that you **can't** use a **filename** other than the [supported config formats] (e.g `.postcssrc.js`, `postcss.config.js`), this option only allows you to manually specify the **directory** where config lookup should **start** from
**`webpack.config.js`**
```js
{
loader: 'postcss-loader',
options: {
config: {
path: 'path/to/.config/' ✅
path: 'path/to/.config/css.config.js' ❌
}
}
}
```
[supported config formats]: https://github.com/michael-ciniawsky/postcss-load-config#usage
#### `Context (ctx)`
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|`env`|`{String}`|`'development'`|`process.env.NODE_ENV`|
|`file`|`{Object}`|`loader.resourcePath`|`extname`, `dirname`, `basename`|
|`options`|`{Object}`|`{}`|Options|
`postcss-loader` exposes context `ctx` to the config file, making your `postcss.config.js` dynamic, so can use it to do some real magic ✨
**`postcss.config.js`**
```js
module.exports = ({ file, options, env }) => ({
parser: file.extname === '.sss' ? 'sugarss' : false,
plugins: {
'postcss-import': { root: file.dirname },
'postcss-preset-env': options['postcss-preset-env'] ? options['postcss-preset-env'] : false,
'cssnano': env === 'production' ? options.cssnano : false
}
})
```
**`webpack.config.js`**
```js
{
loader: 'postcss-loader',
options: {
config: {
ctx: {
'postcss-preset-env': {...options},
cssnano: {...options},
}
}
}
}
```
### `Plugins`
**`webpack.config.js`**
```js
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-preset-env')(),
require('cssnano')()
]
}
}
```
> ⚠️ webpack requires an identifier (`ident`) in `options` when `{Function}/require` is used (Complex Options). The `ident` can be freely named as long as it is unique. It's recommended to name it (`ident: 'postcss'`)
### `Syntaxes`
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|[`parser`](#parser)|`{String\|Function}`|`undefined`|Custom PostCSS Parser|
|[`syntax`](#syntax)|`{String\|Function}`|`undefined`|Custom PostCSS Syntax|
|[`stringifier`](#stringifier)|`{String\|Function}`|`undefined`|Custom PostCSS Stringifier|
#### `Parser`
**`webpack.config.js`**
```js
{
test: /\.sss$/,
use: [
...,
{ loader: 'postcss-loader', options: { parser: 'sugarss' } }
]
}
```
#### `Syntax`
**`webpack.config.js`**
```js
{
test: /\.css$/,
use: [
...,
{ loader: 'postcss-loader', options: { syntax: 'sugarss' } }
]
}
```
#### `Stringifier`
**`webpack.config.js`**
```js
{
test: /\.css$/,
use: [
...,
{ loader: 'postcss-loader', options: { stringifier: 'midas' } }
]
}
```
### `SourceMap`
Enables source map support, `postcss-loader` will use the previous source map given by other loaders and update it accordingly, if no previous loader is applied before `postcss-loader`, the loader will generate a source map for you.
**`webpack.config.js`**
```js
{
test: /\.css/,
use: [
{ loader: 'style-loader', options: { sourceMap: true } },
{ loader: 'css-loader', options: { sourceMap: true } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } }
]
}
```
#### `'inline'`
You can set the `sourceMap: 'inline'` option to inline the source map
within the CSS directly as an annotation comment.
**`webpack.config.js`**
```js
{
loader: 'postcss-loader',
options: {
sourceMap: 'inline'
}
}
```
```css
.class { color: red; }
/*# sourceMappingURL=data:application/json;base64, ... */
```
<h2 align="center">Examples</h2>
###