webpack默认打包把所有的资源都放在chunk-vendors.js,导致文件很大,从而让页面的响应很慢
1 使用compression-webpack-plugin,打包生成gzip静态资源压缩文件,结合服务端Nginx的配置,服务器启用gzip;
1.1 安装compression-webpack-plugin插件
npm install compression-webpack-plugin --save-dev
1.2 修改vue.config.js
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {configureWebpack: {plugins: [// gzipnew CompressionWebpackPlugin({filename: '[path].gz[query]',algorithm: 'gzip',test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),threshold: 10240,minRatio: 0.8,deleteOriginalAssets: false})],resolve: {alias: {'@': resolve('src')}}},}
1.3 修改nginx的配置
http {sendfile on;keepalive_timeout 65;#上传文件的大小client_max_body_size 200m;##缓存cache参数配置## proxy_connect_timeout 60; proxy_read_timeout 60; proxy_send_timeout 60; proxy_buffer_size 16k; proxy_buffers 4 64k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; #缓存到nginx的本地目录 proxy_temp_path /usr/local/nginx/temp/; proxy_cache_path /usr/local/nginx/temp/cache_temp levels=1:2 keys_zone=my_cache:200m inactive=1d max_size=30g;# 开启缓存proxy_cache my_cache;##压缩配置##gzip on; #开启或关闭gzip on off gzip_static on; gzip_disable "MSIE [1-6]\."; #IE1-6版本不支持gzip压缩gzip_min_length 10k; #gzip压缩最小文件大小,超出进行压缩(自行调节) gzip_buffers 4 16k; #buffer 不用修改 gzip_comp_level 5; #压缩级别:1-10,数字越大压缩的越好,时间也越长 gzip_types text/plain text/css application/xml application/javascript text/javascript application/x-httpd-php application/json application/css image/jpeg image/gif image/png; # 压缩文件类型 gzip_vary on; #跟Squid等缓存服务有关,on的话会在Header里增加 "Vary: Accept-Encoding"gzip_http_version 1.0; #不设置的话,gzip不生效# 限流策略,可在一定程度上防止ddos攻击# ip限流策略limit_req_zone $binary_remote_addr zone=iplimit:10m rate=50r/s;# cookies中access_token值限流策略limit_req_zone $COOKIE_access_token zone=cookielimit:10m rate=50r/s;# header中Authorization值限流策略limit_req_zone $http_Authorization zone=headerlimit:10m rate=50r/s;# url中access_token参数值限流策略limit_req_zone $arg_access_token zone=paramlimit:10m rate=50r/s;
}
2 拆分chunk-vendors.js文件
2.1 拆解方式一
指定模块进行单独打包,不进行大小拆分
module.exports = {css: { extract: false, sourceMap: false }, // 开发环境跟生成环境样式不一致时配置chainWebpack: config => {if (process.env.NODE_ENV !== 'development') {// 移除 prefetch 插件config.plugins.delete('prefetch')// 移除 preload 插件config.plugins.delete('preload')config.optimization.splitChunks({maxInitialRequests: 8, // 每个入口和它的同步依赖最多能被拆分的数量cacheGroups: {elementUI: {name: 'chunk-elementUI', // split elementUI into a single packagepriority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or apptest: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpmchunks: 'all',reuseExistingChunk: true,enforce: true},Components: {name: 'chunk-components', // 这里name与pages中chunks里的名字对应test: /[\\/]node_modules[\\/](components)[\\/]/,chunks: 'all',priority: 14,reuseExistingChunk: true},base: {name: 'chunk-base', // 这里name与pages中chunks里的名字对应test: /[\\/]node_modules[\\/](base)[\\/]/,chunks: 'all',priority: 15,reuseExistingChunk: true,enforce: true}}})}
}
2.2 拆解方式二
直接根据模块名称正则配置拆分,并指定文件大小
// 开启分离js
config.optimization = {runtimeChunk: 'single',splitChunks: {chunks: 'all',maxInitialRequests: Infinity,minSize: 20000, // 依赖包超过20000bit将被单独打包cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name(module) {// get the name. E.g. node_modules/packageName/not/this/part.js// or node_modules/packageNameconst packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]// npm package names are URL-safe, but some servers don't like @ symbolsreturn `npm.${packageName.replace('@', '')}`}}}}
};
2.3 上述拆分后,需要在chunks配置上对应的模块名,不然会导致页面空白
以方式一为例
const glob = require('glob')
glob.sync('./src/modules/**/main.js').forEach(path => {const pageName = path.split('./src/modules/')[1].split('/main.js')[0]pages[pageName] = {entry: path, // page 的入口filename: pageName + '.html', // 在 dist/xxxx.html 的输出// If doesn't exist, fallback to 'public/index.html'template: pageName + '.html', // 模板来源// 提取出来的通用 chunk 和 vendor chunk。chunks: ['chunk-vendors', 'chunk-common', 'chunk-elementUI', 'chunk-base', 'chunk-components', pageName]}
})