Skip to content

webpack-contrib/postcss-loader

Repository files navigation

npm node tests coverage size

Webpack discussion:discussion

PostCSS chat:chat-postcss

postcss-loader

Loader to process CSS withPostCSS.

Getting Started

You need webpack v5 to use the latest version. For Webpack v4, you have to install postcss-loader v4.

To begin, you'll need to installpostcss-loaderandpostcss:

npm install --save-dev postcss-loader postcss

or

yarn add -D postcss-loader postcss

or

pnpm add -D postcss-loader postcss

Then add the plugin to yourwebpackconfig. For example:

In the following configuration the pluginpostcss-preset-envis used, which is not installed by default.

file.js

importcssfrom"file.css";

webpack.config.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 withconfig files:

postcss.config.js

module.exports={
plugins:[
[
"postcss-preset-env",
{
// Options
},
],
],
};

The loaderautomaticallysearches for configuration files.

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.css$/i,
use:["style-loader","css-loader","postcss-loader"],
},
],
},
};

And runwebpackvia your preferred method.

Options

execute

Type:

typeexecute=boolean;

Default:undefined

Enable PostCSS Parser support inCSS-in-JS. If you use JS styles thepostcss-jsparser, add theexecuteoption.

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.style.js$/,
use:[
"style-loader",
{
loader:"css-loader",
},
{
loader:"postcss-loader",
options:{
postcssOptions:{
parser:"postcss-js",
},
execute:true,
},
},
],
},
],
},
};

postcssOptions

See the file./src/config.d.ts.

Type:

importtype{ConfigasPostCSSConfig}from"postcss-load-config";
importtype{LoaderContext}from"webpack";

typePostCSSLoaderContext=LoaderContext<PostCSSConfig>;

interfacePostCSSLoaderAPI{
mode:PostCSSLoaderContext["mode"];
file:PostCSSLoaderContext["resourcePath"];
webpackLoaderContext:PostCSSLoaderContext;
env:PostCSSLoaderContext["mode"];
options:PostCSSConfig;
}

exporttypePostCSSLoaderOptions=
|PostCSSConfig
|((api:PostCSSLoaderAPI)=>PostCSSConfig);

Default:undefined

Allows to setPostCSS optionsand plugins.

AllPostCSSoptions are supported. There is the specialconfigoption for config files. How it works and how it can be configured is described below.

We recommend do not specifyfrom,toandmapoptions, because this can lead to wrong path in source maps. If you need source maps please use thesourcemapoption.

For large projects, to optimize performance of the loader, it is better to providepostcssOptionsin loader config and specifyconfig: false.This approach removes the need to lookup and load external config files multiple times during compilation.

object

Setupplugins:

webpack.config.js(recommended)

constmyOtherPostcssPlugin=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)

module.exports={
module:{
rules:[
{
test:/\.sss$/i,
loader:"postcss-loader",
options:{
postcssOptions:{
plugins:{
"postcss-import":{},
"postcss-short":{prefix:"x"},
},
},
},
},
],
},
};

Setupsyntax:

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.sss$/i,
loader:"postcss-loader",
options:{
postcssOptions:{
// Can be `string`
syntax:"sugarss",
// Can be `object`
syntax:require("sugarss"),
},
},
},
],
},
};

Setupparser:

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.sss$/i,
loader:"postcss-loader",
options:{
postcssOptions:{
// Can be `string`
parser:"sugarss",
// Can be `object`
parser:require("sugarss"),
// Can be `function`
parser:require("sugarss").parse,
},
},
},
],
},
};

Setupstringifier:

webpack.config.js

constMidas=require("midas");
constmidas=newMidas();

module.exports={
module:{
rules:[
{
test:/\.sss$/i,
loader:"postcss-loader",
options:{
postcssOptions:{
// Can be `string`
stringifier:"sugarss",
// Can be `object`
stringifier:require("sugarss"),
// Can be `function`
stringifier:midas.stringifier,
},
},
},
],
},
};

function

webpack.config.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:

typeconfig=boolean|string;

Default:true

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:

  • apostcssproperty inpackage.json
  • a.postcssrcfile in JSON or YAML format
  • a.postcssrc.json,.postcssrc.yaml,.postcssrc.yml,.postcssrc.js,or.postcssrc.cjsfile
  • apostcss.config.jsorpostcss.config.cjsCommonJS module exporting an object (recommended)
Examples of Config Files

Usingobjectnotation:

postcss.config.js(recommend)

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",
],
};

Usingfunctionnotation:

postcss.config.js(recommend)

module.exports=(api)=>{
// `api.file` - path to the file
// `api.mode` - `mode` value of webpack, please read https://webpack.js.org/configuration/mode/
// `api.webpackLoaderContext` - loader context for complex use cases
// `api.env` - alias `api.mode` for compatibility with `postcss-cli`
// `api.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)

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 differentpostcss.config.jsfiles in different directories. Config lookup starts frompath.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 yourpostcss.config.js,addpostcss-loaderto yourwebpack.config.js. You can use it standalone or in conjunction withcss-loader(recommended).

Use itbeforecss-loaderandstyle-loader,butafterother preprocessor loaders like e.gsass|less|stylus-loader,if you use any (sincewebpack loaders evaluate right to left/bottom to top).

webpack.config.js(recommended)

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

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

constpath=require("path");

module.exports={
module:{
rules:[
{
test:/\.css$/i,
loader:"postcss-loader",
options:{
postcssOptions:{
config:path.resolve(__dirname,"custom.config.js"),
},
},
},
],
},
};

sourceMap

Type:

typesourceMap=boolean;

Default: depends on thecompiler.devtoolvalue

By default generation of source maps depends on thedevtooloption. All values enable source map generation exceptevalandfalsevalue.

webpack.config.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

module.exports={
devtool:"source-map",
module:{
rules:[
{
test:/\.css$/i,
use:[
{loader:"style-loader"},
{loader:"css-loader"},
{loader:"postcss-loader"},
{loader:"sass-loader"},
],
},
],
},
};

implementation

Type:

typeimplementation=object;

type ofimplementationshould be the same aspostcss.d.ts

Default:postcss

The specialimplementationoption determines which implementation of PostCSS to use. Overrides the locally installedpeerDependencyversion ofpostcss.

This option is only really useful for downstream tooling authors to ease the PostCSS 7-to-8 transition.

function

webpack.config.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"},
],
},
],
},
};

String

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.css$/i,
use:[
{loader:"style-loader"},
{loader:"css-loader"},
{
loader:"postcss-loader",
options:{implementation:require.resolve("postcss")},
},
{loader:"sass-loader"},
],
},
],
},
};

Examples

SugarSS

You'll need to installsugarss:

npm install --save-dev sugarss

UsingSugarSSsyntax.

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.sss$/i,
use:[
"style-loader",
{
loader:"css-loader",
options:{importLoaders:1},
},
{
loader:"postcss-loader",
options:{
postcssOptions:{
parser:"sugarss",
},
},
},
],
},
],
},
};

Autoprefixer

You'll need to installautoprefixer:

npm install --save-dev autoprefixer

Add vendor prefixes to CSS rules usingautoprefixer.

webpack.config.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-envincludesautoprefixer,so adding it separately is not necessary if you already use the preset. Moreinformation

PostCSS Preset Env

You'll need to installpostcss-preset-env:

npm install --save-dev postcss-preset-env

webpack.config.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
},
],
],
},
},
},
],
},
],
},
};

CSS Modules

What isCSS Modules?Pleaseread.

No additional options required on thepostcss-loaderside. To make them work properly, either add thecss-loader’simportLoadersoption.

webpack.config.js

module.exports={
module:{
rules:[
{
test:/\.css$/i,
use:[
"style-loader",
{
loader:"css-loader",
options:{
modules:true,
importLoaders:1,
},
},
"postcss-loader",
],
},
],
},
};

CSS-in-JS andpostcss-js

You'll need to installpostcss-js:

npm install --save-dev postcss-js

If you want to process styles written in JavaScript, use thepostcss-jsparser.

webpack.config.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

importcolorsfrom"./styles/colors";

exportdefault{
".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. Addbabel-plugin-add-module-exportsto your configuration.
  2. You need to have only onedefaultexport per style module.

Extract CSS

Usingmini-css-extract-plugin.

webpack.config.js

constisProductionMode=process.env.NODE_ENV==="production";

constMiniCssExtractPlugin=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:[
newMiniCssExtractPlugin({
filename:isProductionMode?"[name].[contenthash].css":"[name].css",
}),
],
};

Emit assets

To write a asset from PostCSS plugin to the webpack, need to add a message inresult.messages.

The message should contain the following fields:

  • type=asset- Message type (require, should be equalasset)
  • file- file name (require)
  • content- file content (require)
  • sourceMap- sourceMap
  • info- asset info

webpack.config.js

constpostcssCustomPlugin=(opts={})=>{
return{
postcssPlugin:"postcss-custom-plugin",
Once:(root,{result})=>{
result.messages.push({
type:"asset",
file:"sprite.svg",
content:"<svg>...</svg>",
});
},
};
};

module.exports={
module:{
rules:[
{
test:/\.css$/i,
use:[
"style-loader",
"css-loader",
{
loader:"postcss-loader",
options:{
postcssOptions:{
plugins:[postcssCustomPlugin()],
},
},
},
],
},
],
},
};

Add dependencies, contextDependencies, buildDependencies, missingDependencies

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 inresult.messages.

The message should contain the following fields:

  • type=dependency- Message type (require, should be equaldependency,context-dependency,build-dependencyormissing-dependency)
  • file- absolute file path (require)

webpack.config.js

constpath=require("path");

constpostcssCustomPlugin=(opts={})=>{
return{
postcssPlugin:"postcss-custom-plugin",
Once:(root,{result})=>{
result.messages.push({
type:"dependency",
file:path.resolve(__dirname,"path","to","file"),
});
},
};
};

module.exports={
module:{
rules:[
{
test:/\.css$/i,
use:[
"style-loader",
"css-loader",
{
loader:"postcss-loader",
options:{
postcssOptions:{
plugins:[postcssCustomPlugin()],
},
},
},
],
},
],
},
};

Or you can use ready-made pluginpostcss-add-dependencies.

  1. PassloaderContextin plugin.

webpack.config.js

constpath=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

module.exports=(api)=>({
plugins:[
require("path/to/postcssCustomPlugin.js")({
loaderContext:api.webpackLoaderContext,
}),
],
});

postcssCustomPlugin.js

constpath=require("path");

constpostcssCustomPlugin=(opts={})=>{
return{
postcssPlugin:"postcss-custom-plugin",
Once:(root,{result})=>{
opts.loaderContext.addDependency(
path.resolve(__dirname,"path","to","file"),
);
},
};
};

postcssCustomPlugin.postcss=true;
module.exports=postcssCustomPlugin;

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT