You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置HtmlWebpackPlugin与CompressionPlugin返回.gz后缀资源?

Hey Harry, let's fix this gzipped asset serving issue step by step. The key here is that we don't need to change the filenames in Webpack (so HtmlWebpackPlugin can keep referencing .js files) — instead, we'll configure Express to serve the .gz version automatically when the browser supports gzip compression.

1. Fix Your Express Route Order & Add Proper Gzip Checks

Your first Express attempt was on the right track, but the route order was wrong. The express.static middleware was handling the .js requests before your custom route could intercept them. Also, we need to verify two critical things before serving the gzipped file:

  • The browser actually supports gzip (via the Accept-Encoding header)
  • The corresponding .gz file exists on the filesystem to avoid 404 errors

Here's the corrected Express setup:

const express = require('express');
const path = require('path');
const fs = require('fs');
const app = express();

// Handle .js requests first: check for gzip support and existing .gz file
app.get('*.js', (req, res, next) => {
  // Verify browser accepts gzip compression
  if (req.headers['accept-encoding']?.includes('gzip')) {
    const gzipFilePath = `${req.url}.gz`;
    const fullPath = path.resolve(__dirname, '../dist', gzipFilePath.slice(1)); // Strip leading slash

    // Check if the .gz file exists on disk
    if (fs.existsSync(fullPath)) {
      req.url = gzipFilePath;
      res.set('Content-Encoding', 'gzip');
      res.set('Content-Type', 'application/javascript');
    }
  }
  next(); // Pass to express.static to serve either .js or .js.gz
});

// Serve static files AFTER the gzip route logic
app.use(express.static(path.resolve(__dirname, '../dist')));

app.get('/healthz', (req, res) => res.send('OK'));
app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, '../dist/index.html')));

const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || '127.0.0.1';
app.listen(PORT);
console.log(`API started on ${HOST}:${PORT}`);

Instead of writing custom logic, use the express-static-gzip middleware — it handles all gzip checks, file existence verification, and header setting automatically, saving you from boilerplate code.

First install the package:

npm install express-static-gzip --save

Then update your Express code to replace express.static with this middleware:

const express = require('express');
const path = require('path');
const expressStaticGzip = require('express-static-gzip');
const app = express();

// Replace express.static with express-static-gzip for auto gzip serving
app.use(expressStaticGzip(path.resolve(__dirname, '../dist'), {
  enableBrotli: false, // Disable if you don't use Brotli compression
  orderPreference: ['gzip'],
  setHeaders: (res, filePath) => {
    // Optional: Add long-term cache headers for static assets
    if (filePath.endsWith('.js') || filePath.endsWith('.css')) {
      res.setHeader('Cache-Control', 'public, max-age=31536000');
    }
  }
}));

app.get('/healthz', (req, res) => res.send('OK'));
app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, '../dist/index.html')));

const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || '127.0.0.1';
app.listen(PORT);
console.log(`API started on ${HOST}:${PORT}`);

3. Keep Your Webpack Configuration As-Is

You don't need to modify your Webpack output filenames or HtmlWebpackPlugin setup. Your current CompressionPlugin is already correctly generating .gz versions of your assets alongside the original .js files. The server handles the rest: when a browser requests app.abc123.min.js, Express will serve app.abc123.min.js.gz if the browser supports gzip, without changing the URL referenced in index.html.

Why your second Express attempt failed:
You set the Content-Encoding: gzip header for all static files, but you were still serving the original uncompressed .js files. This caused browsers to try decompressing non-gzipped data, leading to parsing errors.

内容的提问来源于stack exchange,提问作者Harry Blue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:06:02