PostCSS loader for webpack
npm install @egoist/postcss-loader[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
Loader for webpack to process CSS with PostCSS
``bash`
npm i -D postcss-loader
postcss.config.js
`js`
module.exports = {
parser: 'sugarss',
plugins: {
'postcss-import': {},
'postcss-preset-env': {},
'cssnano': {}
}
}
You can read more about common PostCSS Config here.
You can use different postcss.config.js files in different directories.path.dirname(file)
Config lookup starts from 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'
]
}
]
}
}
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|exec|{Boolean}|undefined|Enable PostCSS Parser support in CSS-in-JS|parser
||{String\|Object}|undefined|Set PostCSS Parser|syntax
||{String\|Object}|undefined|Set PostCSS Syntax|stringifier
||{String\|Object}|undefined|Set PostCSS Stringifier|config
||{Object}|undefined|Set postcss.config.js config path && ctx|plugins
||{Array\|Function}|[]|Set PostCSS Plugins|sourceMap
||{String\|Boolean}|false|Enable Source Maps|
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 } }
]
}
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|path|{String}|undefined|PostCSS Config Directory|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},
}
}
}
}
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')
|Name|Type|Default|Description|
|:--:|:--:|:-----:|:----------|
|parser|{String\|Function}|undefined|Custom PostCSS Parser|syntax
||{String\|Function}|undefined|Custom PostCSS Syntax|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' } }
]
}
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, ... /
`
webpack.config.js
`js`
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')(),
require('stylelint')(),
...,
]
}
}
]
}
webpack.config.js
`js`
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('autoprefixer')({...options}),
...,
]
}
}
]
}
> :warning: postcss-preset-env includes autoprefixer, so adding it separately is not necessary if you already use the preset.
This loader [cannot be used] with [CSS Modules] out of the box due
to the way css-loader processes file imports. To make them work properly,importLoaders
either add the css-loader’s [] option.
webpack.config.js
`js`
{
test: /\.css$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { modules: true, importLoaders: 1 } },
'postcss-loader'
]
}
or use [postcss-modules] instead of css-loader.
[importLoaders]: https://github.com/webpack-contrib/css-loader#importloaders
[cannot be used]: https://github.com/webpack/css-loader/issues/137
[CSS Modules]: https://github.com/webpack/css-loader#css-modules
[postcss-modules]: https://github.com/css-modules/postcss-modules
If you want to process styles written in JavaScript, use the [postcss-js] parser.
[postcss-js]: https://github.com/postcss/postcss-js
webpack.config.js
`js`
{
test: /\.style.js$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { importLoaders: 2 } },
{ loader: 'postcss-loader', options: { parser: 'postcss-js' } },
'babel-loader'
]
}
As result you will be able to write styles in the following way
`js
import colors from './styles/colors'
export default {
'.menu': {
color: colors.main,
height: 25,
'&_link': {
color: 'white'
}
}
}
`
> :warning: If you are using Babel you need to do the following in order for the setup to work
> 1. Add [babel-plugin-add-module-exports] to your configuration
> 2. You need to have only one default export per style module
[babel-plugin-add-module-exports]: https://github.com/59naga/babel-plugin-add-module-exports
[ExtractPlugin]: https://github.com/webpack-contrib/mini-css-extract-plugin
webpack.config.js
`js
const devMode = process.env.NODE_ENV !== 'production'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : '[name].[hash].css'
})
]
}
``
![]() Michael Ciniawsky | ![]() Alexander Krasnoyarov |
[npm]: https://img.shields.io/npm/v/postcss-loader.svg
[npm-url]: https://npmjs.com/package/postcss-loader
[node]: https://img.shields.io/node/v/postcss-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/postcss/postcss-loader.svg
[deps-url]: https://david-dm.org/postcss/postcss-loader
[tests]: https://img.shields.io/travis/postcss/postcss-loader.svg
[tests-url]: https://travis-ci.org/postcss/postcss-loader
[cover]: https://coveralls.io/repos/github/postcss/postcss-loader/badge.svg
[cover-url]: https://coveralls.io/github/postcss/postcss-loader
[chat]: https://badges.gitter.im/postcss/postcss.svg
[chat-url]: https://gitter.im/postcss/postcss