webpack的css壓縮不兼容IOS8問題探索
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
webpack的css壓縮不兼容IOS8問題探索