Vue 项目之 Webpack 中 PostCSS 工具的使用(2)

2,482 阅读2分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

1. postcss-loader 的使用

真实开发中,我们必然不会直接使用命令行工具来对 css 进行处理,而是会借助构建工具来实现,在 webpack 中,使用 PostCSS 就是通过使用 postcss-loader 来实现的。

比如我们现在修改项目中的 ./src/css/style.css 文件的内容,添加 user-select 属性的设置:

.title {
  color: red;
  font-size: 30px;
  font-weight: 700;

  user-select: none;
}

我们希望待会打包后,能给这个 user-select 属性添加上浏览器前缀。我们先来运行 npm run build 命令打包,看下效果:

image-20211106141607825

可以看到,在默认情况下(没有告诉 webpack 去使用 PostCSS),webpack 是不会给 css 属性添加浏览器前缀的。

如果我们想让 webpack 打包后给 css 属性添加上浏览器前缀,就需要在 webpack 加载 css 文件时,增加使用 postcss-loader 进行处理。因此,我们先来安装 postcss-loader

npm install postcss-loader -D

注意:postcss-loader 依赖 postcss,所以还需要安装 postcss,但前面我们已经安装过了,所以这里没有再进行安装。postcss-loader 的作用是为了在 webpack 中去使用 postcss

然后打开 webpack.config.js,修改如下:

...

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader' // 添加 postcss-loader 对 css 文件进行处理
        ]
      },
      ...
    ]
  }
}

再来运行 npm run build 命令打包,查看页面效果,你会发现,user-select 属性仍然没有添加上浏览器前缀。原因我们前面其实已经说过了,要想让 PostCSS 真正生效,必须给它指定要使用哪些插件,而我们这里还没有指定要使用的 PostCSS 插件。因此,我们需要在使用 postcss-loader 时,指定要使用的 PostCSS 插件,webpack.config.js 中的内容修改如下:

...

module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader', // 添加 postcss-loader 对 css 文件进行处理
            options: {
              postcssOptions: { // 设置 PostCSS 选项和插件
                plugins: [
                  require('autoprefixer') // 使用 autoprefixer 插件
                ]
              }
            }
          }
        ]
      },
      ...
    ]
  }
}

配置完成后,再来运行 npm run build 命令打包,查看页面效果:

image-20211106145353378

可以看到,这次成功添加上浏览器前缀了。

但是,你可能会觉得直接把这些关于 PostCSS 的配置项写在 webpack.config.js 中,看起来太多了,能不能把这些配置信息抽取出去呢?答案是可以的,我们可以在项目目录下新建 postcss.config.js 文件,然后将 webpack.config.js 中想要抽取的配置信息(其实就是 postcssOptions 中的内容)转移到这个文件中,写法如下:

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

这样一来,我们在 webpack.config.js 中对 PostCSS 的配置就可以去掉了,直接使用 postcss-loader 即可:

...

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

抽取了 PostCSS 的配置文件之后,webpackpostcss-loader 的解析过程是这样的:先看一下 webpack 的配置文件中有没有 PostCSS 的配置信息,如果没有,就会来到当前目录下查找 postcss.config.js 或者 postcss.config.cjs 文件,找到后会查看该配置文件中是否有导出一个对象,如果有导出对象,就会将这个导出对象的内容当做 PostCSS 的配置信息。

如果既在 webpack 的配置文件中的加载器选项中写了 PostCSS 的配置信息,又使用了 PostCSS 的配置文件,那么两个地方的配置信息会进行组合,并且加载器选项中的配置优先级更高(加载器选项中的配置会覆盖配置文件中的配置)。

事实上,在配置 postcss-loader 时,我们配置插件并不需要使用 autoprefixer,我们通常会使用另外一个插件:postcss-preset-env

  • PostCSS Preset Env 也是一个 PostCSS 插件;
  • 它可以帮助我们将一些现代的 CSS 特性,转成大多数浏览器认识的 CSS,并且会根据目标浏览器或者运行时环境添加所需的 polyfill
  • 也包括会自动帮助我们添加 autoprefixer,即它已经内置了 autoprefixer

要使用 postcss-preset-env,我们需要先安装它:

npm install postcss-preset-env -D

然后,我们直接用 postcss-preset-env 替换掉之前的 autoprefixer 即可:

plugins: [
  require('postcss-preset-env')
]

运行 npm run build 命令打包后,浏览器中的效果和之前是一样的。但这个插件相比于 autoprefixer 更加强大,举个例子,我们修改 ./src/css/style.css 中的代码如下:

.title {
  color: #12345678; // 使用 8 位十六进制数的颜色值
  font-size: 30px;
  font-weight: 700;

  user-select: none;
}

以前,我们可以使用 6 位的十六进制数来表示某种颜色,而现在,CSS 的新特性中已经可以用 8 位十六进制数来表示颜色了,多出来的最后两位代表的是透明度。所以,我们现在可以写 8 位的十六进制数来设置颜色,但目前,有些浏览器还不支持这种格式,那就意味着我们需要将这种格式转换成普通的 RGBA 格式。如果我们使用的是 autoprefixer 插件,它不会帮助我们进行转换,但我们现在使用的是 postcss-preset-env 插件,它就能自动帮我们将 8 位十六进制格式转换成 RGBA 格式。上面的 color: #12345678 转换后的结果如下:

image-20211106160728729

补充:

  1. 我们在使用某些 postcss 插件时,也可以直接传入字符串:
module.exports = {
  plugins: [
    'postcss-preset-env'
  ]
}
  1. 在编写 cssless 类型文件的处理规则对象时,我们也可以合起来写:
...
	
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.(css|less)$/i,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      }
    ]
  }
}

最后,再来总结一下 PostCSS 这个工具的特性:

  • PostCSS 是一个JS 插件转换样式的工具;
  • 这些插件可以检查(lint)你的 CSS,支持变量和混入(mixins),编译尚未被浏览器广泛支持的先进的 CSS 语法,内联图片,等等;