# Behavior traces — webpack/webpack

> Canonical page: https://codevetter.com/unpack/webpack/behavior-traces

# Behavior traces — webpack/webpack

Scanned commit 87a62dec2304cd2c163c41feeeb43fbe3e5c21dd (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Four flows are worth walking: a one-shot `webpack(config, cb)` run, a single module's resolve→build→parse path, a watch rebuild, and the persistent-cache store/restore path. Each is a callback chain rather than promises, with `tapable` hooks at every joint and `logger.time`/`timeEnd` pairs marking the phases you see in `stats` profiling output. The names below are the actual functions in call order.
- Startup (one-shot): `webpack(options, cb)` → `create()` → schema check → `createCompiler` → `compiler.run(cb)`; `run` calls `cache.endIdle` if idle, then `hooks.beforeRun` → `hooks.run` → `readRecords` → `compile(onCompiled)`. — [lib/webpack.js#L255-330](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/webpack.js#L255-L330) [lib/Compiler.js#L578-710](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compiler.js#L578-L710)
- `Compiler.compile` runs `newCompilationParams()` → `hooks.beforeCompile` → `hooks.compile` → `newCompilation(params)` → `hooks.make` → `hooks.finishMake` → `process.nextTick` → `compilation.finish` → `compilation.seal` → `hooks.afterCompile`, timing each phase with the `webpack.Compiler` logger. — [lib/Compiler.js#L1602-1648](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compiler.js#L1602-L1648)
- Completion: `onCompiled` checks `hooks.shouldEmit`; if emitting it defers a `process.nextTick`, calls `emitAssets`, re-enters `compile` when `needAdditionalPass` is true, then `emitRecords` → build `new Stats(compilation)` → `hooks.done` → `cache.storeBuildDependencies` → `finalCallback`, which sets `cache.beginIdle()` and fires `hooks.afterDone`. — [lib/Compiler.js#L596-700](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compiler.js#L596-L700)
- The callback form of `webpack()` always closes the compiler for you — `compiler.run((err, stats) => compiler.close((err2) => callback(err || err2, stats)))` — which is why plugin authors using the no-callback form must call `close` themselves. — [lib/webpack.js#L300-320](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/webpack.js#L300-L320)
- Module creation: `Compilation.handleModuleCreation` → `factorizeQueue` → `NormalModuleFactory.create` → `hooks.beforeResolve` (a `false` result short-circuits to an ignored module) → `hooks.factorize`/`resolveResource` → `hooks.afterResolve` → `hooks.createModule`/`createModuleClass` → `hooks.module` waterfall. — [lib/Compilation.js#L2441-2500](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compilation.js#L2441-L2500) [lib/module/NormalModuleFactory.js#L1269-1340](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L1269-L1340) [lib/module/NormalModuleFactory.js#L1381-1460](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L1381-L1460)
- Module build: `NormalModule.build` → `_doBuild` → `runLoaders` (pitch pass, `processResource`, normal pass) → on success the parser runs and dependencies are collected; every failure path funnels through `markModuleAsErrored(err)` followed by `_initBuildHash(compilation)` so an errored module still has a hash. — [lib/module/NormalModule.js#L1676-1760](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModule.js#L1676-L1760) [lib/module/NormalModule.js#L1339-1470](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModule.js#L1339-L1470) [lib/module/NormalModule.js#L1596-1675](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModule.js#L1596-L1675)
- Parser and generator instances are resolved per module type through `NormalModuleFactory.getParser`/`createParser` and `getGenerator`/`createGenerator`, cached in `parserCache`/`generatorCache` as `Map<type, WeakMap<options, instance>>`, and a type's one-time async setup runs through the `prepareModuleType` HookMap with in-flight callers queued. — [lib/module/NormalModuleFactory.js#L1946-2040](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L1946-L2040) [lib/module/NormalModuleFactory.js#L690-702](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L690-L702) [lib/module/NormalModuleFactory.js#L656-657](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/module/NormalModuleFactory.js#L656-L657)
- Seal, in order: clear queues in `finalCallback`, optionally re-attach `ChunkGraph` per module for `backCompat`, `hooks.seal`, loop `hooks.optimizeDependencies` until it returns falsy, `hooks.beforeChunks`, `moduleGraph.freeze("seal")`, entry→chunk creation with `assignDepths`, then the optimize/hash/codegen/assets tail. — [lib/Compilation.js#L3612-3700](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compilation.js#L3612-L3700) [lib/Compilation.js#L3900-3999](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compilation.js#L3900-L3999)
- Watch rebuild: `Watching._invalidate` → `_go(fileTimeInfoEntries, contextTimeInfoEntries, changedFiles, removedFiles)` → `compiler.compile` → `_done(err, compilation)`, which re-enters `_go` when `this.invalid` was set during the run; `_done` is pre-bound in the constructor and the first pass is kicked off by `_invalidate` when `_initial`. — [lib/watch/Watching.js#L26-130](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/watch/Watching.js#L26-L130) [lib/watch/Watching.js#L273-320](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/watch/Watching.js#L273-L320) [lib/watch/Watching.js#L450-470](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/watch/Watching.js#L450-L470)
- Persistence: `IdleFileCachePlugin` taps `cache.hooks.store` to queue `strategy.store(identifier, etag, data)` and `cache.hooks.get` to `strategy.restore(...)`, then flushes on an idle timer whose delay is the smaller of `idleTimeout` and `idleTimeoutForInitialStore`, with `idleTimeoutAfterLargeChanges` as a third setting. — [lib/cache/IdleFileCachePlugin.js#L21-120](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/IdleFileCachePlugin.js#L21-L120)
- A cache pack is read lazily by location: `Pack.get(identifier, etag)` looks the identifier up in `itemInfo`, finds its `location`, and only then materializes that `PackContent`'s map — so restoring one module does not deserialize the whole pack. — [lib/cache/PackFileCacheStrategy.js#L203-235](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/PackFileCacheStrategy.js#L203-L235) [lib/cache/PackFileCacheStrategy.js#L903-990](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/cache/PackFileCacheStrategy.js#L903-L990)
- Shutdown: `Compiler.close` first closes any active `watching`, fires `hooks.shutdown`, then defers `_releaseUnusedCompilationData(lastCompilation)` behind `Promise.resolve().then(...)` so a `close()` made inside the run callback cannot release `codeGenerationResults` before `afterDone` fires on the same stack, and finally calls `cache.shutdown(callback)`. — [lib/Compiler.js#L1654-1690](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/Compiler.js#L1654-L1690)
- Minification is a late `processAssets` stage, not part of codegen: `optimization.minimizer` defaults to a plugin wrapper that lazily requires `minimizer-webpack-plugin` at apply time and only constructs it once it knows which of JS/CSS/HTML are actually enabled (returning early if none are). — [lib/config/defaults.js#L2521-2575](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/lib/config/defaults.js#L2521-L2575)
- Test execution mirrors the real runtime rather than mocking it: `test/templates/ConfigTestCases.js` runs a real `webpack()` build, resolves the bundle via a per-case `findBundle`, and executes it in a `vm` context — `test/harness/runner/asModule.js` even builds `vm.SyntheticModule`/`SourceTextModule` wrappers so ESM output is linked and evaluated for real. — [test/templates/ConfigTestCases.js#L94-260](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/test/templates/ConfigTestCases.js#L94-L260) [test/templates/ConfigTestCases.js#L600-640](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/test/templates/ConfigTestCases.js#L600-L640) [test/harness/runner/asModule.js#L1-60](https://github.com/webpack/webpack/blob/87a62dec2304cd2c163c41feeeb43fbe3e5c21dd/test/harness/runner/asModule.js#L1-L60)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
