webpack-bundle-analyzer
webpack-bundle-analyzer copied to clipboard
Feature Request: Analyze gzipped bundles
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
Thank you for opening this separate issue, it is now much clearer what is being asked! :relaxed:
If we'd want to support this, it might be enough to spot that file ends in .js.gz
and then change this code:
https://github.com/webpack-contrib/webpack-bundle-analyzer/blob/b618f652db9f0870dcf92c15a7b7cd95f496bd94/src/parseUtils.js#L10-L11
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 ☺️
@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:
- Fork main branch
- Install dependencies
- run npm start
- Goto test project and run npm link
- Build with webpack,
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.
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 https://github.com/webpack-contrib/compression-webpack-plugin/issues/49
@xitter, great stuff! were you able to test it out with Brotli compression as well or that would be a different feature request?
Brotli is a different feature request :)
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
@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,
});
Made a PR(https://github.com/webpack-contrib/webpack-bundle-analyzer/pull/379), please have a look.
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.
Looks like #379 PR is open but the review by @th0r seems to be incomplete
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.