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.
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.jsis 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-121Best 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.jsonOnline 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/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
