最近自己买个云服务器,把之前搭建的webpack-vue项目进行了部署,现在项目已经成功了。
项目地址:GitHub - wjt162286793/webpack----vue: 使用webpack配置一个脚手架,对照文档,纯手打
?线上地址:IAM架构资产管理系统
不过是没有经过任何优化的,虽然项目体积和业务不是很复杂,但是实际上打完包后体积也是比较大,首次加载也是需要请求大资源文件,导致项目加载很慢,而且还有很多console.log的内容在控制台上,效果如下
我这个项目最多算一个中小型,现在的包就87MB那么大,我在线上部署了一下,白屏16秒......
本文主要针对webpack进行优化,版本为webpack5,并不对业务代码本身进行优化,因为本身业务代码也不是特别的多,编写的时候也是注重代码的结构的
用webpack打包后,vendors.js是所有当前项目中所有的依赖包和业务代码的综合,我们就要想办法让vendors包的提交大大缩减
在配置路由时,我们可以使用懒加载和webpackChunkName,将每个路由组件都生成小包,脱离掉vendors.js
{
path: '/dashboard/business/businessList',
name: 'businessList',
meta: {
name: '列表'
},
component: () => import(/* webpackChunkName:'businessList'*/ 'pages/business/components/businessList.vue')
},
注意:如果用户是可以连接到互联网的情况下,可以这样使用。如果用户是无法访问互联网和对应cdn地址的,就不可以这样去做了。
当你使用了externals之后,里面配置的包就不会出现在打包中
externals: {
'vue': 'Vue',
'axios': 'axios',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'html2canvas': 'html2canvas',
'lodash': '_'
},
在项目中,我们引入的方式必须要要和这里面的一致
key是包名,value是这个包默认导出的名字(!!!一定要写对)
例如:vue3就没有导出vue,而是import {creatApp} from 'vue'
我们这里就要写成这个样子
//原来的写法
//import {createApp} from 'vue'
const Vue = require('vue')
import Main from './main.vue'
export const mainVue = Vue.createApp(Main)
其他同理
如果我们使用externals排除了某个包,就需要在index.html中引入cdn地址。
这里注意,cdn的包地址一定要引对。
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.global.prod.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.5/axios.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/4.1.0/vuex.global.prod.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.16/vue-router.global.prod.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
这里有一个很简单的测试方法,你去cdn地址上将代码复制下来,在本地去测一下,看能不能成功使用你在externals中使用的包类名
?
?如果不能对的上,那你发到生产上就会报错
所以,找cdn的地址一定要找对
大部分项目都会用到ui组件库,如element-ui或者element-plus,echarts等等
这里有一个原则,如果你的项目中基本把这个组件库的绝大多数组件都用了,那你就可以直接将这个组件库也用cdn的形式引用了。如果没有的话,那你就是用按需引入的方式去引入该ui组件库
大部分的组件库都给提供了按需引入的方式,对照着文档操作就可以了
比如一个包在多个文件中使用,我们只需要抽取一次就可以了,这样也可以减除很多的冗余代码
optimization: {
moduleIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
const CompressionPlugin = require('compression-webpack-plugin');
plugins: [
new CompressionPlugin({
algorithm: 'gzip', // 使用gzip算法进行压缩
test: /\.(js|css)$/, // 需要压缩的文件类型
threshold: 10240, // 文件大小大于10KB才会被压缩
minRatio: 0.8, // 压缩比例达到0.8才会被压缩
deleteOriginalAssets: false, // 是否删除原始文件
}),
//...
],
使用了gzip之后,打包后的文件就会生成.gz的压缩文件,也是常见有效的优化,能是构建包更轻量
const TerserPlugin = require('terser-webpack-plugin');
optimization: {
//生产环境上干掉所有的js注释和日志
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
format: {
comments: false, //删除注释
},
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']//删除打印语句
}
},
extractComments: false,
}),
],
},
在开发的时候,我们为了方便查找错误,配置了soureMap。
但是在打包构建的时候,就需要关闭sourceMap了。其一是可以不打包map文件减少体积,其二是可以避免源码泄露。
在配置中加一行
devtool: false
在打包时,js文件会默认压缩。但是很多静态文件之类的不会,特别是图片等资源。
这里我就不在文档中写具体怎么操作了,网上一搜一大把。后续我会在webpack系列中对各种plugin进行演示
现在我在打包一次,可以看看效果
?
?效果也是很明显的
特意说明一下:现在项目也只是完成了初版的,后续还有东西要往里面写。优化还有一些提升的空间
业务也都是模拟的假业务,是为了技术练习,没有任何的实际意义,也没有侵犯任何单位的行为。
项目地址:GitHub - wjt162286793/webpack----vue: 使用webpack配置一个脚手架,对照文档,纯手打
线上地址:IAM架构资产管理系统
感觉有用的在github上给个star吧!