hello,咱又见了~~嘻嘻。本次主要来讲说这个打包优化的问题。一个vue项目从开发到上线必须得经历打包过程,一个项目的打包优化与否都决定了你这个项目的运行速度以及用户体验。本次主要是针对vue.config,js
的配置进行优化。项目地址javascript
开发环境与生产环境的配置也是开发中的必不可少的一环。本项目是由vue-cli3
开发,vue-cli3
深度集成了webpack
,若是不熟悉vue-cli3
能够先去官网看看相关配置。css
在项目根目录下新建.env.development
文件代表是开发环境。html
VUE_APP_CURRENTMODE ="development" //当前的环境
VUE_APP_LOGOUT_URL="http://localhost:3000/" //开发环境的地址
复制代码
在项目根目录下新建.env.production
文件代表是生产环境。vue
VUE_APP_CURRENTMODE ="development" //当前的环境
VUE_APP_LOGOUT_URL="xxx" //生产环境的地址
复制代码
固然你也能够本身建立一个测试环境.env.test
,一样能够像上边同样配置。java
那么接下来咱们怎么用它呢?这里不得不说一下的是package.json
里面的两个命令serve
,build
,其实对应的是全命令是vue-cli-service serve --mode development
,vue-cli-service build --mode production
,若是你想要在构建命令中使用开发环境变量,那么能够加入node
"dev-build": "vue-cli-service build --mode development"
复制代码
接下来在vue.config.js
运用它。webpack
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
。ios
process.env.VUE_APP_LOGOUT_URL
常量,在src
文件夹下面均可以使用。了解更多首先思考,咱们引入的第三方包与咱们的业务代码一块儿打包会产生什么问题?
顾名思义,咱们的业务代码变更比较频繁,而咱们引入的第三方包基本上不会变更。浏览器会有缓存,没有变更的文件会直接从缓存中读取,这也间接的优化了网站的访问速速。 接下来配置vue.config.js
,git
//代码分割
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项目的重要组成部分。至关一部分组件均可以公用,在不一样的文件中引入,所以咱们能够将这部分公用的组件直接分割出来。github
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文件,从而致使包的体积过大,这时咱们须要设定一个属性来关闭它。
productionSourceMap: false
复制代码
alias
运用的好处在于不用一级级的去找,而是直接锁定位置,从而减小文件搜索时间。
//设置别名
config.resolve.alias
.set('@', resolve('src'))
.set('@api', resolve('src/api/api'))//接口地址
.set('@assets', resolve('src/assets'))
复制代码
若是上面的方式都编写了,文件依旧过大,这个时候不得不考虑代码压缩和去掉console插件了,能够说为了优化项目,“无所不用其极”。
首先安装开始安装
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
压缩文件须要后端来配合支持,若是后端没有支持那么项目加载的依旧是没有压缩的文件。
首先安装
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,
}),
复制代码
有的同窗说后端没有支持gzip
压缩加载,那怎么办?那只有凉拌咯~~~。
这里给你们介绍一个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%>" as="style">
<% } %>
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
<% } %>
复制代码
至此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'
})
复制代码
cdn
确实能带来不错的效果,可是有可能不稳定,所以建议你们在实际开发中本身去申请一个专属的cdn
域名,将网站所要用到库直接上传上去。本期的打包优化就到这里啦!感受有不少废话。哈哈~~,最后感谢你们阅读,若是有问题以及错误请及时指正。