压缩 webpack 插件

10

我正试图弄清楚如何正确地使用webpack-html-plugincompression plugin,但后者的文档有点匮乏。

我的webpack配置声明:

output: {
  filename: 'js/[name]-[hash].js',

压缩插件最后运行

new CompressionPlugin({
    asset: "[path].gz[query]",
    algorithm: "gzip"
})

最终脚本已正确生成并压缩。

js/app-caf3b4b3.js.gz     382 kB          [emitted]  [big] 

我可以在 index.html 模板中声明预加载经过 gzip 压缩的文件

 <link rel="preload" href="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>.gz" as="script">

但是 webpack 负责插入这行代码:

<script type="text/javascript" src="/js/app-caf3b4b3.js">

<body></body> 内部

我该如何让webpack使用压缩后的脚本?

4个回答

7
你可以通过Webpack压缩插件在SPA应用程序或服务器端完成此操作。我将回答我测试过的Vue.js spa的配置。React和Angular webpack除了配置文件名称不同外,也不会有太大区别。
步骤:
  1. Create a vue.config.js file if not already present

  2. Add something along these lines

    const CompressionWebpackPlugin = require("compression-webpack-plugin");
    
    module.exports = {
    
      configureWebpack: {
    
        plugins: [
          new CompressionWebpackPlugin({
            filename: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.(js|css)$/,
           ...
    
          })
        ]
      }
    };
    

插件文档中提供了更多选项。


7

在HTML中不需要链接一个压缩文件。你必须在服务器端进行操作。你也可以压缩CSS和HTML文件。

设置你的服务器使用gzip压缩发送文件,你还需要适当的头部来告诉浏览器如何解读这个压缩文件。

如果你使用Apache服务器,你可以通过一个.htaccess文件启用gzip压缩。

我在我的Apache服务器上使用以下代码:

# enable the rewrite capabilities
RewriteEngine On

# prevents the rule from being overrided by .htaccess files in subdirectories
RewriteOptions InheritDownBefore

# provide a URL-path base (not a file-path base) for any relative paths in the rule's target
RewriteBase /

# GZIP
## allows you to have certain browsers uncompress information on the fly
AddEncoding gzip .gz
## serve gzip .css files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]
## serve gzip .js files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]
## serve gzip .html files if they exist and the client accepts gzip
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.html $1\.html\.gz [QSA]
## serve correct content types, and prevent mod_deflate double gzip
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=is_gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=is_gzip:1]
RewriteRule \.html\.gz$ - [T=text/html,E=no-gzip:1,E=is_gzip:1]
Header set Content-Encoding "gzip" env=is_gzip

你可以在谷歌上搜索更多有关如何使用gzip压缩优化网站的信息。

https://gtmetrix.com/enable-gzip-compression.html

https://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/optimize-encoding-and-transfer#text_compression_with_gzip


2

#webpack #compression #express #node

在实现我想做的事情时,将所有信息分组是具有挑战性的。下面是我如何创建webpack并将其与express相关联的方法。

这是webpack文件中的插件部分:webpack.config.js

示例(对象数组)

plugins: [confi1, config2, confi3]

plugins: [
    new CompressionPlugin({
      filename: '[path][base].gz',
      algorithm: 'gzip',
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
    }),
    new CompressionPlugin({
      filename: '[path][base].br',
      algorithm: 'brotliCompress',
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        params: {
          [zlib.constants.BROTLI_PARAM_QUALITY]: 11
        }
      },
      threshold: 10240,
      minRatio: 0.8
    })
  ]

在此输入图片描述

如果您注意到,我只使用了两种压缩方式,虽然还有更多的方式,但我认为这两种已经足够了。

此外,如果您想学习如何修改选项,可以查看此页面:https://webpack.js.org/plugins/compression-webpack-plugin/

br = Brotli is a lossless data compression algorithm developed by Google)
gzip = is a software library used for data compression (STANDAR). zlib was written by Jean-loup Gailly

我同时使用两种方式,用于支持换行的情况下我们发送br标签;如果不支持,则发送gzip文件;最坏的情况下,我们发送.js文件:现在我们来看看它

如何通过express向客户端发送正确的文件: 以下是...

app.use(
  '/static',
  expressStaticGzip(path.join('dist', 'frontend'), {
    enableBrotli: true,
    customCompressions: [
      {
        encodingName: 'deflate',
        fileExtension: 'zz'
      }
    ],
    orderPreference: ['br', 'gz'],
    setHeaders: function (res, path) {
      res.setHeader('Cache-Control', 'public, max-age=0');
    }
  })

);

enter image description here

请查看图像中的文件: 如果您使用webpack进行编译,请注意JS的插件(br,gz)。在这种情况下,bundle.js有bundle.js.br和bundle.js.gz;对于CSS,我们也一样。如果客户端发出请求到Static文件夹,在那里将发送给express客户端的文件,他们会根据请求中的标头来决定发送什么。例如,如果您使用Chrome,express将向您发送“br”,但如果您使用Safari,express将向您发送“gz”。

Chrome和Safari的示例:

Chrome: example crome

Safari的示例:

example safari

通过这种方法,我们将HTML文件发送给客户端,然后客户端将请求JS文件,但服务器将以压缩形式发送JS文件

app.get('/*', function (req, res) {
    let pathServer = process.env.subDOMAIN == "true" ? "" : "/scheduler_app";
    res.render('pages/index', { App: "stringApp", script: `<script src="${pathServer}/static/bundle.js"></script>`, css: `<link rel="stylesheet" href="${pathServer}/static/main.css">` });
});

1

我的方法有些不同,但它在最终目的上起到了作用,并且我可以节省大量发送给客户端的数据!我也曾努力为我的React SSR应用程序提供压缩版本;在我的情况下,使用js.br扩展名的brotli类型>“bundle.js.br”。以下代码片段最终将其更改以正确提供服务。在开发模式下,我将客户端未压缩的捆绑包从1.7 MB减少到0.27 MB。尝试自己解决问题。无需额外插件即可提供文件。当然,必须首先使用webpack生成压缩版本。对于webpack brotli压缩,我与zlib一起使用npmjs软件包compression-webpack-plugin。

var express = require('express');
var app = express();

app.get('*.js', (req, res, next) => {
  if (req.header('Accept-Encoding').includes('br')) {
    req.url = req.url + '.br';
    console.log(req.header('Accept-Encoding'));
    res.set('Content-Encoding', 'br');
    res.set('Content-Type', 'application/javascript; charset=UTF-8');
  }
  next();
});

app.use(express.static('public'));

现在让我解释一下我上面的片段,我用它来为我的SSR React应用程序提供压缩文件服务。

  • 在开头使用参数'*.js'表示这个app.get适用于每个被触发的端点,以获取JS文件。
  • 在回调函数内,我将.br附加到请求的URL上。此外,Content-Encoding响应头设置为br。
  • Content-Type头设置为application/javascript; charset=UTF-8以指定MIME类型。
  • 最后但非常重要的是,next()使得可以继续到可能是下一个回调。
  • 不要忘记提供您的压缩包所放置的文件夹。在我的情况下,我使用了app.use(express.static('public'))。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接