webpack 使用 postCSS 的 autoprefixer 插件, 并在压缩 css 时使用了 cssnano, 处理不当的情况下会导致压缩 css 后, 部分兼容前缀 (比如 - webkit-) 被删除的问题.
postcss 的 autoprefixer 配置如下:
- autoprefixer({
- browsers: ['> 1%', 'iOS>= 7',"ie>= 7", 'Android>= 2.4']
- })
css 压缩的配置如下:
- // 压缩 css 代码
- new OptimizeCssAssetsPlugin({
- assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
- cssProcessor: require('cssnano'),
- cssProcessorOptions: {
- discardComments: {removeAll: true },
- // 避免 cssnano 重新计算 z-index
- safe: true
- },
- canPrint: true
- })
通过查阅资料发现, 如果你使用的是 webpack1.x 版本, UglifyJsPlugin 这个插件开启了 minimize, 导致 css-loader 也开启了压缩, 然后 css-loader 会使用 cssnano 进行压缩, 而 cssnano 会使用到 autoprefixer 进行无关前缀的清理. 所以可以通过给 css-loader 添加 - autoprefixer 参数来告诉 css-loader 关闭掉 autoprefixer 这个功能, 不要强制删除某些你觉得不重要的前缀.
{test: /\.less$/, loader: 'style-loader!css-loader?minimize&-autoprefixer!postcss-loader!less-loader'},
而上述原因已经在 webpack2.x 修复, webpack2 的 UglifyJsPlugin 插件去掉了强制开启 minimize.
然而如果你不是使用的 webpack1.x, 通过排查发现, 在 css 压缩插件未使用的时候, 兼容前缀正常, 一旦使用了 OptimizeCssAssetsPlugin 来压缩 css 就会丢失部分的 webkit 前缀.
上面有提到, cssnano 会使用 autoprefixer 自动清除掉一些他认为不重要的前缀. 而 OptimizeCssAssetsPlugin 中默认了是使用 cssnano. 所以我们主动关闭 cssnano 的 autoprefixer 功能即可, 因为我们已经在 postcss 中使用了 autoprefixer 插件, 这里无需重复使用.
解决方法如下:
- // 压缩 css 代码
- new OptimizeCssAssetsPlugin({
- assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
- cssProcessor: require('cssnano'),
- cssProcessorOptions: {
- discardComments: {removeAll: true },
- // 避免 cssnano 重新计算 z-index
- safe: true,
- //cssnano 通过移除注释, 空白, 重复规则, 过时的浏览器前缀以及做出其他的优化来工作, 一般能减少至少 50% 的大小
- //cssnano 集成了 autoprefixer 的功能. 会使用到 autoprefixer 进行无关前缀的清理. 默认不兼容 ios8, 会去掉部分 webkit 前缀, 比如 flex
- // 所以这里选择关闭, 使用 postcss 的 autoprefixer 功能
- autoprefixer: false
- },
- canPrint: true
- })
再次编译发现压缩状态时也带有全部的兼容前缀, ios8 的不兼容问题即也解决.
参考:
- http://www.css88.com/archives/7317
- https://github.com/ShowJoy-com/showjoy-blog/issues/31
- https://www.w3cplus.com/css/taobao-2018-year.html
来源: https://www.cnblogs.com/saysmy/p/9021598.html