「这是我参与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 命令打包,看下效果:
可以看到,在默认情况下(没有告诉 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 命令打包,查看页面效果:
可以看到,这次成功添加上浏览器前缀了。
但是,你可能会觉得直接把这些关于 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 的配置文件之后,webpack 对 postcss-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 转换后的结果如下:
补充:
- 我们在使用某些
postcss插件时,也可以直接传入字符串:module.exports = { plugins: [ 'postcss-preset-env' ] }
- 在编写
css和less类型文件的处理规则对象时,我们也可以合起来写:... module.exports = { ... module: { rules: [ { test: /\.(css|less)$/i, use: [ 'style-loader', 'css-loader', 'postcss-loader', 'less-loader' ] } ] } }
最后,再来总结一下 PostCSS 这个工具的特性:
PostCSS是一个用JS插件转换样式的工具;- 这些插件可以检查(
lint)你的CSS,支持变量和混入(mixins),编译尚未被浏览器广泛支持的先进的CSS语法,内联图片,等等;