The Module Graph is webpack's central data structure for tracking module-to-module relationships, dependencies, and export/import information during compilation. It provides APIs to query which modules depend on which other modules, what each module exports, and how those exports are used across the module graph. This information enables optimizations like tree shaking and dead code elimination.
The Module Graph is distinct from the Chunk Graph (see Chunk Graph Construction). The Module Graph represents source-level dependencies between modules, while the Chunk Graph represents output-level grouping of modules into chunks for the final bundle.
Sources: lib/ModuleGraph.js1-1000
The ModuleGraph class is the primary interface for accessing module relationship data. It is created once per Compilation and stored at compilation.moduleGraph.
Key Data Structures:
| Property | Type | Purpose |
|---|---|---|
_moduleMap | WeakMap<Module, ModuleGraphModule> | Maps each module to its graph metadata |
_dependencyMap | WeakMap<Dependency, ModuleGraphConnection> | Maps dependencies to their resolved connections |
_originMap | WeakMap<Module, ModuleGraphDependency[]> | Maps modules to dependencies originating from them |
_metaMap | WeakMap<Dependency, any> | Stores arbitrary metadata for dependencies |
Sources: lib/ModuleGraph.js36-140 lib/ModuleGraph.js174-218
ModuleGraphModule holds per-module metadata within the graph:
incomingConnections: Set of connections where this module is the targetoutgoingConnections: Set of connections where this module is the sourceexports: ExportsInfo object tracking what this module exportsissuer: The module that caused this module to be includedprofile: Optional profiling data for build timingasync: Whether this module is async (top-level await)Sources: lib/ModuleGraph.js66-94
ModuleGraphConnection represents a dependency relationship between two modules:
Key Properties:
| Property | Type | Purpose |
|---|---|---|
originModule | Module | null | Source module of the dependency |
resolvedModule | Module | Target module that the dependency resolves to |
dependency | Dependency | The dependency object itself |
active | boolean | Whether this connection is active (not tree-shaken) |
conditional | boolean | Whether the connection is conditional on runtime |
weak | boolean | Whether this is a weak dependency |
Sources: lib/ModuleGraphConnection.js1-350
The Module Graph is built incrementally during the compilation's make phase:
setResolvedModule(dependency, module): Creates a connection from a dependency to its resolved module.
updateModule(dependency, module): Updates which module a dependency resolves to (used during module rebuilds).
Sources: lib/ModuleGraph.js456-600 lib/Compilation.js1600-1800
The ModuleGraph provides numerous query methods:
| Method | Returns | Purpose |
|---|---|---|
getModule(dependency) | Module | null | Get the module a dependency resolves to |
getParentModule(dependency) | Module | null | Get the module containing a dependency |
getOrigin(module) | Module | null | Get the first module that depended on this module |
getIssuer(module) | Module | null | Get the module that triggered inclusion of this module |
Sources: lib/ModuleGraph.js241-330
Key Connection Methods:
getConnection(dependency): Get the connection for a specific dependencygetOutgoingConnections(module): Get all connections originating from a modulegetIncomingConnections(module): Get all connections targeting a modulesetResolvedModule(dependency, module): Create or update a connectionSources: lib/ModuleGraph.js456-600
Each module has an ExportsInfo object that tracks its exports:
| Property | Type | Purpose |
|---|---|---|
provided | boolean | null | undefined | Whether the export is actually provided by the module |
used | UsageState | How the export is used: Unused, OnlyPropertiesUsed, Used, etc. |
usedName | string | false | The name used in output (for mangling) or false if unused |
canMangleProvide | boolean | Whether the export name can be mangled |
canMangleUse | boolean | Whether usage can reference a mangled name |
exportsInfoOwned | boolean | Whether this export has its own ExportsInfo (for namespace objects) |
Sources: lib/ExportsInfo.js1-200 lib/ExportsInfo.js400-600
Setting Usage:
exportsInfo.setUsedInUnknownWay(runtime): Mark all exports as potentially usedexportsInfo.setUsedWithoutInfo(runtime): Mark as used but no specifics knownexportInfo.setUsed(usageState, runtime): Set specific usage stateQuerying Usage:
exportInfo.isUsed(runtime): Check if export is usedexportInfo.getUsed(runtime): Get the UsageStateexportsInfo.getUsedExports(runtime): Get list of used export namesexportInfo.getUsedName(name, runtime): Get the mangled name if applicableSources: lib/ExportsInfo.js700-1200 lib/FlagDependencyUsagePlugin.js1-400
The ModuleGraph is created in the Compilation constructor and stored as compilation.moduleGraph:
All operations that need to query or modify module relationships access this shared instance.
Sources: lib/Compilation.js700-750
| Phase | Module Graph Operations |
|---|---|
| Module Creation | setResolvedModule(), setIssuer(), setParentBlock() |
| Module Building | Dependencies added; connections created |
| Dependency Optimization | optimizeDependencies hook; connections may be marked inactive |
| Export Discovery | FlagDependencyExportsPlugin populates ExportsInfo |
| Usage Tracking | FlagDependencyUsagePlugin marks used/unused exports |
| Tree Shaking | SideEffectsFlagPlugin reads usage info to remove modules |
| Module Concatenation | ModuleConcatenationPlugin reads connections to merge modules |
| Chunk Graph Construction | buildChunkGraph() reads connections to assign modules to chunks |
Sources: lib/Compilation.js2700-3000 lib/FlagDependencyExportsPlugin.js1-300 lib/FlagDependencyUsagePlugin.js1-300
Different dependency types create different kinds of connections:
| Dependency Type | Conditional | Weak | Description |
|---|---|---|---|
HarmonyImportDependency | false | false | Static ES import |
HarmonyImportSpecifierDependency | false | false | Named ES import |
ImportDependency | true | false | Dynamic import() |
ImportWeakDependency | true | true | Dynamic import() with webpackMode: "weak" |
CommonJsRequireDependency | false | false | Static require() |
Sources: lib/dependencies/HarmonyImportDependency.js1-200 lib/dependencies/ImportDependency.js1-200
The Module Graph tracks async modules (modules with top-level await):
This information is used to determine which modules need async handling in the runtime.
Sources: lib/ModuleGraph.js900-950
When --profile is enabled, the Module Graph stores timing information:
Sources: lib/ModuleGraph.js850-900
The Module Graph maintains bidirectional references:
originModule → dependency → resolvedModulemodule.incomingConnections tracks all dependencies targeting this moduleThis enables efficient queries like "which modules import this module?" without scanning all modules.
Sources: lib/ModuleGraph.js330-400
The Module Graph integrates with several other webpack systems:
Sources: lib/ModuleGraph.js1-100 lib/Compilation.js2700-3000
Refresh this wiki