vue-cli 解决白屏、兼容、压缩及清除console

问题

  • 打包白屏
  • IE白屏
  • 打包后清除控制台所有console信息
  • js\css压缩问题

解决

问题1. 打包白屏

描述
npm run build打包后,生成dist文件夹。从该文件夹打开dist/index.html页面,发现页面空白,且控制台报错。原因是路径配置有问题。
方案
根目录打开/新建vue.config.js,配置路径:

module.exports = {
  // 基本路径配置
  publicPath: './'
}

重新打包验证,问题得以解决。

问题2. IE白屏

描述
在打包完成之后,如果是pc项目,或者移动端低版本兼容项目,则会有许多问题,其中白屏问题困扰着很多开发者,在安卓4.0、IE多个版本环境中体现的尤为别致。
方案

  1. 下载相关插件
npm install @babel/core @babel/plugin-transform-runtime @babel/preset-env es6-promise babel-polyfill --save-dev-dev
  1. 根目录新建文件.babelrc
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}
*[注: 基于vue-cli 3.x]*
  1. 修改根目录下的文件babel.config.js
// ... some other codes

// 打包时删除console
const plugins = [];
if (['production', 'prod'].includes(process.env.NODE_ENV)) {
  plugins.push("transform-remove-console")
}

module.exports = {
  presets: [
    [
      '@vue/app',
      {
        "useBuiltIns": "entry",
        polyfills: [
          'es6.promise',
          'es6.symbol'
        ]
      }
    ]
  ],
  
  plugins: plugins
}
  1. 创建/修改根目录下的文件vue.config.js
module.exports = {
    // 显式转义依赖
    transpileDependencies: ['webpack-dev-server/client'],
    
    chainWebpack: config => {
            // 指定入口  es6转es5
            config.entry.app = ['babel-polyfill', './src/main.js'];
    }
}
  1. 入口引入相关插件src/main.js
// 解决ie白屏问题
import '@babel/polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()

  1. 重启服务/重新打包
    页面正常显示,控制台无报错信息。问题解决。

问题3. 打包后清除控制台所有console信息

描述
在开发环境中,我们调试过程中会添加些许的console.log或者debugger相关代码,来帮助我们完成开发。但是有时候此类代码太多或者马虎了,上线前没有删除干净,那么打包后生产环境中就会在控制台留下相关信息。那么为了避免这一不友好行为,我们采取插件来在打包时,清除所有打印信息。
方案

  1. 安装插件
npm install uglifyjs-webpack-plugin --save-dev
  1. 配置vue.config.js
// 去除console
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

const env = process.env.NODE_ENV;

module.exports = {
    // ... other codes

    // 去除console
    configureWebpack: (config) => {
        if (env !== 'development' || env !== 'test') {

            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true, // 注释console
                            drop_console: true,
                            pure_funcs:['console.log'] // 移除console
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                }),
            );
        }
    },
}
  1. 重新打包
    配置完成后,重新打包npm run build,打开dist/index.html验证,console全部清除。

问题4. js\css压缩问题

描述
在打包成功后,为了缩小包体积,提高页面响应速度,一般会对包进行压缩,此处主要针对js\css来处理。
方案

  1. 安装插件
npm install compression-webpack-plugin --save-dev
  1. 配置vue.config.js中的configureWebpack
// 压缩css、js
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// 要压缩的文件
const productionGzipExtensions = ['js', 'css'];

configureWebpack: (config) => {
    if (env !== 'development' || env !== 'test') {
        config.plugins.push(new CompressionWebpackPlugin({
            algorithm: 'gzip',
            test: new RegExp(`\\.(${productionGzipExtensions.join('|')})$`),
            threshold: 10240,
            minRatio: 0.8,
        }));
    }
}
  1. 重启服务
    完成陪之后重启服务/重新打包,处理完成,搞定收工!

附赠

这里附上基于vue-cli3的一些简单配置文件

vue.config.js

const path = require('path');

const resolve = dir => path.resolve(__dirname, dir);

// const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);

// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;





// 去除console
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
// 压缩css、js
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// 要压缩的文件
const productionGzipExtensions = ['js', 'css'];
// const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;


const env = process.env.NODE_ENV;


module.exports = {
    // 基本路径配置
    publicPath: './',

    // 显式转义依赖
    transpileDependencies: ['webpack-dev-server/client'],

    // 配置less
    css: {
        loaderOptions: {
            less: {
                javascriptEnabled: true,
            }
        }
    },

    configureWebpack: (config) => {
        if (env !== 'development' || env !== 'test') {
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: 'gzip',
                test: new RegExp(`\\.(${productionGzipExtensions.join('|')})$`),
                threshold: 10240,
                minRatio: 0.8,
            }));
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        compress: {
                            warnings: false,
                            drop_debugger: true, // 注释console
                            drop_console: true,
                            pure_funcs:['console.log'] // 移除console
                        },
                    },
                    sourceMap: false,
                    parallel: true,
                }),
            );
        }
    },

    chainWebpack: config => {
        // 指定入口  es6转es5
        config.entry.app = ['babel-polyfill', './src/main.js'];

        // 修复HMR
        config.resolve.symlinks(true);

        // //修复 Lazy loading routes Error
        // config.plugin('html').tap(args => {
        //     args[0].chunksSortMode = 'none';
        //     return args;
        // });

        // 添加别名
        config.resolve.alias
            .set('@', resolve('src'))
            .set('assets', resolve('src/assets'))
            .set('static', resolve('src/static'));

        // //压缩图片
        // config.module
        //     .rule("images")
        //     .use("image-webpack-loader")
        //     .loader("image-webpack-loader")
        //     .options({
        //         mozjpeg: {progressive: true, quality: 65},
        //         optipng: {enabled: false},
        //         pngquant: {quality: "65-90", speed: 4},
        //         gifsicle: {interlaced: false},
        //         webp: {quality: 75}
        //     });

        // // 打包分析
        // if (process.env.IS_ANALYZ) {
        //     config.plugin('webpack-report')
        //         .use(BundleAnalyzerPlugin, [{
        //             analyzerMode: 'static',
        //         }]);
        // }
    },

    // 是否使用包含运行时编译器的 Vue 构建版本
    // runtimeCompiler: true,

    // 去除打包.map后缀文件
    // productionSourceMap: false,

    // devServer: {//跨域
    //     port: 8080,// 端口号
    //     open: true, //配置自动启动浏览器
    //     proxy: {// 配置跨域处理 可以设置多个
    //         '/api': {
    //             target: '',
    //             ws: true,
    //             changeOrigin: true
    //         },
    //     }
    // }
}

babel.config.js

// 打包时删除console
const plugins = [];
if (['production', 'prod'].includes(process.env.NODE_ENV)) {
  plugins.push("transform-remove-console")
}



module.exports = {
  presets: [
    [
      '@vue/app',
      {
        "useBuiltIns": "entry",
        polyfills: [
          'es6.promise',
          'es6.symbol'
        ]
      }
    ]
  ],
  // 配置babel-plugin-import, 用于按需加载组件代码和样式
  plugins: [
    [
      "import",
      { libraryName: "ant-design-vue", libraryDirectory: "es", style: true }
    ]
  ],

}

.babelrc

{
  "presets": ["@babel/preset-env"],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// 解决ie白屏问题
import '@babel/polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()

// 使用antd-vue Button组件
import { Button } from 'ant-design-vue'

// Button组件
Vue.component(Button.name, Button);


Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,889评论 1 4
  • 33、JS中的本地存储 把一些信息存储在当前浏览器指定域下的某一个地方(存储到物理硬盘中)1、不能跨浏览器传输:在...
    萌妹撒阅读 2,067评论 0 2
  • 原文http://www.cnblogs.com/libin-1/p/6596810.html 版本号 vue-c...
    tengrl阅读 3,630评论 0 0
  • 本文主要介绍两个插件:DllPlugin和DllReferencePlugin,后者配合前者使用。 Github地...
    yozosann阅读 10,958评论 4 27
  • 响应式布局的理解 响应式开发目的是一套代码可以在多种终端运行,适应不同屏幕的大小,其原理是运用媒体查询,在不同屏幕...
    懒猫_6500阅读 777评论 0 0