How to Leverage Webpack Stats for Dependency Analysis and Build Optimization

This article explains how to use Webpack's stats object to generate a JSON report of module dependencies and compilation performance, enabling developers to visualize the dependency graph, identify impact of changes, and fine‑tune build speed and bundle size.

ELab Team
ELab Team
ELab Team
How to Leverage Webpack Stats for Dependency Analysis and Build Optimization

Meta

Abstract

This talk explains how to use Webpack's stats object to analyze dependencies and compilation speed. The object contains extensive build‑time information that can be exported as a JSON file, helping developers understand the module graph and optimize build performance.

Outline

Describe the problem encountered during development and the proposed solution.

Explain core Webpack concepts such as module , chunk , and bundle .

Detail the process of constructing module dependency relationships during compilation.

Introduce the stats object, its origin, contained information, and how to export stats.json.

Show how to use the exported data to analyze module dependencies with related tools.

Audience Benefits

After the session, attendees should understand Webpack's module and chunk relationships, be able to retrieve module dependency information from stats.json, and determine which components are affected by changes for more effective regression testing.

Introduction

In everyday development, modifying a shared component that is referenced in many places makes it difficult to manually locate all affected business scenarios, especially when taking over a project or after a long time. Relying on manual searches is error‑prone and can lead to incomplete regression testing.

Solution

Concept Definitions

First we define several concepts for clarity:

1. Module : A discrete piece of code before compilation; each source file is a module.

2. Chunk : A Webpack‑specific term used internally to manage bundling. A bundle consists of chunks; an entry file typically generates a corresponding chunk.

3. Bundle : The final compiled output that contains many modules. After processing chunks, Webpack emits the bundle that runs in the browser.

Dependency Construction Process

The build phase starts from the entry and recursively resolves resources and their dependencies. Within the compilation object, Webpack builds a collection of module objects and their dependency links. The core flow is illustrated below:

The steps are:

Call handleModuleCreate to create a module instance based on file type.

Run loaders via runLoaders to transform the module content to JavaScript.

Parse the JavaScript with acorn to produce an AST.

Traverse the AST, triggering hooks such as HarmonyExportDependencyParserPlugin to discover import/export specifiers.

Add discovered dependencies to the module via addDependency.

After AST traversal, call module.handleParseResult to finalize dependencies.

For each new dependency, repeat the process by invoking handleModuleCreate again.

When all dependencies are resolved, the build phase ends.

The data flow is module → ast → dependencies → module, requiring loaders to output standard JavaScript that can be parsed by acorn. For assets like images, loaders must emit either a base64 data URL or a plain URL.

Example: Hierarchical Progression

Consider the following file dependency tree:

index.js

is the entry file, depending on a.js and b.js; a.js further depends on c.js and d.js. After initializing the compilation, EntryPlugin locates index.js and triggers compilation.addEntry, producing a data structure that records module relationships.

The process continues recursively, parsing a.js, b.js, then c.js / d.js, until no new dependencies are found.

Stats Configuration

The stats option controls what information Webpack prints. It can be exported to a JSON file with: webpack --profile --json > stats.json Key configuration fields (default values shown) include:

module.exports = {
  ...
  stats: {
    all: undefined,
    assets: true,
    assetsSort: "field",
    builtAt: true,
    cached: true,
    cachedAssets: true,
    children: true,
    chunks: true,
    chunkModules: true,
    chunkOrigins: true,
    chunksSort: "field",
    context: "../src/",
    colors: false,
    depth: false,
    entrypoints: false,
    env: false,
    errors: true,
    errorDetails: true,
    excludeAssets: "filter",
    excludeModules: "filter",
    exclude: "filter",
    hash: true,
    maxModules: 15,
    modules: true,
    modulesSort: "field",
    moduleTrace: true,
    performance: true,
    providedExports: false,
    publicPath: true,
    reasons: true,
    source: true,
    timings: true,
    usedExports: false,
    version: true,
    warnings: true,
    warningsFilter: "filter"
  }
};

stats.json Structure

The top‑level JSON contains fields such as version, hash, time, assets, chunks, modules, errors, and warnings. Each section has its own schema:

Asset Objects

{
  "chunkNames": [],
  "chunks": [10, 6],
  "emitted": true,
  "name": "10.web.js",
  "size": 1058
}

Chunk Objects

{
  "entry": true,
  "files": [],
  "id": 0,
  "initial": true,
  "modules": [],
  "names": [],
  "origins": [],
  "parents": [],
  "rendered": true,
  "size": 188057
}

Module Objects

{
  "assets": [],
  "built": true,
  "cacheable": true,
  "chunks": [],
  "errors": 0,
  "failed": false,
  "id": 0,
  "identifier": "(webpack)\\test\\browsertest\\lib\\index.web.js",
  "name": "./lib/index.web.js",
  "optional": false,
  "prefetched": false,
  "profile": {
    "building": 73,
    "dependencies": 242,
    "factory": 11
  },
  "reasons": [],
  "size": 3593,
  "source": "// Should not break it...
if(typeof...",
  "warnings": 0
}

Errors and Warnings

Both are arrays of strings containing messages and stack traces, e.g.:

../cases/parsing/browserify/index.js
Critical dependencies:
2:114-121 This seem to be a pre‑built javascript file. ...
@ ../cases/parsing/browserify/index.js 2:114-121

Best Practices

Provide a concise summary, methodology, and patterns so the audience gains a strong sense of growth and achievement.

To generate stats.json locally, add a stats field to webpack.config.js:

module.exports = {
  ...
  stats: {
    chunkModules: false,
    chunks: false,
    modules: true,
    children: false,
    exclude: [/.*node_modules\/.*\/]
  }
};

Run:

webpack --config webpack.config.js --profile --json > stats.json

Online Analysis

Webpack provides an online visualizer Webpack Analyse that parses the uploaded stats.json locally in the browser. It displays Modules, Chunks, Assets, Warnings, Errors, and Hints, allowing you to click a module and see its inbound and outbound dependencies.

Manual Parsing for Dependency Chains

Using the modules array and each module's reasons, you can build a tree from a changed module upward, then extract all paths to determine affected components. Example Node.js script:

const fs = require('fs');
const _ = require('lodash');
fs.readFile('../../nodeServerClient/stats.json', 'utf8', (err, data) => {
  if (err) { console.error(err); return; }
  const fileObj = JSON.parse(data);
  const moduleArr = fileObj.modules;
  const moduleMap = {};
  moduleArr.forEach(m => { moduleMap[m.nameForCondition] = m; });
  const filename = '/Users/.../src/controller/ser.js';
  const tree = [];
  function createTree(name, node) {
    const mod = moduleMap[name];
    if (!mod) return;
    const current = { name: mod.nameForCondition, children: [] };
    node.push(current);
    if (mod.reasons && mod.reasons.length) {
      mod.reasons.forEach(r => {
        if (r.type !== 'entry' && r.resolvedModuleIdentifier !== node[node.length-1].name) {
          createTree(r.resolvedModuleIdentifier, current.children);
        }
      });
    }
  }
  createTree(filename, tree);
  const paths = [];
  function collect(node, path) {
    node.forEach(n => {
      const newPath = path.concat(n.name);
      if (n.children.length) collect(n.children, newPath);
      else paths.push(_.cloneDeep(newPath));
    });
  }
  collect(tree, []);
  paths.forEach(p => p.reverse());
  console.log(JSON.stringify(paths, null, 2));
});

Future Outlook

Potential extensions include integrating dependency analysis into CI pipelines (e.g., during yarn commit or Git merge requests) to automatically suggest test scopes based on changed files.

References

https://segmentfault.com/a/1190000039956437

https://gitmind.cn/app/doc/fac1c196e29b8f9052239f16cff7d4c7

https://webpack.wuhaolin.cn/4%E4%BC%98%E5%8C%96/4-15%E8%BE%93%E5%87%BA%E5%88%86%E6%9E%90.html

https://www.webpackjs.com/api/stats/#asset-objects

https://webpack.github.io/analyse/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Build OptimizationwebpackDependency Analysismodule graph_stats
ELab Team
Written by

ELab Team

Sharing fresh technical insights

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.