PostCSS loader for webpack
npm install @phated/postcss-loader[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![size][size]][size-url]
Webpack chat: [![chat][chat]][chat-url]
PostCSS chat: [![chat-postcss][chat-postcss]][chat-postcss-url]
Loader to process CSS with PostCSS.
To begin, you'll need to install postcss-loader and postcss:
``console`
npm install --save-dev postcss-loader postcss
Then add the plugin to your webpack config. For example:
file.js
`js`
import css from "file.css";
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
],
},
],
},
};
Alternative use with config files:
postcss.config.js
`js`
module.exports = {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
};
The loader automatically searches for configuration files.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ["style-loader", "css-loader", "postcss-loader"],
},
],
},
};
And run webpack via your preferred method.
| Name | Type | Default | Description |
| :---------------------------------: | :------------------: | :-----------------------------------: | :------------------------------------------- |
| execute | {Boolean} | undefined | Enable PostCSS Parser support in CSS-in-JS |postcssOptions
| | {Object\|Function} | defaults values for Postcss.process | Set PostCSS options and plugins |sourceMap
| | {Boolean} | compiler.devtool | Enables/Disables generation of source maps |
Type: Booleanundefined
Default:
If you use JS styles the postcss-js parser, add the execute option.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.style.js$/,
use: [
"style-loader",
{
loader: "css-loader",
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
parser: "postcss-js",
},
execute: true,
},
},
],
},
],
},
};
Type: Object|Functionundefined
Default:
Allows to set PostCSS options and plugins.
All PostCSS options are supported.config
There is the special option for config files. How it works and how it can be configured is described below.
We recommend do not specify from, to and map options, because this can lead to wrong path in source maps.sourcemap
If you need source maps please use the option.
#### Object
Setup plugins:
webpack.config.js (recommended)
`js
const myOtherPostcssPlugin = require("postcss-my-plugin");
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-import",
["postcss-short", { prefix: "x" }],
require.resolve("my-postcss-plugin"),
myOtherPostcssPlugin({ myOption: true }),
// Deprecated and will be removed in the next major release
{ "postcss-nested": { preserveEmpty: true } },
],
},
},
},
],
},
};
`
webpack.config.js (deprecated, will be removed in the next major release)
`js`
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: {
"postcss-import": {},
"postcss-short": { prefix: "x" },
},
},
},
},
],
},
};
Setup syntax:
webpack.config.js
`jsString
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
// Can be Object
syntax: "sugarss",
// Can be `
syntax: require("sugarss"),
},
},
},
],
},
};
Setup parser:
webpack.config.js
`jsString
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
// Can be Object
parser: "sugarss",
// Can be Function
parser: require("sugarss"),
// Can be `
parser: require("sugarss").parse,
},
},
},
],
},
};
Setup stringifier:
webpack.config.js
`js
const Midas = require("midas");
const midas = new Midas();
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
// Can be StringObject
stringifier: "sugarss",
// Can be Function
stringifier: require("sugarss"),
// Can be `
stringifier: midas.stringifier,
},
},
},
],
},
};
#### Function
webpack.config.js
`js
module.exports = {
module: {
rules: [
{
test: /\.(css|sss)$/i,
loader: "postcss-loader",
options: {
postcssOptions: (loaderContext) => {
if (/\.sss$/.test(loaderContext.resourcePath)) {
return {
parser: "sugarss",
plugins: [
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
}
return {
plugins: [
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
},
},
},
],
},
};
`
#### config
Type: Boolean|Stringundefined
Default:
Allows to set options using config files.
Options specified in the config file are combined with options passed to the loader, the loader options overwrite options from config.
##### Config Files
The loader will search up the directory tree for configuration in the following places:
- a postcss property in package.json.postcssrc
- a file in JSON or YAML format.postcssrc.json
- a , .postcssrc.yaml, .postcssrc.yml, .postcssrc.js, or .postcssrc.cjs filepostcss.config.js
- a or postcss.config.cjs CommonJS module exporting an object (recommended)
##### Examples of Config Files
Using Object notation:
postcss.config.js (recommend)
`js`
module.exports = {
// You can specify any options from https://postcss.org/api/#processoptions here
// parser: 'sugarss',
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
Using Function notation:
postcss.config.js (recommend)
`jsapi.file
module.exports = (api) => {
// - path to the fileapi.mode
// - mode value of webpack, please read https://webpack.js.org/configuration/mode/api.webpackLoaderContext
// - loader context for complex use casesapi.env
// - alias api.mode for compatibility with postcss-cliapi.options
// - the postcssOptions options
if (/\.sss$/.test(api.file)) {
return {
// You can specify any options from https://postcss.org/api/#processoptions here
parser: "sugarss",
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
}
return {
// You can specify any options from https://postcss.org/api/#processoptions here
plugins: [
// Plugins for PostCSS
["postcss-short", { prefix: "x" }],
"postcss-preset-env",
],
};
};
`
postcss.config.js (deprecated, will be removed in the next major release)
`js`
module.exports = {
// You can specify any options from https://postcss.org/api/#processoptions here
// parser: 'sugarss',
plugins: {
// Plugins for PostCSS
"postcss-short": { prefix: "x" },
"postcss-preset-env": {},
},
};
##### Config Cascade
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.css-loader
You can use it standalone or in conjunction with (recommended).
Use it before css-loader and style-loader, but after other preprocessor loaders like e.g sass|less|stylus-loader, if you use any (since webpack loaders evaluate right to left/bottom to top).
webpack.config.js (recommended)
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
},
},
"postcss-loader",
],
},
],
},
};
#### Boolean
Enables/Disables autoloading config.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
config: false,
},
},
},
],
},
};
#### String
Allows to specify the path to the config file.
webpack.config.js
`js
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: "postcss-loader",
options: {
postcssOptions: {
config: path.resolve(__dirname, "custom.config.js"),
},
},
},
],
},
};
`
Type: Booleancompiler.devtool
Default: depends on the value
By default generation of source maps depends on the devtool option.
All values enable source map generation except eval and false value.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: "style-loader" },
{ loader: "css-loader", options: { sourceMap: true } },
{ loader: "postcss-loader", options: { sourceMap: true } },
{ loader: "sass-loader", options: { sourceMap: true } },
],
},
],
},
};
Alternative setup:
webpack.config.js
`js`
module.exports = {
devtool: "source-map",
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "postcss-loader" },
{ loader: "sass-loader" },
],
},
],
},
};
Type: Functionundefined
Default:
The special implementation option determines which implementation of PostCSS to use. Overrides the locally installed peerDependency version of postcss.
This option is only really useful for downstream tooling authors to ease the PostCSS 7-to-8 transition.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{
loader: "postcss-loader",
options: { implementation: require("postcss") },
},
{ loader: "sass-loader" },
],
},
],
},
};
You'll need to install sugarss:
`console`
npm install --save-dev sugarss
Using SugarSS syntax.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.sss$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: { importLoaders: 1 },
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
parser: "sugarss",
},
},
},
],
},
],
},
};
You'll need to install autoprefixer:
`console`
npm install --save-dev autoprefixer
Add vendor prefixes to CSS rules using autoprefixer.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: { importLoaders: 1 },
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"autoprefixer",
{
// Options
},
],
],
},
},
},
],
},
],
},
};
> :warning: postcss-preset-env includes autoprefixer, so adding it separately is not necessary if you already use the preset. More information
You'll need to install postcss-preset-env:
`console`
npm install --save-dev postcss-preset-env
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: { importLoaders: 1 },
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
// Options
},
],
],
},
},
},
],
},
],
},
};
What is CSS Modules? Please read.
No additional options required on the postcss-loader side.css-loader
To make them work properly, either add the ’s importLoaders option.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
importLoaders: 1,
},
},
"postcss-loader",
],
},
],
},
};
You'll need to install postcss-js:
`console`
npm install --save-dev postcss-js
If you want to process styles written in JavaScript, use the postcss-js parser.
webpack.config.js
`js`
module.exports = {
module: {
rules: [
{
test: /\.style.js$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
parser: "postcss-js",
},
execute: true,
},
},
"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.
Using mini-css-extract-plugin.
webpack.config.js
`js
const isProductionMode = process.env.NODE_ENV === "production";
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: isProductionMode ? "production" : "development",
module: {
rules: [
{
test: /\.css$/,
use: [
isProductionMode ? MiniCssExtractPlugin.loader : "style-loader",
"css-loader",
"postcss-loader",
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: isProductionMode ? "[name].[contenthash].css" : "[name].css",
}),
],
};
`
To write a asset from PostCSS plugin to the webpack, need to add a message in result.messages.
The message should contain the following fields:
- type = asset - Message type (require, should be equal asset)file
- - file name (require)content
- - file content (require)sourceMap
- - sourceMapinfo
- - asset info
webpack.config.js
`js
const customPlugin = () => (css, result) => {
result.messages.push({
type: "asset",
file: "sprite.svg",
content: "",
});
};
const postcssPlugin = postcss.plugin("postcss-assets", customPlugin);
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [postcssPlugin()],
},
},
},
],
},
],
},
};
`
The dependencies are necessary for webpack to understand when it needs to run recompilation on the changed files.
There are two way to add dependencies:
1. (Recommended). The plugin may emit messages in result.messages.
The message should contain the following fields:
- type = dependency - Message type (require, should be equal dependency)file
- - absolute file path (require)
webpack.config.js
`js
const path = require("path");
const customPlugin = () => (css, result) => {
result.messages.push({
type: "dependency",
file: path.resolve(__dirname, "path", "to", "file"),
});
};
const postcssPlugin = postcss.plugin("postcss-assets", customPlugin);
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [postcssPlugin()],
},
},
},
],
},
],
},
};
`
2. Pass loaderContext in plugin.
webpack.config.js
`js
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
config: path.resolve(__dirname, "path/to/postcss.config.js"),
},
},
},
],
},
],
},
};
`
postcss.config.js
`js`
module.exports = (api) => ({
plugins: [
require("path/to/customPlugin")({
loaderContext: api.webpackLoaderContext,
}),
],
});
customPlugin.js
`js
const path = require("path");
const customPlugin = (loaderContext) => (css, result) => {
loaderContext.webpack.addDependency(
path.resolve(__dirname, "path", "to", "file")
);
};
module.exports = postcss.plugin("postcss-assets", customPlugin);
``
Please take a moment to read our contributing guidelines if you haven't yet done so.
[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/webpack-contrib/postcss-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/postcss-loader
[tests]: https://github.com/webpack-contrib/postcss-loader/workflows/postcss-loader/badge.svg
[tests-url]: https://github.com/webpack-contrib/postcss-loader/actions
[cover]: https://codecov.io/gh/webpack-contrib/postcss-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/postcss-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[chat-postcss]: https://badges.gitter.im/postcss/postcss.svg
[chat-postcss-url]: https://gitter.im/postcss/postcss
[size]: https://packagephobia.now.sh/badge?p=postcss-loader
[size-url]: https://packagephobia.now.sh/result?p=postcss-loader