vue项目打包压缩静态资源—使用compression-webpack-plugin

vue项目打包压缩静态资源—使用compression-webpack-plugin

场景: vue项目打包上线后,资源加载缓慢,用户体验感差。
解决方案: 使用compression-webpack-plugin插件压缩打包的静态资源,优化项目性能。

使用方法

  1. 下载compression-webpack-plugin
cnpm i [email protected] --save

注意: 这里不能直接下载,需要下载低版本的。直接下载就是最新版的了,vue脚手架暂时不支持最新版的,所以就会报错:TypeError: Cannot read property ‘tapPromise’ of undefined。我这里下载是指定@6.1.1版本,是可以用的。
2. 配置vue.config.js

const CompressionWebpackPlugin = require("compression-webpack-plugin"); // 引入
module.exports = {
	configureWebpack: config => {
        // 开发环境不配置
        if (process.env.NODE_ENV !== 'production') return
        // 生产环境才去配置
        return {
            plugins: [
                new CompressionPlugin({
                 	cache: false, // 取消缓存 
                    // filename: "[path][base].gz", // 输出文件名 这种方式是默认的,多个文件压缩就有多个.gz文件,建议使用下方的写法
                    filename: '[path].gz[query]', //  使得多个.gz文件合并成一个文件,这种方式压缩后的文件少,建议使用
                    algorithm: 'gzip', // 压缩算法 默认是gzip
                    test: /\.(js|css)(\?.*)?$/g, // 使用正则给匹配到的文件做压缩,这里是给css、js做压缩
                    threshold: 10240, // 只处理大于 10KB 的文件
                    minRatio: 0.8, // 只有压缩率大于0.8的文件才会被处理
                    //是否删除原有静态资源文件,即只保留压缩后的.gz文件,建议这个置为false,还保留源文件。以防:
                    // 假如出现访问.gz文件访问不到的时候,还可以访问源文件双重保障
                    deleteOriginalAssets: false
                })
            ]
        }
    },
}
  1. 后端nginx配置
server {
        listen       80;
        server_name  localhost;
        location / {
            try_files $uri $uri/ /index.html;
            root C:/nginx-1.18.0/html/gzip/dist;
            index  index.html index.htm;
        }
        location /api/ {
            proxy_pass http://localhost:6666/;
        }
        
        # 主要是下方的gizp配置哦,直接复制粘贴就可以使用啦,亲测有效哦
        gzip on; # 开启gzip压缩
        gzip_min_length 10k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
        gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
        gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
        gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
                 # 压缩的文件类型 MIME类型,百度一下,一大把                                    # css             # xml             # 识别php     # 图片
        gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
                 # text                   # 早期js                 # js        # js的另一种写法                                                                                 # .eot字体                   # woff字体  # ttf字体
        gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启       
    }
  1. vue.config.js完整配置项
'use strict'
const path = require('path')
const define = require('./src/utils/define.js')
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const Version = new Date().getTime()
const Env = process.env.VUE_APP_ENV

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = '空间科学与应用项目论证系统' // page title

const port = process.env.port || process.env.npm_config_port || 3000 // dev port

module.exports = {
  // 如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署  https://www.xxx.vip/admin/,则设置 publicPath 为 /admin/。
  publicPath: Env == 'production'? '/web/' : '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: false,
  productionSourceMap: false,
  devServer: {
    port: port,
    open: false,
    overlay: {
      warnings: false,
      errors: true
    },
    // 接口转发
    proxy: {
      '/pmweb': {
        target: define.APIURl,
        changeOrigin: true,
        pathRewrite: {
          '^/pmweb': ''
        }
      }
    }
  },

  configureWebpack: {
    name: name,
    output: {
      filename: `js/[name].js?v=${Version}`,
      chunkFilename: `js/[name].js?v=${Version}`,
    },
    resolve: {
      alias: {
        '@': resolve('src'),
        'static': resolve('static') // 增加这一行代码
      }
    },
    plugins: [
      new MonacoWebpackPlugin({
        languages: ['javascript', 'css', 'html', 'typescript', 'json', 'java', 'sql']
      })
    ],
  },
  css: { 
    extract: { 
      filename: `css/[name].css?v=${Version}`,
      chunkFilename: `css/chunk.[id].css?v=${Version}`,
    }
  },
  chainWebpack(config) {
    config.externals({
      'echarts': 'echarts'
    })
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [{
      rel: 'preload',
      fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
      include: 'initial'
    }])
    config.plugins.delete('prefetch')
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    config
      .when(process.env.NODE_ENV === 'development',
        config => config.devtool('cheap-source-map')
      )

    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                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
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
            config.optimization.runtimeChunk('single')
            config.plugin("compression").use(CompressionWebpackPlugin, [
              {
                cache: false, // 取消缓存
                filename: "[path][base].gz[query]", // 输出文件名
                algorithm: "gzip",  // 压缩算法
                // test: /\.(js|css)$/, // 匹配需要压缩的文件类型,使用该种方式js文件夹下js不会被压缩
                test: /\.(js|css)(\?.*)?$/g,
                threshold: 10240,  // 只处理大于 10KB 的文件
                minRatio: 0.8, // 只有压缩率大于0.8的文件才会被处理
                deleteOriginalAssets: false, // 是否删除原始文件
              },
            ]);
        }
      )
  }
}

参考文章https://zhuanlan.zhihu.com/p/530959154

你可能感兴趣的:(vue.js,webpack,前端)