Vuejs Webpack 压缩插件不压缩

Dan*_*sch 8 javascript performance webpack vue.js vuejs2

我需要帮助调试 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,
     }])
Run Code Online (Sandbox Code Playgroud)
  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
      }])
Run Code Online (Sandbox Code Playgroud)
  1. (使用Webpack链API)
config
  .plugin('CompressionPlugin')
      .use(CompressionWebpackPlugin)
Run Code Online (Sandbox Code Playgroud)
  1. (使用 vue-cli-plugin:压缩)当我在运行后作为使用 Webpack Chain API 进行压缩配置的替代方案来响应 IDE 控制台消息时,由于缺少生成器错误而失败。vue invoke compressionvue add compression
  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
      }
    }
  },
Run Code Online (Sandbox Code Playgroud)
  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,
      }])
  },
}
Run Code Online (Sandbox Code Playgroud)

包.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"
  }
Run Code Online (Sandbox Code Playgroud)

我感谢所有的意见。谢谢。

ton*_*y19 5

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

\n

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

\n
    \n
  1. 重写所有.js接受br编码的请求以附加.br到原始 URL,该 URL 与filename给定的设置匹配compression-webpack-plugin。这有效地获取了.br由插件压缩的文件。

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

    \n
  4. \n
\n

Vue CLI 5(Webpack 5)

\n

使用devServer.setupMiddlewares

\n
// vue.config.js\nconst CompressionPlugin = require(\'compression-webpack-plugin\')\n\nmodule.exports = {\n  transpileDependencies: true,\n  configureWebpack: {\n    plugins: [\n      new CompressionPlugin({   1\xef\xb8\x8f\xe2\x83\xa3\n        filename: \'[path][base].br\',\n        algorithm: \'brotliCompress\',\n        test: /\\.js$/,\n      })\n    ]\n  },\n  devServer: {\n    setupMiddlewares(middlewares, devServer) {\n      if (!devServer) {\n        throw new Error(\'webpack-dev-server is not defined\')\n      }\n\n      middlewares.unshift({\n        name: \'serve-brotli-js\',\n        path: \'*.js\',\n        middleware: (req, res, next) => {\n          if (req.get(\'Accept-Encoding\')?.includes(\'br\')) {\n            1\xef\xb8\x8f\xe2\x83\xa3\n            req.url += \'.br\'\n\n            2\xef\xb8\x8f\xe2\x83\xa3\n            res.set(\'Content-Encoding\', \'br\')\n            res.set(\'Content-Type\', \'application/javascript; charset=utf-8\')\n          }\n          next()\n        }\n      })\n\n      return middlewares\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Vue CLI 4(Webpack 4)

\n

使用devServer.before

\n

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

\n
// vue.config.js\n\xe2\x8b\xae\nmodule.exports = {\n  \xe2\x8b\xae\n  devServer: {\n    before(app) {\n      // same code as Webpack 5 above\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

GitHub 演示

\n