「Webpack 基础」CSS loader配置解读

4,797 阅读2分钟

作为一个前端开发,离不开webpack打包。webpack 内容比较多,本篇主要对常用的 CSS 相关的 loader 进行系统解读。

在使用webpack打包的时候,需要使用一堆跟css相关的loader,这些loader都有什么用呢,怎么配置这些loader呢?

1. css-loader

css-loader 用来处理 CSS 文件,会对 @importurl() 进行处理,就像 js 解析 import/require() 一样

  • 安装 css-loader
npm install --save-dev css-loader
  • webpack.config.js中添加配置
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['css-loader'],
      },
    ],
  },
};

webpack 先用 css-loader 加载器去解析后缀为.css 的文件,遇到@import/url()等语句就将相应样式文件引入(所以如果没有 css-loader,就没法解析这类语句),最后使用 style-loader 生成一个解析完的 css 代码的 <style> 标签,放到 html 文件的 <head> 标签里。(生产环境建议使用MiniCssExtractPlugin.loader 替代style-loader,将 css 资源分离到单独的文件)

2. style-loader

style-loader 把 js 中 import 导入的样式文件代码,打包到 js 文件中,运行 js 文件时,将样式自动插入到<style>标签中。建议将 style-loader 与 css-loader 结合使用

  • 安装style-loader
npm install style-loader --save-dev
  • 修改webpack.config.js配置
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

loader 是有顺序的,webpack 先将所有 css 模块依赖解析完得到计算结果再创建 <style> 标签。因此应该把 style-loader 放在 css-loader 的前面(webpack loader 的执行顺序是从后到前)

3. sass-loader

sass-loader 加载 Sass/SCSS 文件并将他们编译为 CSS。项目中使用less文件编写样式的,需要安装less-loader

  • 安装sass-loader,需要同时安装node-sass到开发依赖
npm install sass-loader node-sass --save-dev
  • 修改webpack.config.js配置
module.exports = {
  module: {
    rules: [
      {
        test: /\.(c|sa|sc)ss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
};

sass-loadercss-loaderstyle-loader 进行链式调用,可以使用style-loader将样式以 <style> 标签的形式插入 DOM 中,或者使用 mini-css-extract-plugin 将样式输出到独立的文件中。

4. postcss-loader

postcss-loader可以让 css 自动加上兼容性前缀,详见PostCSS 及其常用插件

  • 安装postcss-loader
npm install postcss-loader --save-dev
  • 修改webpack.config.js配置
module.exports = {
  module: {
    rules: [
      {
        test: /\.(c|sa|sc)ss$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: (loader) => [require('autoprefixer')()],
            },
          },
          'sass-loader',
        ],
      },
    ],
  },
};

5. MiniCssExtractPlugin.loader

使用 MiniCssExtractPlugin.loader 来分离 css 样式。把 js 中 import 导入的样式文件代码,打包成一个实际的 css 文件,结合 html-webpack-plugin,在 dist/index.html 中以 link 插入 css 文件;默认将 js 中 import 的多个 css 文件,打包时合成一个

  • 安装 mini-css-extract-plugin
npm install mini-css-extract-plugin --save-dev
  • 修改webpack.config.js配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // 类似 webpackOptions.output里面的配置 可以忽略
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(c|sa|sc)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: (loader) => [require('autoprefixer')()],
            },
          },
          'sass-loader',
        ],
      },
    ],
  },
};

mini-css-extract-plugin不能与style-loader混用,会冲突。建议 mini-css-extract-plugin 与 css-loader 一起使用。

6. px2rem-loader

px2rem-loader用于移动端适配,自动将 px 转换成 rem

  • 安装px2rem-loader
npm install px2rem-loader --save-dev
  • webpack.config.js中添加配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // 类似 webpackOptions.output里面的配置 可以忽略
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(c|sa|sc)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: (loader) => [require('autoprefixer')()],
            },
          },
          {
            loader: 'px2rem-loader',
            options: {
              remUni: 75, // 按设计稿750的十分之一计算
              remPrecision: 8, // 计算的精确度到小数点后8位
            },
          },
          'sass-loader',
        ],
      },
    ],
  },
};