vue、webpack打包优化

webpack默认打包把所有的资源都放在chunk-vendors.js,导致文件很大,从而让页面的响应很慢

1 使用compression-webpack-plugin,打包生成gzip静态资源压缩文件,结合服务端Nginx的配置,服务器启用gzip;

1.1 安装compression-webpack-plugin插件

bash 复制代码
npm install compression-webpack-plugin --save-dev

1.2 修改vue.config.js

const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {

 configureWebpack: {
    plugins: [
      // gzip
      new 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 package
            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
            chunks: '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/packageName
                    const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                    // npm package names are URL-safe, but some servers don't like @ symbols
                    return `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]
  }
})
相关推荐
前端李易安12 分钟前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js
红绿鲤鱼14 分钟前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
周全全15 分钟前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
Domain-zhuo24 分钟前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
小丁爱养花32 分钟前
前端三剑客(三):JavaScript
开发语言·前端·javascript
ZwaterZ40 分钟前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
码农六六40 分钟前
vue3封装Element Plus table表格组件
javascript·vue.js·elementui
西凉河的葛三叔44 分钟前
vue3+elementui-plus el-dialog全局配置点击空白处不关闭弹窗
前端·vue3·elementui-plus
徐同保1 小时前
el-table 多选改成单选
javascript·vue.js·elementui
快乐小土豆~~1 小时前
el-input绑定点击回车事件意外触发页面刷新
javascript·vue.js·elementui