如何让postcss-loader、postcss-cssnext与sass-loader在Webpack中协同工作?
问题:PostCSS cssnext的gray()函数输出为空值
我针对SCSS/CSS文件的Webpack配置如下:
... { test: /\.s?css$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 2 } }, { loader: 'postcss-loader', options: { ident: 'postcss', plugins: loader => [ require('postcss-import')({ root: loader.resourcePath }), require('cssnano')(), require('postcss-cssnext')(), ] } }, 'sass-loader', ] } ...
遇到的问题是:当我使用cssnext的gray(100)这类函数时,输出的CSS文件中该函数位置的值为空。例如background-color: gray(100);会被输出为background-color: ;。我是PostCSS新手,不太清楚它的工作原理及正确配置方式,想知道问题出在哪里。
问题根源:插件执行顺序搞反了
兄弟,你这个问题其实是PostCSS插件的执行顺序不对导致的。PostCSS的插件是按照你在数组里写的顺序依次执行的,你现在把cssnano放在了postcss-cssnext前面,这就出问题了:
cssnano是用来压缩优化CSS的,它识别不了还没被postcss-cssnext转译的gray()函数,直接把它当成无效值删掉了,所以最后输出就变成空的了。- 正确的顺序应该是先让
postcss-cssnext把这些未来语法(比如gray())转译成浏览器能识别的普通CSS,再交给cssnano去压缩。
修复方案:调整插件执行顺序
把postcss-cssnext移到cssnano前面,修改后的postcss-loader配置如下:
{ loader: 'postcss-loader', options: { ident: 'postcss', plugins: loader => [ require('postcss-import')({ root: loader.resourcePath }), require('postcss-cssnext')(), // 先转译cssnext语法 require('cssnano')(), // 再压缩优化 ] } }
另外再给你两个小建议,帮你避免后续踩坑:
- PostCSS插件的顺序很关键,预处理类的插件(比如转译语法、补全前缀)要放在压缩类插件前面,不然压缩插件会把未处理的语法当成垃圾删掉。
- 如果你用的是较新版本的PostCSS,其实
postcss-cssnext已经被废弃了,官方推荐用postcss-preset-env来替代它,它包含了cssnext的所有功能,还支持更多现代CSS特性,你可以后续试试迁移过去。
内容的提问来源于stack exchange,提问作者hwkd
相关产品推荐
相关产品推荐

