繁体   English   中英

Vuejs Webpack压缩插件不压缩

[英]Vuejs Webpack Compression Plugin not compressing

我需要帮助调试 Webpack 的压缩插件。

问题总结

  • 目标是启用资产压缩并减少我的应用程序包的大小。 使用 Brotli 算法作为默认算法,gzip 作为不支持的浏览器的后备。
  • 我希望资产的响应标头中有一个内容编码字段。 相反,它们是在没有字段的情况下加载的。 我使用 Chrome 开发工具的网络标签来确认这一点。 有关上下文,请参见以下代码段: 示例资产请求
  • 在本地运行时,我的浏览器或 IDE 中没有显示错误。

我尝试了什么

  • 为压缩插件使用不同的实现。 请参阅下面的方法列表:
    1. (使用 Webpack 链 API)
config
 .plugin('brotliCompress')
     .use(CompressionWebpackPlugin, [{
       exclude: /.map$/,
       cache: true,
       algorithm: 'brotliCompress',
       test: /\.(js|css|html|svg)$/,
       threshold: 10240,
       minRatio: 0.8,
     }])
  1. (使用 Webpack 链 API)
config
  .plugin('gzip')
      .use(CompressionWebpackPlugin, [{
        algorithm: 'gzip',
        test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
        threshold: 8192, // Assets larger than 8192 bytes are not processed
        minRatio: 0.8, // Assets compressing worse that this ratio are not processed
      }])
  1. (使用 Webpack 链 API)
config
  .plugin('CompressionPlugin')
      .use(CompressionWebpackPlugin)
  1. (使用 vue-cli-plugin:compression)当我使用vue invoke compression来响应 IDE 控制台消息时,由于缺少生成器错误,这会失败,因为我运行vue add compression作为使用 Webpack Chain API 进行压缩配置的替代方法。
  pluginOptions: {
    compression: {
      brotli: {
        filename: '[file].br[query]',
        algorithm: 'brotliCompress',
        include: /\.(js|css|html|svg|json)(\?.*)?$/i,
        minRatio: 0.8,
      },
      gzip: {
        filename: '[file].gz[query]',
        algorithm: 'gzip',
        include: /\.(js|css|html|svg|json)(\?.*)?$/i,
        minRatio: 0.8
      }
    }
  },
  1. 最后,我尝试将阈值字段设置为 0 并将其提高到大于 10k 字节。

意义点

  • 上述尝试没有达到我在第一个摘要项目符号中所述的目标,并被用来代替之前测试的方法。
  • 我优先考虑使用 Webpack Chain API,因为它在重新构建和运行应用程序时不会导致错误。

参考链接/文档

代码

vue.config.js

const path = require('path')
const CompressionWebpackPlugin = require('compression-webpack-plugin')

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

module.exports = {
  /* ....shortened for brevity */

  // Compress option VI (with vue cli plugin, generator bug when invoked)
  // pluginOptions: {
  //   compression: {
  //     brotli: {
  //       filename: '[file].br[query]',
  //       algorithm: 'brotliCompress',
  //       include: /\.(js|css|html|svg|json)(\?.*)?$/i,
  //       minRatio: 0.8,
  //     },
  //     gzip: {
  //       filename: '[file].gz[query]',
  //       algorithm: 'gzip',
  //       include: /\.(js|css|html|svg|json)(\?.*)?$/i,
  //       minRatio: 0.8
  //     }
  //   }
  // },

  chainWebpack: config => {
    config
      .resolve.alias
        .set('@', resolve('src'))

    config
      .plugins.delete('prefetch') 
        
    config
      .optimization.splitChunks()

    config
      .output
      .chunkFilename('[id].js')

    // The below configurations are recommeneded only in prod.
    // config.when(process.env.NODE_ENV === 'production', config => { config... })

    // Compress option VII
    // config
      // .plugin('gzip')
      // .use(CompressionWebpackPlugin, [{
      //   algorithm: 'gzip',
      //   test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
      //   threshold: 8192, // Assets larger than 8192 bytes are not processed
      //   minRatio: 0.8, // Assets compressing worse that this ratio are not processed
      // }])

    // Compress option VIII
    // config
      // .plugin('CompressionPlugin')
      // .use(CompressionWebpackPlugin)

    config
      .plugin('brotliCompress')
      .use(CompressionWebpackPlugin, [{
        exclude: /.map$/,
        // deleteOriginalAssets: true,
        cache: true,
        algorithm: 'brotliCompress',
        test: /\.(js|css|html|svg)$/,
        threshold: 10240,
        minRatio: 0.8,
      }])
  },
}

包.json

"dependencies": {
    "@auth0/auth0-spa-js": "^1.15.0",
    "audio-recorder-polyfill": "^0.4.1",
    "compression-webpack-plugin": "^6.0.0",
    "core-js": "^3.6.5",
    "dotenv": "^8.2.0",
    "dotenv-expand": "^5.1.0",
    "moment": "^2.29.1",
    "register-service-worker": "^1.7.1",
    "uuid": "^3.4.0",
    "vue": "^2.6.11",
    "vue-loader": "^15.9.8",
    "vue-router": "^3.5.1",
    "vuex": "^3.6.2"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-pwa": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-cli-plugin-compression": "~1.1.5",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^4.46.0"
  }

我感谢所有输入。 谢谢。

似乎compression-webpack-plugin只压缩文件,但它不会自动配置开发服务器以提供压缩文件来代替原始文件。

但是,您可以通过vue.config.jsdevServer选项(传递给webpack-dev-server )手动设置中间件来执行此操作:

  1. 重写所有接受br编码的.js请求,以将.br附加到原始 URL,这与提供给compression-webpack-pluginfilename设置相匹配。 这有效地获取插件压缩的.br文件。

  2. 设置响应标头以指示br 内容编码application/javascript 内容类型,以便浏览器可以了解如何处理文件。

Vue CLI 5 (Webpack 5)

使用devServer.setupMiddlewares

// vue.config.js
const CompressionPlugin = require('compression-webpack-plugin')

module.exports = {
  transpileDependencies: true,
  configureWebpack: {
    plugins: [
      new CompressionPlugin({   1️⃣
        filename: '[path][base].br',
        algorithm: 'brotliCompress',
        test: /\.js$/,
      })
    ]
  },
  devServer: {
    setupMiddlewares(middlewares, devServer) {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined')
      }

      middlewares.unshift({
        name: 'serve-brotli-js',
        path: '*.js',
        middleware: (req, res, next) => {
          if (req.get('Accept-Encoding')?.includes('br')) {
            1️⃣
            req.url += '.br'

            2️⃣
            res.set('Content-Encoding', 'br')
            res.set('Content-Type', 'application/javascript; charset=utf-8')
          }
          next()
        }
      })

      return middlewares
    }
  }
}

Vue CLI 4 (Webpack 4)

使用devServer.before

注意:与 Webpack 5 的唯一区别是 Express app直接作为参数传递给devserver.before()

// vue.config.js
⋮
module.exports = {
  ⋮
  devServer: {
    before(app) {
      // same code as Webpack 5 above
    }
  }
}

GitHub 演示

目前尚不清楚哪台服务器正在为这些资产提供服务。 如果是 Express,请查看带有标题X-Powered-By的屏幕截图, https://github.com/expressjs/compression/issues/71表明尚未将 Brotli 支持添加到 Express 中。

不过,可能有一种方法可以手动指定content-encoding的标头。

在你的 nginx.conf 文件中添加这些,如果客户端支持 gzip 解析,那么只要服务端可以返回 gzip 就可以启用 gzip

gzip on; #  Turn on Gzip
gzip_static on; #  Turn on static file compression 
gzip_min_length  1k; #  Incompressible critical value , Greater than 1K It s only a matter of time 
gzip_buffers     4 16k;
gzip_comp_level 5;
gzip_types     application/javascript application/x-javascript application/xml application/xml+rss application/x-httpd-php text/plain text/javascript text/css image/jpeg image/gif image/png; #  The type of file to be compressed 
gzip_http_version 1.1;
gzip_vary on;
gzip_proxied   expired no-cache no-store private auth;
gzip_disable   "MSIE [1-6]\.";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM