Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Analyze gzipped bundles #377

Closed
RedVelocity opened this issue Aug 27, 2020 · 12 comments
Closed

Feature Request: Analyze gzipped bundles #377

RedVelocity opened this issue Aug 27, 2020 · 12 comments

Comments

@RedVelocity
Copy link

Issue description

webpack-bundle-analyzer currently displays a blank page when a webpack build uses compression-webpack-plugin to compress bundles.

Technical info

Using the following workaround. This skips compression when webpack build command is used with 'analyze' environment variable.

module.exports = ({ env, analyze }) => {
  switch (env) {
    case 'development':
      return merge(commonConfig, developmentConfig);
    case 'production':
      if (analyze) commonConfig.plugins.push(new BundleAnalyzerPlugin());
      else
        productionConfig.plugins.push(
          new CompressionPlugin({
            filename: '[path].gz',
            algorithm: 'gzip',
            test: /\.(js|jsx|css|html|png|svg|jpg|gif)$/,
            threshold: 10240,
            minRatio: 0.8,
            deleteOriginalAssets: true,
          })
        );
      return merge(commonConfig, productionConfig);
    default:
      throw new Error('No matching configuration was found!');
  }
};
  System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
    Memory: 8.06 GB / 15.81 GB
  Binaries:
    Node: 12.18.1 - ~\Apps\Node\node.EXE
    npm: 6.14.5 - ~\Apps\Node\npm.CMD
  npmPackages:
    clean-webpack-plugin: ^3.0.0 => 3.0.0 
    compression-webpack-plugin: ^4.0.1 => 4.0.1 
    html-webpack-plugin: ^4.3.0 => 4.3.0 
    optimize-css-assets-webpack-plugin: ^5.0.3 => 5.0.3 
    webpack: ^4.44.1 => 4.44.1 
    webpack-bundle-analyzer: ^3.8.0 => 3.8.0 
    webpack-cli: ^3.3.12 => 3.3.12 
    webpack-dev-server: ^3.11.0 => 3.11.0 
    webpack-merge: ^5.1.1 => 5.1.1 

Debug info

How do you use this module? As CLI utility or as plugin?
-Both

If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json)

If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true }))
new BundleAnalyzerPlugin()

What other Webpack plugins were used?
clean-webpack-plugin: ^3.0.0 => 3.0.0
compression-webpack-plugin: ^4.0.1 => 4.0.1
html-webpack-plugin: ^4.3.0 => 4.3.0
optimize-css-assets-webpack-plugin: ^5.0.3 => 5.0.3
webpack: ^4.44.1 => 4.44.1
webpack-bundle-analyzer: ^3.8.0 => 3.8.0
webpack-cli: ^3.3.12 => 3.3.12
webpack-dev-server: ^3.11.0 => 3.11.0
webpack-merge: ^5.1.1 => 5.1.1

@valscion
Copy link
Member

Thank you for opening this separate issue, it is now much clearer what is being asked! ☺️

If we'd want to support this, it might be enough to spot that file ends in .js.gz and then change this code:

function parseBundle(bundlePath) {
const content = fs.readFileSync(bundlePath, 'utf8');

to decompress the .js.gz file to plain JS file before continuing. A PR with a test case demonstrating that such a feature works would be nice ☺️

@RedVelocity
Copy link
Author

@valscion, I'd like to help but I'm not sure if my local fork is setup right because nothing I change(console logs, file writes) seem to reflect in the webpack build.

Steps:

  1. Fork main branch
  2. Install dependencies
  3. run npm start
  4. Goto test project and run npm link
  5. Build with webpack,

@valscion
Copy link
Member

Hmm, I'm hazy on how npm link works. The instructions in https://github.com/webpack-contrib/webpack-bundle-analyzer/blob/master/CONTRIBUTING.md should work but I haven't verified them in a while — let me know if there's something that does not work.

@xitter
Copy link

xitter commented Aug 28, 2020

I played around with this and was able to get content from the compressed file by doing:

content = zlib.unzipSync(fs.readFileSync(bundlePath)).toString();

Config which I kept was:

    output: {
        path: path.resolve('build'),
        filename: '[name].js',
    },
    plugins: [
        new BundleAnalyzerPlugin(),
        new CompressionPlugin({
            filename: '[path].gz',
            algorithm: 'gzip',
            test: /\.(js|jsx|css|html|png|svg|jpg|gif)$/,
            threshold: 10240,
            minRatio: 0.8,
            deleteOriginalAssets: true,
        }),
    ],

However, there is still a blank page for the above config. Reason being that when stats.toJSON() call tries to map chunks at stats/DefaultStatsFactoryPlugin.js#L260, it sees that compilation.chunks have filename as test.js, while the compilation.asset has filename as test.js.gz, and thus it thinks that chunks aren't available for test.js.gz asset. Due to which this plugin isn't able to map modules to any chunks.

But, there is a way to fix this by keeping output filename and compressed filename same, like:

    output: {
        path: path.resolve('build'),
        filename: '[name].js.gz',  // changed
    },
    plugins: [
        new BundleAnalyzerPlugin(),
        new CompressionPlugin({
            filename: '[path]',     // changed
            algorithm: 'gzip',
            test: /\.(js|jsx|css|html|png|svg|jpg|gif)$/,
            threshold: 10240,
            minRatio: 0.8,
            deleteOriginalAssets: true,
        }),
    ],

This way webpack can map the chunks to compressed file and so can BundlerAnalyzer. And all stats are generated correctly.

@valscion let me know if it makes sense, I can raise a PR for this.

PS: There is an issue logged for this in compression-plugin webpack-contrib/compression-webpack-plugin#49

@RedVelocity
Copy link
Author

@xitter, great stuff! were you able to test it out with Brotli compression as well or that would be a different feature request?

@valscion
Copy link
Member

Brotli is a different feature request :)

@valscion
Copy link
Member

Sorry, don't have time to reply thoroughly to your comment yet, @xitter — sounds like you have made some progress and a PR could be useful

@xitter
Copy link

xitter commented Aug 28, 2020

@RedVelocity @valscion Brotli also worked well as zlib supports it, PR on the way.

Config for brotli:

new CompressionPlugin({
  filename: '[path].br',
  algorithm: 'brotliCompress',
  test: /\.(js|jsx|css|html|png|svg|jpg|gif)$/,
  compressionOptions: {
     // zlib’s `level` option matches Brotli’s `BROTLI_PARAM_QUALITY` option.
     level: 11,
  },
  threshold: 10240,
  minRatio: 0.8,
  deleteOriginalAssets: true,
});

@xitter
Copy link

xitter commented Aug 31, 2020

Made a PR(#379), please have a look.

@grug
Copy link

grug commented Sep 14, 2022

Was there ever a resolution to this? I'm currently in a situation where we use compression-webpack-plugin for our builds and this is causing blank pages for the bundle analyzer.

@valscion
Copy link
Member

Looks like #379 PR is open but the review by @th0r seems to be incomplete

@grug
Copy link

grug commented Sep 15, 2022

For the time being I've just had to run a separate build and pass in a "isStatsBuild" parameter to webpack to omit the compression. It works - not ideal, though.

@webpack-contrib webpack-contrib locked and limited conversation to collaborators Feb 23, 2023
@valscion valscion converted this issue into discussion #584 Feb 23, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

4 participants