深入 Webpack5 等构建工具系列二(9) - postcss 在 webpack 中的使用

1,236 阅读5分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

上一篇文章最后,我们使用的是命令行工具来对 css 进行处理,但是,如果项目中有很多地方(文件)都用到了 css,而且这些 css 需要添加浏览器前缀,那我们再去命令行中每次都用工具转化就不现实了。这时,我们就可以借助 webpack,让 webpack 在加载 css 文件时先使用 postcss 将需要添加浏览器前缀的 css 样式添加上浏览器前缀,转换完之后再让 css-loader 进行处理。

需要声明的是,当前 test.css 文件中的样式在项目中是没有生效的,原因是这个 test.css 文件没有被项目中的任何地方使用过。那下面我们先在项目中使用这个文件。有两种方式可以选择,第一种是在 index.css 文件中引入 test.css,第二种是直接把 test.css 中的内容剪切到 index.css 中去。你可能会觉得直接引入(即这里的第一种方式)是更好的一种方式,但事实上这样做到时在处理时是会有问题的,具体我们待会再讲,下面我们先采取第二种方式(直接把 test.css 中的内容剪切到 index.css 中):

image-20210205220855188.png

index.css 是在 component.js(项目的入口文件是 main.jsmain.js 中已经引入了 component.js) 中被引入的:

image-20210205221517659.png

所以到时候运行项目也会去处理 index.css 中的样式代码啦。

但是这里有涉及到需要添加浏览器前缀的样式(比如:CSS 伪类 :fullscreenCSS 属性 user-select),而默认情况下,直接运行 npm run build 编译打包出来的代码是没有添加上浏览器前缀的,这个我们可以在浏览器中看到:

image-20210206070637411.png

但是,我们需要让样式加上浏览器前缀,那该怎么做呢?

我们可以来到 webpack 的配置文件(这里是 wk.config.js)中,修改 css 文件的匹配规则,在使用 css-loader 处理之前先使用 postcss 工具处理,那如何使用 postcss 工具做处理呢?这个时候,我们就需要另外一个 loader 了,叫做 postcss-loaderpostcss-loader 会自动去找 postcss 工具,找到之后就会使用这个 postcss 工具对样式进行处理,处理完后再依次交给 css-loaderstyle-loader 处理,那么最终生成的样式就会有浏览器前缀啦。

但目前项目中还没有 postcss-loader,所以我们先来安装它:

npm install postcss-loader -D

记住哦,使用 postcss-loader 的目的是为了让我们能在 webpack 中使用 postcss。(我们每安装一个工具,都要知道这个工具是什么作用哈)

安装好 postcss-loader 后,我们再去修改 css 文件的匹配规则,在 use 属性对应的数组最后新增 postcss-loader,如下图所示:

image-20210206074802170.png

那这样配置完以后真的会做处理吗?我们再来验证一下,运行 npm run build 命令对项目代码进行编译,然后来到浏览器页面,页面刷新后,效果如下:

image-20210206075707307.png

可以看到,并没有添加上浏览器前缀,也就是说当前 postcss 没有生效。这是为甚莫呢?我明明已经通过 postcss-loader 去使用 postcss 了呀,它怎么没生效呢?原因很简单,要想添加前缀,postcss 本身还需依赖别的插件,但现在我们还没有告诉 postcss 要依赖哪些插件,所以才不会生效。因此,我们修改配置如下:

image-20210206083445260.png

use: [
  // 注意:执行顺序(从下往上,从右往左,从后往前)
  'style-loader',
  'css-loader',
  {
    loader: 'postcss-loader',
    options: {
      postcssOptions: {
        plugins: [
          require('autoprefixer')
        ]
      }
    }
  }
],

我们把“postcss-loader”字符串修改为了 UseEntry 对象(深入 Webpack5 等构建工具系列二(4) - webpack 中 css-loader 的使用和 Rule 配置规则这篇文章中已讲过),里面对 loaderoptions 两个属性进行了设置。loader 属性的值设置为了 postcss-loader,意味着加载 postcss-loader;同时我们还需要传一些参数来告诉 loader 要加载的插件,那就需要设置 options 属性,options 属性的值会被传入到 loader 中,这里这个值是一个对象,对象中有个属性叫做 postcssOptions,这个属性对应的又一个对象。在这个对象里面就要真正开始配置 postcss 需要依赖的插件了。postcssOptions 对象中有一个 plugins 属性,对应一个数组(为甚莫是数组呢?因为可能会依赖多个插件,多个插件就可以放在数组中啦),里面可以放多个插件,因为我们现在需要依赖的插件是 autoprefixer,所以可以通过 require 的方式将它引入进来就可以啦。

总结一下上面修改的配置内容,当使用 postcss-loader 时,告诉它在使用 postcss 时要依赖 autoprefixer 这个插件。

下面,我们再运行 npm run build 命令对代码进行打包,然后来到浏览器页面,页面刷新后,效果如下:

image-20210206091826125.png

可以看到,:fullscreen 这个 CSS 伪类以及 user-select 这个 CSS 属性都已经加上浏览器前缀了。可见,当前 postcss 这个工具结合 autoprefixer 这个插件就已经生效啦。这就意味着,以后在项目中编写的任何 css,都不需要考虑要不要添加浏览器前缀的问题啦,因为经过配置,项目中已经通过 postcss-loader 引入的 postcss 加载的 autoprefixer 插件,给有需要的 css 样式自动添加上浏览器前缀啦。

当然,我们还可以尝试修改 .browserslistrc 文件中的查询条件后,重新打包查看样式效果:

image-20210206095310730.png

我们把要查询的浏览器的市场占有率为大于 1% 改为大于 0.1% 后(意味着条件变得更宽泛了,要适配的浏览器更多了),再来运行 npm run build,然后来到浏览器页面,页面刷新后,效果如下:

image-20210206100150844.png

可以看到,当我们要适配的浏览器更多了以后,对比之前的样式,这次 transition 这个 CSS 属性也加上了浏览器前缀。(之前要适配的浏览器都支持 transition,所以不需要添加浏览器前缀)

以上,就是关于添加浏览器前缀在 webpack 中的操作流程。重点需要清楚整个过程中安装的各个包的作用,以及在 webpack 配置文件(这里是 wk.config.js)中的相关配置。