How to get a list of all files (or modules) included per chunk in Webpack

Can't seem to find any debug option or plugin in webpack to show what exactly went into a chunk.

Why do I need this? I've noticed cases where code splitting literally makes everything much larger then just sticking everything in a single file. This is a bit counter intuitive since I don't believe the bootstrap code from webpack is that significant; I suspect it might be minification/deduping, but with out knowing which modules are actually being chunked togheter it's very hard to do some isolated tests to confirm.

My build process uses gulp; if that makes any difference.


Solution 1:

Webpack 5.x:

$ webpack --stats-modules-space 999

Before Webpack 5.x:

It seems that it has the parameter called --display-modules to show all the modules as follows:

$ webpack --display-modules

Then you will get the list of used modules similar the following:

                   Asset     Size  Chunks             Chunk Names
javascripts/webpack/app.js   211 kB       0  [emitted]  javascripts/webpack/app
stylesheets/webpack/app.js  4.13 kB       1  [emitted]    stylesheets/webpack/app
stylesheets/webpack/app.scss  2.99 kB       1  [emitted]  stylesheets/webpack/app
[0] ./app/webpack/js/behaviors/lory-icon-slider.js.coffee 1.1 kB {0} [optional] [built]
[1] ./app/webpack/css/components (\.scss|\.css)$ 160 bytes {1} [built]
[2] ./app/webpack/js/behaviors (\.js|\.js.jsx|\.js.coffee)$ 252 bytes {0} [built]
[3] ./~/pickmeup/css/pickmeup.scss 41 bytes {1} [built]
[4] ./app/webpack/css/app.js 205 bytes {1} [built]
[5] ./app/webpack/js/app.js 250 bytes {0} [built]
[6] ./app/webpack/js/behaviors/pickmeup-fixed-calendar.js 3.47 kB {0} [optional] [built]
[7] ./~/lory.js/dist/jquery.lory.js 25 kB {0} [built]
[8] ./~/pickmeup/js/pickmeup.js 41.4 kB {0} [built]
[9] (webpack)/buildin/global.js 509 bytes {0} [built]
Child extract-text-webpack-plugin:
   [0] ./~/css-loader/lib/css-base.js 1.51 kB {0} [built]
   [1] ./~/css-loader!./~/sass-loader/lib/loader.js!./~/pickmeup/css/pickmeup.scss 3.23 kB {0} [built]

Solution 2:

You can write a plugin that does this.

For example,

var PrintChunksPlugin = function() {};
PrintChunksPlugin.prototype.apply = function(compiler) {
    compiler.plugin('compilation', function(compilation, params) {
        compilation.plugin('after-optimize-chunk-assets', function(chunks) {
            console.log(chunks.map(function(c) {
                return {
                    id: c.id,
                    name: c.name,
                    includes: c.modules.map(function(m) {
                        return m.request;
                    })
                };
            }));
        });
    });
};

For more details, check this page http://webpack.github.io/docs/plugins.html . It contains documentation for all the places you can hook into. Find the proper hook which gets called with chunks: Chunk[] or chunk, and inside this you'll be able to access everything you want.

Also, the stats object contains all the post-build information you'd ever need. It's available in the done plugin.

Solution 3:

This is an updated version of Boopathi Rajaa's answer that will work for later versions of Webpack (I'm using 4.37.0)

This updated version worked for me:

class PrintChunksPlugin {
    apply (compiler) {
        compiler.plugin('compilation', compilation => {
            compilation.plugin('after-optimize-chunk-assets', chunks => {
                console.log(chunks.map(chunk => ({
                    id: chunk.id,
                    name: chunk.name,
                    modules: Array.from(chunk._modules).map(module => module.id)
                })))
            })
        })
    }
}

Usage:

plugins: [
    new PrintChunksPlugin(),
]

The big difference is that they now store the module information in _modules rather than modules and it isn't a mappable object before the Array.from. I found module.id to be closer to what I needed, but module.request is still there if you need that.

Solution 4:

And here is also a plugin compatible with webpack4, that outputs all your chunks to a single JSON file.

https://www.npmjs.com/package/chunks-2-json-webpack-plugin

Here is how you can use it:

1) In your webpack config file, import the plugin (after you've installed it of course :) - npm i --save-dev chunks-2-json-webpack-plugin) and instantiate it under plugins key.

const Chunks2JsonPlugin = require('chunks-2-json-webpack-plugin');
const path = require('path');

const publicPath = '/app/';

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].[hash].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath
  },
  plugins: [
    new Chunks2JsonPlugin({ outputDir: 'dist/', publicPath })
  ]
};

And that's pretty much it, what you will get as a result is a JSON file, that will look something like this:

{
  "chunk-vendors": {
    "js": ["/app/js/chunk-vendors.fc40696c.js"],
    "js.map": ["/app/js/chunk-vendors.fc40696c.js.map"]
  },
  "app": {
    "css": ["/app/css/app.eb829ccc.css"],
    "js": ["/app/js/app.dd31cdcb.js"],
    "js.map": ["/app/js/app.dd31cdcb.js.map"]
  }
}

Here, we have all our chunks in a single JSON file.

More information you can find on the link itself.