从0到1搭建element后台框架优化篇(打包优化)


Posted in Javascript onMay 12, 2019

前言

hello,咱又见了~~嘻嘻。本次主要来说说这个打包优化的问题。一个vue项目从开发到上线必须得经历打包过程,一个项目的打包优化与否都决定了你这个项目的运行速度以及用户体验。本次主要是针对vue.config,js的配置进行优化。项目地址

开发环境与生产环境

开发环境与生产环境的配置也是开发中的必不可少的一环。本项目是由vue-cli3开发,vue-cli3深度集成了webpack,如果不熟悉vue-cli3可以先去官网看看相关配置。

开发环境

在项目根目录下新建.env.development文件表明是开发环境。

VUE_APP_CURRENTMODE ="development" //当前的环境
 VUE_APP_LOGOUT_URL="http://localhost:3000/" //开发环境的地址

生产环境

在项目根目录下新建.env.production文件表明是生产环境。

VUE_APP_CURRENTMODE ="development" //当前的环境
 VUE_APP_LOGOUT_URL="xxx" //生产环境的地址

当然你也可以自己创建一个测试环境.env.test,同样可以像上边一样配置。

环境运用

那么接下来我们怎么用它呢?这里不得不说一下的是package.json里面的两个命令serve,build,其实对应的是全命令是vue-cli-service serve --mode development,vue-cli-service build --mode production,如果你想要在构建命令中使用开发环境变量,那么可以加入

"dev-build": "vue-cli-service build --mode development"

接下来在vue.config.js运用它。

config.plugin('define').tap(args => {
   args[0]['process.env'].VUE_APP_LOGOUT_URL = JSON.stringify(process.env.VUE_APP_LOGOUT_URL)
   console.log(args[0])
   return args;
 });

这里有必要说下,这段代码是写在chainWebpack配置项下面。这段代码其实运用了两个webpack插件webpack-chain允许配置链式操作,以及webpack.DefinePlugin。

  1. webpack-chain:尝试通过提供可链式或顺流式的 API 创建和修改webpack 配置。了解更多
  2. webpack.DefinePlugin:它的作用是定义全局常量,是常量。即在模块用它定义的全局常量,那么你就不能改变它。也就是说我定义了一个process.env.VUE_APP_LOGOUT_URL常量,在src文件夹下面都可以使用。了解更多

分包(code splitting)

首先思考,我们引入的第三方包与我们的业务代码一起打包会产生什么问题?

顾名思义,我们的业务代码变动比较频繁,而我们引入的第三方包基本上不会变动。浏览器会有缓存,没有变动的文件会直接从缓存中读取,这也间接的优化了网站的访问速速。

接下来配置vue.config.js,

分割第三方库

//代码分割
 config.optimization.minimize(true);
 config.optimization.splitChunks({
  chunks: 'all',
  cacheGroup:{
  //vue2-editor单独打一个包
   vueEdior: {
   name: 'vueEdior',
   test: /[\\/]node_modules[\\/]vue2-editor[\\/]/,
   priority: 10 // 优先级要大于 vendors 不然会被打包进 vendors
   },
   //其余的第三方包打进vendor
   vendors: {
   test: /[\\/]node_modules[\\/]/,
   priority: -10
   }
  }
 })

分割共用文件

组件是vue项目的重要组成部分。相当一部分组件都可以公用,在不同的文件中引入,因此我们可以将这部分公用的组件直接分割出来。

config.optimization.minimize(true);
 config.optimization.splitChunks({
  chunks: 'all',
  cacheGroup:{
   vueEdior: {
   name: 'vueEdior',
   test: /[\\/]node_modules[\\/]vue2-editor[\\/]/,
   priority: 10 // 优先级要大于 vendors 不然会被打包进 vendors
   },
   public: {
   name: 'public',
   test: resolve('src/components'),
   minSize: 0, //表示在压缩前的最小模块大小,默认值是 30kb
   minChunks: 2, // 最小公用次数
   priority: 5, // 优先级
   reuseExistingChunk: true // 公共模块必开启
   },
   //其余的第三方包打进vendor
   vendors: {
   test: /[\\/]node_modules[\\/]/,
   priority: -10
   }
  }
 })

打包完后会发现dist/static/js,多了一个vueEditor和public文件,这就表明分割完成。

map文件处理和别名设置(alias)

map文件

我们可以进一步优化,打包默认生成map文件,从而导致包的体积过大,这时我们需要设定一个属性来关闭它。

productionSourceMap: false

别名设置

alias运用的好处在于不用一级级的去找,而是直接锁定位置,从而减少文件搜索时间。

//设置别名
 config.resolve.alias
  .set('@', resolve('src'))
  .set('@api', resolve('src/api/api'))//接口地址
  .set('@assets', resolve('src/assets'))

gzip压缩与去console插件

如果上面的方式都编写了,文件依旧过大,这个时候不得不考虑代码压缩和去掉console插件了,可以说为了优化项目,“无所不用其极”。

gzip压缩

首先安装开始安装

cnpm install compression-webpack-plugin --save-dev

然后在configureWebpack里面配置它

const CompressionWebpackPlugin = require('compression-webpack-plugin')
 new CompressionWebpackPlugin({
  filename: '[path].gz[query]',
  algorithm: 'gzip',
  test: new RegExp(
   '\\.(' +
   ['js', 'css'].join('|') +
   ')$',
  ),
  threshold: 10240,
  minRatio: 0.8,
  }),

值得注意的是gzip压缩文件需要后端来配合支持,如果后端没有支持那么项目加载的依旧是没有压缩的文件。

去console插件

首先安装

cnpm install uglifyjs-webpack-plugin --save-dev

然后在configureWebpack里面配置它

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
 new UglifyJsPlugin({
  uglifyOptions: {
   compress: {
   warnings: false,
   drop_debugger: true,
   drop_console: true,
   },
  },
  sourceMap: false,
  parallel: true,
  }),

cdn引入

有的同学说后端没有支持gzip压缩加载,那怎么办?那只有凉拌咯~~~。
这里给大家介绍一个cdn引入的方式,有的第三方插件太大,导致单独分包后还是挺大的,这个时候可以考虑用cdn的方式引入文件。

无插件引入cdn

首先我们不让webpack打包用cdn引入的文件

   

//对一些不经常改动的库,可以通过cdn引入,webpack不对他们打包 
 let externals = {
  'vue': 'Vue',
  'axios': 'axios',
  'element-ui': 'ELEMENT',
  'vue-router': 'VueRouter',
  'vuex': 'Vuex',
  'echarts': 'echarts',
  'vue2-editor': 'VueEditor'
 }

然后配置cdn

 

const cdn = {
  css: [
  //element-ui css
  'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
  ],
  js: [
  //vue
  'https://unpkg.com/vue@2.6.10/dist/vue.min.js',
  //axios
  'http://cdn.staticfile.org/axios/0.19.0-beta.1/axios.min.js',
  //vuex
  'https://unpkg.com/vuex@3.1.0/dist/vuex.min.js',
  //vue-router
  'https://unpkg.com/vue-router@3.0.6/dist/vue-router.min.js',
  //element
  'https://unpkg.com/element-ui@2.7.2/lib/index.js',
  //echarts
  'https://cdn.jsdelivr.net/npm/echarts@4.2.1/dist/echarts.min.js',
  //vue2-editor
  "https://unpkg.com/vue2-editor@2.6.6/dist/vue2-editor.js"
  ]
 }

接下来在chainWebpack配置

process.env.VUE_APP_CURRENTMODE === 'production') {
  config.externals(externals)//忽略打包
  config.plugin('html')
  .tap(args => {
   args[0].cdn = cdn;
   return args
  })
 }

这里需要解释的是config.plugin('html')其实是运用了 html-webpack-plugin插件在其实例化的options挂载cdn对象,然后通过ejs模板语法,读取相关cdn。

紧接着我们需要在public/index.html中读取相关cdn

<% if (process.env.VUE_APP_CURRENTMODE === 'production') { %>
  <% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
  <link rel="stylesheet" href="<%=css%>" rel="external nofollow" as="style">
  <% } %>
  <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
  <script src="<%=js%>"></script>
  <% } %>
 <% } %>

至此cdn引入完成

插件引入cdn

由于手动引入cdn太过麻烦,而且担心版本变化,每次都需要手动去更改,所以为了更好的开发体验,引入了自动匹配cdn插件,webpack-cdn-plugin。接下来开始安装

cnpm install webpack-cdn-plugin --save

实例化插件

const cdnPlugin = require('webpack-cdn-plugin')

接下来开始在configureWebpack中引用

new cdnPlugin({
  modules: [
   { name: 'vue', var: 'Vue', path: 'dist/vue.min.js' },
   { name: 'axios', var: 'axios', path: 'dist/axios.min.js' },
   { name: 'vuex', var: 'Vuex', path: 'dist/vuex.min.js' },
   { name: 'element-ui', var: 'ELEMENT', path: 'lib/index.js', style: 'lib/theme-chalk/index.css' },
   { name: 'echarts', var: 'echarts', path: 'dist/echarts.min.js' },
   { name: 'vue2-editor', var: 'VueEditor', path: 'dist/vue2-editor.js' },
   { name: 'vue-router', var: 'VueRouter', path: 'dist/vue-router.min.js' },
  ],
  publicPath: '/node_modules'
  })
  • name:插件名
  • var :项目中实例化的名字
  • path:路径名称
  • style:css路径名称

更多了解请参考官方文档。

总体来说引入第三方cdn确实能带来不错的效果,但是有可能不稳定,因此建议大家在实际开发中自己去申请一个专属的cdn域名,将网站所要用到库直接上传上去。

结语

本期的打包优化就到这里啦!感觉有很多废话。哈哈~~,最后感谢大家阅读,如果有问题以及错误请及时指正。

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

Javascript 相关文章推荐
破解Session cookie的方法
Jul 28 Javascript
JQuery获取样式中的background-color颜色值的问题
Aug 20 Javascript
js判断数据类型如判断是否为数组是否为字符串等等
Jan 15 Javascript
jQuery动态修改超链接地址的方法
Feb 13 Javascript
详解iframe与frame的区别
Jan 13 Javascript
Node.js Sequelize如何实现数据库的读写分离
Oct 23 Javascript
Angular.js中数组操作的方法教程
Jul 31 Javascript
node.js利用mongoose获取mongodb数据的格式化问题详解
Oct 06 Javascript
微信小程序定义和调用全局变量globalData的实现
Nov 01 Javascript
js代码实现轮播图
May 04 Javascript
原生JS实现天气预报
Jun 16 Javascript
【js设计模式】SOLID五大设计原则
Mar 24 Javascript
Vue项目服务器部署之子目录部署方法
May 12 #Javascript
vue配置接口域名方法总结
May 12 #Javascript
详解babel升级到7.X采坑总结
May 12 #Javascript
babel7.x和webpack4.x配置vue项目的方法步骤
May 12 #Javascript
vue轻量级框架无法获取到vue对象解决方法
May 12 #Javascript
使vue实现jQuery调用的两种方法
May 12 #jQuery
React优化子组件render的使用
May 12 #Javascript
You might like
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
2012/01/12 PHP
一个严格的PHP Session会话超时时间设置方法
2014/06/10 PHP
PHP网站建设的流程与步骤分享
2015/09/25 PHP
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
jquery tools 系列 scrollable(2)
2009/09/06 Javascript
JQUERY的属性选择符和自定义选择符使用方法(二)
2011/04/07 Javascript
Javascript继承(上)——对象构建介绍
2012/11/08 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
两行代码轻松搞定JavaScript日期验证
2016/08/03 Javascript
bootstrap table之通用方法( 时间控件,导出,动态下拉框, 表单验证 ,选中与获取信息)代码分享
2017/01/24 Javascript
[js高手之路]寄生组合式继承的优势详解
2017/08/28 Javascript
vue-cli 3.x配置跨域代理的实现方法
2019/04/12 Javascript
微信小程序 this.triggerEvent()的具体使用
2019/12/10 Javascript
vuex的数据渲染与修改浅析
2020/11/26 Vue.js
[01:14:19]NAVI vs Mineski 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
[27:08]完美世界DOTA2联赛PWL S2 SZ vs Rebirth 第二场 11.21
2020/11/23 DOTA
[57:55]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第二场 12.12
2020/12/16 DOTA
深入Python解释器理解Python中的字节码
2015/04/01 Python
python处理大数字的方法
2015/05/27 Python
在python win系统下 打开TXT文件的实例
2018/04/29 Python
利用Python如何批量更新服务器文件
2018/07/29 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
2018/12/10 Python
一款纯css3实现的动画加载导航
2014/10/08 HTML / CSS
HTML5 WebSocket实现点对点聊天的示例代码
2018/01/31 HTML / CSS
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
iPad和Surface Pro蓝牙键盘:Brydge
2018/11/10 全球购物
澳大利亚音乐商店:Bava’s Music City
2019/05/05 全球购物
如何配置、使用和清除Smarty缓存
2015/12/23 面试题
中专生毕业自我鉴定
2013/11/01 职场文书
试用期转正鉴定评语
2014/01/27 职场文书
物理力学求职信
2014/02/18 职场文书
幼儿教师暑期培训方案
2014/08/27 职场文书
个人批评与自我批评
2014/10/15 职场文书
主持人开场白台词
2015/05/29 职场文书
HTML通过表单实现酒店筛选功能
2021/05/18 HTML / CSS