当前位置:

postcss-loader 失效的原因

访客 2024-04-23 1484 0

项目场景

很久之前在webpack中使用postcss-loader遇到了失效的问题。
最近刚好也遇到了,顺便将解决方案以及出现问题的原因做一个记录。


问题描述

首先,在平时的开发中,我们会对一些css文件进行处理,比如添加前缀排序等。
那我们最常见的一段代码如下:

/*reset.css*/@charset"utf-8";*{transition:all0.3s;user-select:none;}//webpack.config.jsmodule.exports={//......module:{rules:[{test:/\.css$/,use:['style-loader','css-loader','postcss-loader']}]}}

正常打包后,出现的css代码一般会长成如下这样

*{transition:all0.3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}

异常情况

但是天有不测风云,如果当前css文件通过@import语法导入了另一个css文件,这时再去打包就会发现,postcss失效了。
比如,在index.css文件中导入reset.css,然后对index.css进行打包

/*index.css*/@charset"utf-8";@import'reset.css';

打包后的结果如下

是的,长得和源文件一模一样。


原因分析

要分析产生这个问题的原因,必须要知道loader执行的顺序以及每个loader大概要做的事情。

过程分析

1、首先,webpack通过入口文件开始爬文件进行打包,此时会识别到文件对index.css有依赖。由于配置过关于css文件的loader使用规则,index.css首先会被交给postcss-loader进行处理

2、当postcss-loader在对css进行处理时,它主要功能是将css文件内的css代码进行处理,而不会执行css文件内部的代码。也就是说,css文件中的@import语法,此时并不会执行。

3、postcss-loader处理完成后,会将已经具备兼容性前缀的css代码再交给css-loader进行处理。此时,文件中的@import就被执行了,reset.css中的代码开始进入index.css
但很可惜,这一步已经晚了,因为postcss-loader已经下班了。换句话说,默认情况下,loader的执行顺序是单向的,index.css文件已经被postcss-loader处理完毕,不会回头再去处理一遍。

4、css-loader执行完毕,再交给style-loader进行样式注入。

原因

根据以上对执行过程的分析,其实可以发现,导致这个问题产生的原因是:

  • css文件中的@import语法,在postcss-loader处理时并不会执行
  • loader不会逆向进行处理

解决方案

总结:使用importLoaders属性将文件再交给postcss-loader处理

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

importLoaders的意思是,如果在这个css文件中有@import进来的文件,那这些文件将交给前nloader进行处理。

此处我们需要将新文件交给前一个loader,也就是postcss-loader来处理,所以它的值为1

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~