Webpack postcss-loader

2023-05-20 17:54 更新

npm   node   tests   coverage  

Webpack chat:  chat

PostCSS chat:  chat-postcss

使用 PostCSS 處理 CSS 的 loader。

快速開始

如果要使用最新版本的話,你需要使用 webpack v5。如果使用 webpack v4 的話,你需要安裝 postcss-loader v4。

為了使用本 loader,你需要安裝 postcss-loader 和 postcss:

npm install --save-dev postcss-loader postcss

然后添加本 loader 的相關(guān)配置到你的 webpack 的配置文件。例如:

在以下配置中使用了 postcss-preset-env 插件,該插件并非默認(rèn)安裝。

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',
                    {
                      // 其他選項
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

或者使用 PostCSS 本身的 配置文件:

postcss.config.js

module.exports = {
  plugins: [
    [
      'postcss-preset-env',
      {
        // 其他選項
      },
    ],
  ],
};

Loader 將會自動搜索配置文件。

webpack.config.js

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

最后,通過你喜歡的方式運行 webpack。

選項

名稱 類型 默認(rèn)值 描述
execute {Boolean} undefined 在 CSS-in-JS 中啟動 PostCSS Parser 支持
postcssOptions {Object|Function} Postcss.process的默認(rèn)值 設(shè)置 PostCSS 選項與插件
sourceMap {Boolean} compiler.devtool 開啟 / 關(guān)閉 source map 的生成
implementation {Function|String} postcss 為 PostCSS 設(shè)置對應(yīng)實現(xiàn)并使用

execute

類型:?Boolean? 默認(rèn)值:undefined

如果你在 JS 文件中編寫樣式,請使用 postcss-js parser,并且添加 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

類型:?Object|Function? 默認(rèn)值:undefined

允許設(shè)置 PostCSS 選項 和插件。

支持所有的 PostCSS 選項。 這是配置文件中特殊的 配置 選項。它如何工作、如何配置再接下來的部分將會有詳細(xì)的描述。

因為可能會導(dǎo)致 source map 中錯誤的文件路徑,我們不推薦使用指定的 from、to 和 map 選項。 如果你需要 source map,請使用 sourcemap 選項。

Object

設(shè)置 plugins:

webpack.config.js (recommended)

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 }),
              // 廢棄的,將會在下一個主要版本中移除
              { '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' },
            },
          },
        },
      },
    ],
  },
};

設(shè)置 syntax:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            // 可以是 `String`
            syntax: 'sugarss',
            // 可以是 `Object`
            syntax: require('sugarss'),
          },
        },
      },
    ],
  },
};

設(shè)置 parser:

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            // 可以是 `String`
            parser: 'sugarss',
            // 可以是 `Object`
            parser: require('sugarss'),
            // 可以是 `Function`
            parser: require('sugarss').parse,
          },
        },
      },
    ],
  },
};

設(shè)置 stringifier:

webpack.config.js

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

module.exports = {
  module: {
    rules: [
      {
        test: /\.sss$/i,
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            // 可以是 `String`
            stringifier: 'sugarss',
            // 可以是 `Object`
            stringifier: require('sugarss'),
            // 可以是 `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

類型:?Boolean|String? 默認(rèn)值:undefined

允許使用配置文件設(shè)置選項。 在配置文件中指定的選項將會和 loader option 進行合并,并且 loader option 將會覆蓋配置文件中的選項。

配置文件

Loader 將會從下面幾個地方搜索目錄樹來尋找配置文件:

  • ?package.json? 中的 postcss 屬性
  • JSON 或者 YAML 格式的 .postcssrc 文件
  • .postcss.json、.postcss.yaml、.postcss.yml、.postcss.js 或者 .postcss.cjs 文件
  • postcss.config.js 或者 postcss.config.cjs 導(dǎo)出一個對象的 CommonJS 模塊(推薦)
配置文件示例

使用 Object:

postcss.config.js(推薦)

module.exports = {
  // 你可以指定下面提到的所有選項 https://postcss.org/api/#processoptions
  // parser: 'sugarss',
  plugins: [
    // PostCSS 插件
    ['postcss-short', { prefix: 'x' }],
    'postcss-preset-env',
  ],
};

使用 Function:

postcss.config.js(推薦)

module.exports = (api) => {
  // `api.file` - 文件路徑
  // `api.mode` - webpack 的 `mode` 屬性值,請查閱 https://webpack.js.org/configuration/mode/
  // `api.webpackLoaderContext` - 在復(fù)雜情況下使用的 loader 上下文
  // `api.env` - `api.mode` 的別名,與 `postcss-cli` 兼容
  // `api.options` - `postcssOptions` 的選項

  if (/\.sss$/.test(api.file)) {
    return {
      //你可以指定下面提到的所有選項 https://postcss.org/api/#processoptions here
      parser: 'sugarss',
      plugins: [
        // PostCSS 插件
        ['postcss-short', { prefix: 'x' }],
        'postcss-preset-env',
      ],
    };
  }

  return {
    // 你可以指定下面提到的所有選項 https://postcss.org/api/#processoptions
    plugins: [
      // PostCSS 插件
      ['postcss-short', { prefix: 'x' }],
      'postcss-preset-env',
    ],
  };
};

postcss.config.js(廢棄的,將會在下一個主要版本中移除)

module.exports = {
  // 你可以指定下面提到的所有選項 https://postcss.org/api/#processoptions
  // parser: 'sugarss',
  plugins: {
    // PostCSS 插件
    'postcss-short': { prefix: 'x' },
    'postcss-preset-env': {},
  },
};
配置級聯(lián)

你可以在不同的目錄中使用不同的 postcss.config.js 文件。 配置文件的尋找從 path.dirname(file) 開始根據(jù)文件樹向上尋找,直至找到一個配置文件。

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

在設(shè)置 postcss.config.js 之后,將 postcss-loader 添加到 webpack.config.js 中。 你可以單獨使用它,或者與 css-loader 結(jié)合使用(推薦)。

在 css-loader 和 style-loader 之前使用它,但是在其他預(yù)處理器(例如:sass|less|stylus-loader)之后使用 (因為 webpack loader 從右到左 / 從底到頂執(zhí)行)。

webpack.config.js (推薦)

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

Boolean

開啟 / 關(guān)閉自動加載配置。

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

類型:?Boolean? 默認(rèn)值:依賴于 compiler.devtool 的值

默認(rèn)情況下 source map 的生成依賴于 devtool選項。 除 eval 和 false 外,其他的值都將打開 source map 生成。

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

替代設(shè)置:

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

類型:?Function | String? 默認(rèn)值:postcss

特殊的 implementation 選項決定使用 PostCSS 哪個實現(xiàn)。重載本地安裝的 postcss 的 peerDependency 版本。

此選項只對底層工具的作者有效,以便于 PostCSS 7 到 PostCSS 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:

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 添加廠商前綴。

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',
                    {
                      // 選項
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};
?? postcss-preset-env 包含 autoprefixer,因此如果你已經(jīng)使用了 preset 就無需單獨添加它了。

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',
                    {
                      // 選項
                    },
                  ],
                ],
              },
            },
          },
        ],
      },
    ],
  },
};

CSS Modules

在 postcss-loader 中沒有額外的設(shè)置。 為了使他們正常工作,請?zhí)砑?nbsp;css-loader 的 importLoaders 選項。

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

你需要安裝 ?postcss-js?:

npm install --save-dev postcss-js

如果你想處理寫在 JavaScript 中的樣式,那么你需要使用 postcss-js parser。

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且為了程序正常工作,你需要進行下面的步驟:
添加 babel-plugin-add-module-exports 到你的配置中。你需要在每一個樣式模塊中有一個默認(rèn)導(dǎo)出。

提取 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',
    }),
  ],
};

觸發(fā)資源打包

要將資源從 PostCSS 插件寫到 webpack,需要向 result.messages 中添加一條消息。

一條符合規(guī)范的消息應(yīng)該包含下面的字段:

  • type = asset - 消息類型(必需字段,并且應(yīng)該為 asset)
  • file - 文件名稱(必需)
  • content - 文件內(nèi)容(必需)
  • sourceMap - sourceMap
  • info - 資源信息

webpack.config.js

const customPlugin = () => (css, result) => {
  result.messages.push({
    type: 'asset',
    file: 'sprite.svg',
    content: '<svg>...</svg>',
  });
};

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

添加 dependencies、contextDependencies、buildDependencies、missingDependencies

當(dāng)需要在文件變化時進行重新編譯時,webpack 為了理解這樣的操作需要添加必要的依賴。

由兩種方式添加依賴:

  1. (推薦)。插件在 result.messages 中觸發(fā)消息。

消息應(yīng)該包含下面兩個字段:

  • type = dependency - 消息類型(必需字段,并且應(yīng)該為 dependency、context-dependency、build-dependency 或 missing-dependency)
  • file - 文件的絕對路徑(必需)

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

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

customPlugin.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);

貢獻

如果你還沒有讀過我們的貢獻指南,請花一點時間閱讀它。

License

MIT


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號