webpack 對 css 壓縮中對前綴的處理

在 vue-cli 建立的項目中,用默認的 webpack 配置對項目打包後,發現 css 文件中樣式的前綴有所缺失,例如:flex 這個應該有前綴的屬性卻沒有(display:-webkit-flex; && -webkit-flex:1),致使樣式在 iphone 6s plus 上出現了兼容問題。css

postcss 對 css 的前綴是有處理功能的,在項目的默認配置中,會根據各個瀏覽器最新兩個版本的支持狀況去添加前綴的,而如今瀏覽器都應該能很好地支持 flex 了,因而,便再也不加前綴。對此,咱們能夠作以下處理:html

//vue-loader.config.js

......
module.exports = {
 ......
  postcss: [
    require('autoprefixer')({ browsers: ['last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie > 8'] })
  ]
}

 

通過以上處理,打包後的 css 應該就擁有合適的前綴了,但並不如此,緣由是在打包過程當中,css 有個壓縮動做,在這個動做中,壓縮插件(用的是 optimize-css-assets-webpack-plugin 這個插件)會再一次對 css 的前綴作處理,會將它認爲不須要的代碼(如不須要的 css 前綴)去掉。由於前面已經用 postcss 對 css 的前綴作過處理,因此在這裏對 css 前綴的處理是多餘的,咱們能夠作以下處理:vue

// webpack.prod.config.js

......
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

......

new OptimizeCSSPlugin({
    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
    //cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true }
}),

......

 

再次打包後,你會發現你想要的前綴出現了。webpack

 

即使如此作了,你發現 -webkit-flex:1 這個仍是沒有出現,因而有了下面這個文件ios

const fs = require('fs');
const path = require('path');
const config = require('../config/index.js');


function resolve(dir) {
    return path.join(__dirname, '..', dir)
}

function changeFile(obj) {
    fs.readFile(obj.changeFile, function(err, data) {
        if (err) {
            throw err;
        } else {
            var dataStr = data.toString();
            // dataStr = dataStr.replace(obj.olddisplayflex, ';display:-webkit-flex;display:flex');
            dataStr = dataStr.replace(obj.oldflxe, function() {
                var source = arguments[0];
                var flexNum = source.match(/\d+/)[0];
                var str = ';-webkit-flex:' + flexNum + ';flex:' + flexNum;
                return str;
            });
            fs.unlink(obj.changeFile, function(err) {
                if (err) {
                    throw err
                } else {
                    fs.writeFile(obj.changeFile, dataStr, function(errs) {
                        if (errs) {
                            throw errs
                        } else {
                            var cssNam = obj.changeFile.split('/');
                            console.log('\x1B[32m%s\x1B[39m', '樣式 flex 修改爲功--------' + cssNam[cssNam.length - 1]);
                        }
                    });
                }
            })
        }
    });
}

// 由於每次打包,css 的文件名都不同,因此經過遍歷文件夾來找到 css 文件 function getFile(obj) { fs.readdir(obj.changeFile, function(err, files) {
if (err) { throw err; } else { files.forEach(function(item) { if (/(css)$/.test(item)) { obj.changeFile = obj.changeFile + item; changeFile(obj); } }); } }); } var webkit = { changeFile: config.build.assetsRoot + '/' + config.build.assetsSubDirectory + '/css/', //resolve('/farm/static/css/'), oldflxe: /;+\s*flex\:\s*\d+/g, olddisplayflex: /;+\s*display\:\s*flex/g } var webkitHtml = { changeFile: config.build.assetsRoot + '/index.html', //resolve('/farm/index.html'), oldflxe: /;+\s*flex\:\s*\d+/g, olddisplayflex: /;+\s*display\:\s*flex/g } function cssFix() { getFile(webkit); changeFile(webkitHtml); } module.exports = cssFix;

這個代碼是在 npm run build 以後運行的,其做用就是給須要添加 -webkit-flex:x 的地方加上這個。web

這個也是無奈之下不得已而爲之,我會繼續尋找別的更好的方法,以後再更新了。vue-cli

 

2018.10.22 更新:使用 vue-cli 3.0 建立項目,這個問題解決了。npm

相關文章
相關標籤/搜索