postcss-loader

免责声明 postcss-loader是一个由社区成员维护的第三方包,它可能不具备与 webpack 相同的支持、安全策略或许可证,并且不受 webpack 维护。

npm node tests coverage size

Webpack 讨论: discussion

PostCSS 聊天: chat-postcss

一个使用 PostCSS 处理 CSS 的加载器。

入门

你需要 webpack v5 才能使用最新版本。对于 Webpack v4,你必须安装 postcss-loader v4。

首先,你需要安装 postcss-loaderpostcss

npm install --save-dev postcss-loader postcss

yarn add -D postcss-loader postcss

pnpm add -D postcss-loader postcss

然后将加载器添加到你的 webpack 配置中。例如:

在以下配置中使用了插件 postcss-preset-env,它默认情况下并未安装。

file.js

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

替代使用方式:配置文件

postcss.config.js

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

该加载器**会自动**搜索配置文件。

webpack.config.js

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

最后,使用你通常使用的方法运行 webpack(例如,通过 CLI 或 npm 脚本)。

选项

execute

类型

type execute = boolean;

默认值:undefined

启用 PostCSS 对 CSS-in-JS 的解析器支持。如果你使用 JS 样式和 postcss-js 解析器,请添加 execute 选项。

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

查看文件 https://github.com/webpack-contrib/postcss-loader/blob/master/src/config.d.ts

类型

import type { Config as PostCSSConfig } from "postcss-load-config";
import type { LoaderContext } from "webpack";

type PostCSSLoaderContext = LoaderContext<PostCSSConfig>;

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

export type PostCSSLoaderOptions =
  | PostCSSConfig
  | ((api: PostCSSLoaderAPI) => PostCSSConfig);

默认值:undefined

允许你设置 PostCSS options 和插件。

支持所有 PostCSS 选项。配置文件有一个特殊的 config 选项。其工作原理和配置方法将在下文描述。

我们建议不要指定 fromtomap 选项,因为这可能导致源码映射中的路径错误。如果你需要源码映射,请改用 sourcemap 选项。

对于大型项目,为了优化加载器性能,最好在加载器配置中提供 postcssOptions 并指定 config: false。这种方法消除了在编译过程中多次查找和加载外部配置文件的需要。

object

设置 plugins

webpack.config.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已废弃,将在下个主要版本中移除)

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

设置 syntax

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

设置 parser

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

设置 stringifier

webpack.config.js

const Midas = require("midas");
const midas = new Midas();

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 config = boolean | string;

默认值:true

允许你使用配置文件设置选项。配置文件中指定的选项将与传递给加载器的选项合并,加载器选项会覆盖配置文件中的选项。

配置文件

加载器会在目录树中向上搜索以下位置的配置:

  • `package.json` 中的 postcss 属性
  • JSON 或 YAML 格式的 .postcssrc 文件
  • 一个 .postcssrc.json.postcssrc.yaml.postcssrc.yml.postcssrc.js.postcssrc.cjs 文件
  • 导出对象的 postcss.config.jspostcss.config.cjs CommonJS 模块(推荐
配置文件示例

使用 object 记法

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

使用 function 记法

postcss.config.js推荐

module.exports = (api) => {
  // `api.file` - path to the file
  // `api.mode` - `mode` value of webpack, please read https://webpack.js.cn/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已废弃,将在下个主要版本中移除)

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": {},
  },
};
配置级联

你可以在不同的目录中使用不同的 postcss.config.js 文件。配置查找从 path.dirname(file) 开始,并向上遍历文件树,直到找到配置文件。

|– 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

设置好 postcss.config.js 后,将 postcss-loader 添加到你的 webpack.config.js 中。你可以单独使用它,也可以与 css-loader 结合使用(推荐)。

使用 postcss-loadercss-loaderstyle-loader **之前**,但在其他预处理器加载器(如 sass|less|stylus-loader)**之后**(因为 webpack 加载器从右到左/从下到上评估)。

webpack.config.js推荐

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

boolean

启用/禁用自动加载配置。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: "postcss-loader",
        options: {
          postcssOptions: {
            config: false,
          },
        },
      },
    ],
  },
};

String

允许指定配置文件的路径。

webpack.config.js

const path = require("path");

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

sourceMap

类型

type sourceMap = boolean;

默认值:取决于 compiler.devtool 的值

默认情况下,源映射的生成取决于 devtool 选项。除了 evalfalse 值之外,所有值都启用源映射生成。

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

替代设置

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 implementation = object;

implementation 的类型应与 postcss.d.ts 相同

默认:postcss

特殊的 implementation 选项决定使用哪个 PostCSS 实现。它会覆盖本地安装的 postcsspeerDependency 版本。

此选项仅对下游工具的作者有用,用于简化 PostCSS 7 到 8 的过渡。

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

示例

SugarSS

SugarSS 是一种基于空白的 PostCSS 语法。

你需要安装 sugarss

npm install --save-dev sugarss

使用 SugarSS 语法。

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

你需要安装 autoprefixer

npm install --save-dev autoprefixer

使用 autoprefixer 自动为 CSS 规则添加供应商前缀。

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",
                    {
                      // Autoprefixer options (optional)
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

[!警告]

postcss-preset-env 包含了 autoprefixer,因此如果你已经使用了该预设,则无需单独添加它。更多信息

PostCSS Preset Env

你需要安装 postcss-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

什么是 CSS Modules?请点击此处阅读

postcss-loader 端无需额外选项即可支持 CSS Modules。为了使其正常工作,需要添加 css-loaderimportLoaders 选项。

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 和 postcss-js

要处理用 JavaScript 编写的样式,你可以使用 postcss-js 作为解析器。

你需要安装 postcss-js

npm install --save-dev postcss-js

如果你想处理用 JavaScript 编写的样式,请使用 postcss-js 解析器。

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

结果是你可以以下列方式编写样式

import colors from "./styles/colors";

export default {
  ".menu": {
    color: colors.main,
    height: 25,
    "&_link": {
      color: "white",
    },
  },
};

[!警告]

如果你使用 Babel,你需要进行以下操作才能使设置生效

  1. babel-plugin-add-module-exports 添加到你的配置中。
  2. 每个样式模块只能有一个**默认**导出。

提取 CSS

要将 CSS 提取到单独的文件中,请使用 mini-css-extract-plugin

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

💡 使用此设置可以在生产环境中提取和缓存 CSS,同时在开发过程中保持快速的样式注入。

发出资源

要从 PostCSS 插件向 webpack 发出资源,需要在 result.messages 中添加一条消息。

消息应包含以下字段:

  • type = asset - 消息类型(必填,应等于 asset
  • file - 文件名(必填)
  • content - 文件内容(必填)
  • sourceMap - sourceMap
  • info - 资源信息

webpack.config.js

const postcssCustomPlugin = (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()],
              },
            },
          },
        ],
      },
    ],
  },
};

ℹ️ 这允许你的插件在构建过程中生成额外文件,Webpack 会像处理任何其他发出的资源一样处理它们。

添加依赖项、上下文依赖项、构建依赖项、缺失依赖项

这些依赖项对于 webpack 理解何时需要对更改的文件进行重新编译至关重要。

添加依赖项有两种方式:

  1. (推荐)插件可以在 result.messages 中发出消息。

消息应包含以下字段:

  • type = dependency - 消息类型(必填,应等于 dependencycontext-dependencybuild-dependencymissing-dependency
  • file - 绝对文件路径(必填)

webpack.config.js

const path = require("path");

const postcssCustomPlugin = (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()],
              },
            },
          },
        ],
      },
    ],
  },
};

💡 你可以使用现成的插件 postcss-add-dependencies 来简化此过程。

  1. 在插件中传递 loaderContext(适用于高级设置)。

webpack.config.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 配置管理动态导入或外部文件依赖时使用此方法。

postcss.config.js

通过 PostCSS api 对象传递 webpackLoaderContext

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

postcssCustomPlugin.js

使用 loaderContext.addDependency 注册文件依赖项

const path = require("path");

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

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

✅ 当你希望动态声明依赖项而无需依赖 `result.messages` 时,此方法是理想选择,特别是在更复杂的设置或共享插件配置中。

贡献

我们欢迎所有贡献!如果您是新用户,请在提交问题或拉取请求之前花一些时间阅读我们的贡献指南。

贡献

许可证

MIT