javascriptwebpackmanifestsource-mapswebpack-5

How can I retrieve/generate a list source files for each chunk file in Webpack 5?


Using Webpack5, I need a manifest with the source files containing in each chunk. That is, for each file [name].[id].[hash].js (e.g. myapp.931.48654ad6a4s6d.js) created during build, I need a list of all files that were bundled in that chunk, for each chunk.

I have tried webpack-assets-manifest and webpack-manifest-plugin, but what they generate is not enough, as they only provide a list of files with and without hash, e.g.:

  "js/app.930.js": "/app/static/js/app.930.59370e27f67ee1c4d4b8.js",

I have tried as well Webpack's own recordsPath configuration, which was nearest to what I need, but this also is incomplete as does not list all files in each chunk, only the file that initiated the chunk split (the file which has import('somefile') and the 'somefile' name), e.g.:

{
  "chunks": {
    "byName": {
      "app": 143,
      "main": 179,
      "polyfills": 429,
      "runtime": 666,
      "vendor.common": 149
    },
    "bySource": {
      "0 ./node_modules/babel-loader/lib/index.js??clonedRuleSet-6.use!../../../../../../../../../../../Absolute/path/to/my/app/folder/fileThatUsesImportStatement.ext TheImportedFile.ext": 930,
    (...)

I need basically the information that each sourcemap (.js.map) provides in it's "sources", that is:

{
   (...)
   "file":"js/app.930.59370e27f67ee1c4d4b8.js",
   "sources":[
"webpack://dependencyname/../../../../../../../../../../../Absolute/path/to/my/app/folder/originalFilenameInThisChunk.ext",
"webpack://dependencyname/../../../../../../../../../../../Absolute/path/to/my/app/folder/anotherOriginalFilenameInThisChunk.ext"
   ],
   (...)

In sum, I am looking for a way to generate a manifest of chunkfile -> List of files in it, for example:

{
  "app.930.59370e27f67ee1c4d4b8.js": [
     "/path/to/my/app/folder/originalFilenameInThisChunk.ext",
     "/path/to/my/app/folder/anotherOriginalFilenameInThisChunk.ext",
     (...)
  ],
  "anotherchunkfile.js": [
      "/path/to/importedfiles.ext",
     (...)
   ],
  (...)

Is it possible somehow to retrieve this information in Webpack (maybe as a plugin entry, during build) without I manually needing to write a standalone code to read each .map file and do the json manually (which will be ultra slow opening each map with fs.readfile)?


Solution

  • You can use the npm module webpack-stats-plugin for this.

    With this configuration for example:

    const { StatsWriterPlugin } = require("webpack-stats-plugin");
    
    module.exports = {
      plugins: [
        // ...
        new StatsWriterPlugin({
          stats: {
            fields: ["assets"]
          },
          filename: "stats.json",
        }),
      ],
    };
    

    It creates a detailed list in a JSON file (stats.json) of the files used.

    The output looks something like this:

      "assets": [
        {
          "type": "asset",
          "name": "main.js",
          "size": 737766,
          "emitted": false,
          "comparedForEmit": false,
          "cached": true,
          "info": {
            "javascriptModule": false,
            "related": {
              "sourceMap": "main.js.map"
            }
          },
          ...