前言
vue程序代码写完了,不做任何优化,发现包有点大,为此我们需要分析打包文件中都有些什么。才能对症下药。主要是因为博主当初的服务器才1M带宽........1M
该Demo为vue3.0的~
查看包文件
这个没有优化过的包
首先,修改我们的 package.json 文件
然后执行打包命令
npm run build
我们会发现多了一个 report.html,打开他
加载时长
分析
vue-cli的打包策略是将node_module中的包打包成一个chunk-vendors.js 其他的js 如assets中的打包成app.js。
现在我们需要:
1、尽量减小打包的大小,可采用CDN方式加载;
2、将包打包成压缩包并且配置好nginx压缩功能;
configureWebpack
通过操作对象的形式,来修改默认的webpack配置,该对象将会被 webpack-merge 合并入最终的 webpack 配置chainWebpack
通过链式编程的形式,来修改默认的webpack配置/*
* @Author: Penk
* @LastEditors: Penk
* @LastEditTime: 2020-11-05 10:09:37
* @FilePath: \penk-web-master\Vue.config.js
*/
const path = require('path');
const webpack = require('webpack');
function resolve(dir) {
return path.join(__dirname, dir)
}
//config/index.js
const os = require('os');
// 动态设置IP,多网卡,需要配置正则表达式 如下方
// (/^192.168.1.*&/).test(alias.address)) 即表示192.168.1.1 网段
function getNetworkIp() {
let needHost = ''; // 打开的host
try {
// 获得网络接口列表
let network = os.networkInterfaces();
for (let dev in network) {
let iface = network[dev];
console.log(iface)
for (let i = 0; i < iface.length; i++) {
let alias = iface[i];
if (alias.family === 'IPv4' &&
alias.address !== '127.0.0.1' &&
!alias.internal &&
(/^192.168.1.(\d+)$/).test(alias.address)) {
needHost = alias.address;
}
}
}
} catch (e) {
needHost = 'localhost';
}
return needHost;
}
// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development'
// 本地环境是否需要使用cdn
const devNeedCdn = true;
// cdn链接
const cdn = {
// cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
// externals中的key是用于import,
// value表示的在全局中访问到该对象,就是window.echarts
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
'element-ui': 'ELEMENT',
'echarts': 'echarts',
'moment': 'moment',
'mavon-editor': 'MavonEditor',
'jquery': '$',
'tinymce': 'tinymce',
},
// cdn的css链接
css: [,
'https://unpkg.com/[email protected]/lib/theme-chalk/index.css',
'https://unpkg.com/[email protected]/lib/theme-chalk/display.css',
'https://unpkg.com/[email protected]/dist/css/index.css',
'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css'
],
// cdn的js链接
js: [
'https://cdn.staticfile.org/vue/2.6.11/vue.min.js',
'https://cdn.staticfile.org/vuex/3.1.2/vuex.min.js',
'https://cdn.staticfile.org/vue-router/3.1.5/vue-router.min.js',
'https://unpkg.com/[email protected]/lib/index.js',
'https://unpkg.com/[email protected]/dist/echarts.min.js',
'https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js',
'https://cdn.bootcss.com/moment.js/2.20.1/locale/zh-cn.js',
'https://unpkg.com/[email protected]/dist/mavon-editor.js',
'https://cdn.bootcss.com/jquery/3.5.1/jquery.min.js',
'https://cdn.bootcss.com/tinymce/5.2.0/tinymce.min.js'
]
}
module.exports = {
pwa: {
iconPaths: {
favicon32: 'favicon.ico',
favicon16: 'favicon.ico',
appleTouchIcon: 'favicon.ico',
maskIcon: 'favicon.ico',
msTileImage: 'favicon.ico'
}
},
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
outputDir: 'penk-web-master-dist',
lintOnSave: false, //是否开启eslint保存检测 ,它的有效值为 true || false || 'error'\
css: {
extract: false
},
devServer: {
open: true,
host: getNetworkIp(),
port: 8886,
proxy: {
'/server': { //这里最好有一个 /
// target: 'http://192.168.1.150:3000', // 后台接口域名
target: 'http://localhost:9500', // 后台接口域名
ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^/server': ''
}
}
}
},
chainWebpack: config => {
// ============压缩图片 start============
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({
bypassOnDebug: true
})
.end()
// ============压缩图片 end============
// ============注入cdn start============
config.plugin('html').tap(args => {
// 生产环境或本地需要cdn时,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============注入cdn start============
// ============别名 start============
config.resolve.alias
.set('@', resolve('src'))
// ============别名 start============
},
configureWebpack: config => {
config.devtool = 'source-map'
// 全局引入JQuery
config.plugins.push(
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
jquery: "jquery",
"windows.jQuery": "jquery",
"windows.jquery": "jquery"
})
)
// 用cdn方式引入,则构建时要忽略相关资源
if (isProduction || devNeedCdn) config.externals = cdn.externals
// 生产环境相关配置
if (isProduction) {
// 代码压缩
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
//生产环境自动删除console
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
},
warnings: false, // 若打包错误,则注释这行
},
sourceMap: process.env.NODE_ENV === 'production' ? false : true,
parallel: true
})
)
// gzip压缩
const productionGzipExtensions = ['html', 'js', 'css']
config.plugins.push(
new CompressionWebpackPlugin({
// filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' + productionGzipExtensions.join('|') + ')$'
),
threshold: 10240, // 只有大小大于该值的资源会被处理 10240
minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
deleteOriginalAssets: false // 删除原文件,不用删除也可以,会优先传递压缩文件
})
)
// 公共代码抽离
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
}
}
}
比较
通过下图,可发现各包体积减小了
部分包已经采用CDN方式加载
本地加载的包,已经通过压缩的方式传递
额外Bug(图片压缩)
npm安装的image-webpack-loader会报错,哪怕你用了nrm设置了国内镜像~~~
# 使用npm安装的 image-webpack-loader在编译的时候会有问题,不信可以试试
npm install --save-dev image-webpack-loader
npm run build
# 安装cnpm
npm install cnpm -g --registry=https://registry.npm.taobao.org
# cnpm : 无法加载文件 D:\nodejs\node_global\cnpm.ps1,因为在此系统上禁止运行脚本
# 运行cnpm会产生问题,所以需要配置一下权限
# 打开powershell
# 管理员授权
Start-Process powershell -Verb runAs
# 继续重新执行set-ExecutionPolicy RemoteSigned 选择 Y
# 安装
cnpm install --save-dev image-webpack-loader
# 编译
npm run build