vue-cli3全面配置详解


Posted in Javascript onNovember 14, 2018

本文介绍了vue-cli3全面配置详解,分享给大家,具体如下:

vue-cli3-config

创建项目

配置环境变量

通过在package.json里的scripts配置项中添加--mode xxx来选择不同环境

在项目根目录中新建.env, .env.production, .env.analyz等文件

只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中,代码中可以通过process.env.VUE_APP_BASE_API访问

NODE_ENV 和 BASE_URL 是两个特殊变量,在代码中始终可用

.env serve默认的环境变量

NODE_ENV = 'development'
VUE_APP_BASE_API = 'https://demo.cn/api'
VUE_APP_SRC = 'https://wechat-timg.oss-cn-hangzhou.aliyuncs.com/demo'

.env.production build默认的环境变量

NODE_ENV = 'production'

VUE_APP_BASE_API = 'https://demo.com/api'
VUE_APP_SRC = 'https://img-wechat.oss-cn-hangzhou.aliyuncs.com/demo'

.env.analyz 用于webpack-bundle-analyzer打包分析

NODE_ENV = 'production'
IS_ANALYZ = 'analyz'

VUE_APP_BASE_API = 'https://demo.com/api'
VUE_APP_SRC = 'https://img-wechat.oss-cn-hangzhou.aliyuncs.com/demo'

修改package.json

"scripts": {
 "serve": "vue-cli-service serve",
 "build": "vue-cli-service build",
 "analyz": "vue-cli-service build --mode analyz",
 "lint": "vue-cli-service lint"
}

配置vue.config.js

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

module.exports = {
 baseUrl: './', // 默认'/',部署应用包时的基本 URL
 outputDir: process.env.outputDir || 'dist', // 'dist', 生产环境构建文件的目录
 assetsDir: '', // 相对于outputDir的静态资源(js、css、img、fonts)目录
 lintOnSave: false,
 runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
 productionSourceMap: false, // 生产环境的 source map
 parallel: require('os').cpus().length > 1,
 pwa: {}
};

配置proxy跨域

const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
module.exports = {
  devServer: {
    // overlay: {
    //  warnings: true,
    //  errors: true
    // },
    open: IS_PROD,
    host: '0.0.0.0',
    port: 8000,
    https: false,
    hotOnly: false,
    proxy: {
     '/api': {
      target: process.env.VUE_APP_BASE_API || 'http://127.0.0.1:8080',
      changeOrigin: true
     }
    }
  }
}

修复HMR(热更新)失效

module.exports = {
  chainWebpack: config => {
    // 修复HMR
    config.resolve.symlinks(true);
  }
}

添加别名

const path = require('path');
const resolve = (dir) => path.join(__dirname, dir);
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);

module.exports = {
  chainWebpack: config => {
    // 添加别名
    config.resolve.alias
     .set('@', resolve('src'))
     .set('assets', resolve('src/assets'))
     .set('components', resolve('src/components'))
     .set('layout', resolve('src/layout'))
     .set('base', resolve('src/base'))
     .set('static', resolve('src/static'));
  }
}

添加打包分析

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

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

配置externals

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖

module.exports = {
  configureWebpack: config => {
    config.externals = {
     'vue': 'Vue',
     'element-ui': 'ELEMENT',
     'vue-router': 'VueRouter',
     'vuex': 'Vuex',
     'axios': 'axios'
    }
  }
}

去掉console.log

方法一:

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
  configureWebpack: config => {
    if (IS_PROD) {
      const plugins = [];
      plugins.push(
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false,
              drop_console: true,
              drop_debugger: false,
              pure_funcs: ['console.log']//移除console
            }
          },
          sourceMap: false,
          parallel: true
        })
      );
      config.plugins = [
        ...config.plugins,
        ...plugins
      ];
    }
  }
}

方法二:使用babel-plugin-transform-remove-console插件

npm i --save-dev babel-plugin-transform-remove-console

在babel.config.js中配置

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

module.exports = {
 presets: [["@vue/app",{"useBuiltIns": "entry"}]],
 plugins: plugins
};

开启gzip压缩

npm i --save-dev compression-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;

module.exports = {
  configureWebpack: config => {
    if (IS_PROD) {
      const plugins = [];
      plugins.push(
        new CompressionWebpackPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: productionGzipExtensions,
          threshold: 10240,
          minRatio: 0.8
        })
      );
      config.plugins = [
        ...config.plugins,
        ...plugins
      ];
    }
  }
}

还可以开启比gzip体验更好的Zopfli压缩详见https://webpack.js.org/plugins/compression-webpack-plugin

npm i --save-dev @gfx/zopfli brotli-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const zopfli = require("@gfx/zopfli");
const BrotliPlugin = require("brotli-webpack-plugin");
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;

module.exports = {
  configureWebpack: config => {
    if (IS_PROD) {
      const plugins = [];
      plugins.push(
        new CompressionWebpackPlugin({
          algorithm(input, compressionOptions, callback) {
           return zopfli.gzip(input, compressionOptions, callback);
          },
          compressionOptions: {
           numiterations: 15
          },
          minRatio: 0.99,
          test: productionGzipExtensions
        })
      );
      plugins.push(
        new BrotliPlugin({
          test: productionGzipExtensions,
          minRatio: 0.99
        })
      );
      config.plugins = [
        ...config.plugins,
        ...plugins
      ];
    }
  }
}

为sass提供全局样式,以及全局变量

可以通过在main.js中Vue.prototype.$src = process.env.VUE_APP_SRC;挂载环境变量中的配置信息,然后在js中使用$src访问。

css中可以使用注入sass变量访问环境变量中的配置信息

module.exports = {
  css: {
    modules: false,
    extract: IS_PROD,
    sourceMap: false,
    loaderOptions: {
     sass: {
      // 向全局sass样式传入共享的全局变量
      data: `@import "~assets/scss/variables.scss";$src: "${process.env.VUE_APP_SRC}";`
     }
    }
  }
}

在scss中引用

.home {
  background: url($src + '/images/500.png');
}

添加IE兼容

npm i --save @babel/polyfill

在main.js中添加

import '@babel/polyfill';

配置babel.config.js

const plugins = [];

module.exports = {
 presets: [["@vue/app",{"useBuiltIns": "entry"}]],
 plugins: plugins
};

完整配置

安装依赖

npm i --save-dev compression-webpack-plugin babel-plugin-transform-remove-console @gfx/zopfli brotli-webpack-plugin

package.json

"scripts": {
  "serve": "vue-cli-service serve",
  "build": "vue-cli-service build",
  "analyz": "vue-cli-service build --mode analyz",
  "lint": "vue-cli-service lint"
}

babel.config.js

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

module.exports = {
 presets: [["@vue/app",{"useBuiltIns": "entry"}]],
 plugins: plugins
};
vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// const zopfli = require("@gfx/zopfli");
// const BrotliPlugin = require("brotli-webpack-plugin");

const path = require('path');
const resolve = (dir) => path.join(__dirname, dir);
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;

module.exports = {
  baseUrl: './', // 默认'/',部署应用包时的基本 URL
  outputDir: process.env.outputDir || 'dist', // 'dist', 生产环境构建文件的目录
  assetsDir: '', // 相对于outputDir的静态资源(js、css、img、fonts)目录
  lintOnSave: false,
  runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
  productionSourceMap: false, // 生产环境的 source map

  configureWebpack: config => {
    // config.externals = {
    //   'vue': 'Vue',
    //   'element-ui': 'ELEMENT',
    //   'vue-router': 'VueRouter',
    //   'vuex': 'Vuex',
    //   'axios': 'axios'
    // }

    if (IS_PROD) {
      const plugins = [];
      plugins.push(
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false,
              drop_console: true,
              drop_debugger: false,
              pure_funcs: ['console.log']//移除console
            }
          },
          sourceMap: false,
          parallel: true
        })
      );
      plugins.push(
        new CompressionWebpackPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: productionGzipExtensions,
          threshold: 10240,
          minRatio: 0.8
        })
      );
      // Zopfli压缩 https://webpack.js.org/plugins/compression-webpack-plugin/
      // plugins.push(
      //   new CompressionWebpackPlugin({
      //     algorithm(input, compressionOptions, callback) {
      //       return zopfli.gzip(input, compressionOptions, callback);
      //     },
      //     compressionOptions: {
      //       numiterations: 15
      //     },
      //     minRatio: 0.99,
      //     test: productionGzipExtensions
      //   })
      // );
      // plugins.push(
      //   new BrotliPlugin({
      //     test: productionGzipExtensions,
      //     minRatio: 0.99
      //   })
      // );
      config.plugins = [
        ...config.plugins,
        ...plugins
      ];
    }
  },
  chainWebpack: config => {
    // 修复HMR
    config.resolve.symlinks(true);

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

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

    // 多页面配置,为js添加hash
    // config.output.chunkFilename(`js/[name].[chunkhash:8].js`)

    // 修改图片输出路径
    // config.module
    //  .rule('images')
    //  .test(/\.(png|jpe?g|gif|ico)(\?.*)?$/)
    //  .use('url-loader')
    //  .loader('url-loader')
    //  .options({
    //    name: path.join('../assets/', 'img/[name].[ext]')
    //  })
  },
  css: {
    modules: false,
    extract: IS_PROD,
    // 为css后缀添加hash
    // extract: {
    // filename: 'css/[name].[hash:8].css',
    // chunkFilename: 'css/[name].[hash:8].css'
    //},
    sourceMap: false,
    loaderOptions: {
      sass: {
        // 向全局sass样式传入共享的全局变量
        // data: `@import "~assets/scss/variables.scss";$src: "${process.env.VUE_APP_SRC}";`
        data: `$src: "${process.env.VUE_APP_SRC}";`
      },
      // px转换为rem
      // postcss: {
      //  plugins: [
      //   require('postcss-pxtorem')({
      //    rootValue : 1, // 换算的基数
      //    selectorBlackList : ['weui', 'el'], // 忽略转换正则匹配项
      //    propList  : ['*']
      //   })
      //  ]
      // }
    }
  },
  pluginOptions: {
    // 安装vue-cli-plugin-style-resources-loader插件
    // 添加全局样式global.scss
    // "style-resources-loader": {
    //  preProcessor: "scss",
    //  patterns: [
    //   resolve(__dirname, "./src/scss/scss/variables.scss")
    //  ]
    // }
  },
  parallel: require('os').cpus().length > 1,
  pwa: {},
  devServer: {
    // overlay: {
    //  warnings: true,
    //  errors: true
    // },
    open: IS_PROD,
    host: '0.0.0.0',
    port: 8000,
    https: false,
    hotOnly: false,
    proxy: {
      '/api': {
        target: process.env.VUE_APP_BASE_API || 'http://127.0.0.1:8080',
        changeOrigin: true
      }
    }
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
SyntaxHighlighter代码加色使用方法
Sep 07 Javascript
JavaScript创建一个欢迎cookie弹出窗实现代码
Mar 15 Javascript
JS简单实现元素复制示例附图
Nov 19 Javascript
jQuery操作元素css样式的三种方法
Jun 04 Javascript
在css加载完毕后自动判断页面是否加入css或js文件
Sep 10 Javascript
深入学习AngularJS中数据的双向绑定机制
Mar 04 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
Aug 30 Javascript
Bootstrap3多级下拉菜单
Feb 24 Javascript
JavaScript实现数值自动增加动画
Dec 28 Javascript
axios向后台传递数组作为参数的方法
Aug 11 Javascript
使用layui 渲染table数据表格的实例代码
Aug 19 Javascript
使用webpack4编译并压缩ES6代码的方法示例
Apr 24 Javascript
详解IOS微信上Vue单页面应用JSSDK签名失败解决方案
Nov 14 #Javascript
laydate时间日历插件使用方法详解
Nov 14 #Javascript
JQuery模拟实现网页中自定义鼠标右键菜单功能
Nov 14 #jQuery
你应该了解的JavaScript Array.map()五种用途小结
Nov 14 #Javascript
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
Nov 14 #Javascript
Vue 框架之动态绑定 css 样式实例分析
Nov 14 #Javascript
js删除对象/数组中null、undefined、空对象及空数组方法示例
Nov 14 #Javascript
You might like
单一index.php实现PHP任意层级文件夹遍历(Zjmainstay原创)
2012/07/31 PHP
smarty中post用法实例
2014/11/28 PHP
php读取txt文件并将数据插入到数据库
2016/02/23 PHP
PHP邮箱验证示例教程
2016/06/01 PHP
PHP对象克隆clone用法示例
2016/09/28 PHP
PHP调用Mailgun发送邮件的方法
2017/05/04 PHP
JQuery 确定css方框模型(盒模型Box Model)
2010/01/22 Javascript
关于jquery.validate1.9.0前台验证的使用介绍
2013/04/26 Javascript
BootStrap Typeahead自动补全插件实例代码
2016/08/10 Javascript
详解JavaScript模块化开发
2016/12/04 Javascript
javascript设计模式之模块模式学习笔记
2017/02/15 Javascript
html+javascript+bootstrap实现层级多选框全层全选和多选功能
2017/03/09 Javascript
使用 Vue.js 仿百度搜索框的实例代码
2017/05/09 Javascript
react native与webview通信的示例代码
2017/09/25 Javascript
js+css实现全屏侧边栏
2020/06/16 Javascript
基于Electron实现桌面应用开发代码实例
2020/07/07 Javascript
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
解决python 文本过滤和清理问题
2019/08/28 Python
使用批处理脚本自动生成并上传NuGet包(操作方法)
2019/11/19 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
Harrods美国:英国最大的百货公司
2018/11/04 全球购物
医学生自荐信范文
2013/12/03 职场文书
大二学期个人自我评价
2014/01/13 职场文书
中级会计职业生涯规划书
2014/03/01 职场文书
低碳生活倡议书
2014/04/14 职场文书
假面舞会策划方案
2014/05/29 职场文书
银行委托书范本
2014/09/28 职场文书
男方婚前保证书
2015/02/28 职场文书
2015年防汛工作总结
2015/05/15 职场文书
党小组意见范文
2015/06/08 职场文书
2015秋季开学演讲稿范文
2015/07/16 职场文书
2016幼儿园新学期寄语
2015/12/03 职场文书
python爬虫请求库httpx和parsel解析库的使用测评
2021/05/10 Python
Python基础之元组与文件知识总结
2021/05/19 Python