How Does Webpack Use Loaders in Asset Compilation?
Webpack relies on loaders as module-level preprocessors that translate non-JavaScript assets into valid modules ready for the dependency graph. During asset compilation, Webpack resolves dependencies, matches source files against defined module rules, executes loader pipelines across distinct pitching and normal execution phases, and finally passes standard JavaScript or asset structures to its internal parser.
Resolution and Rule Matching
Asset compilation begins when Webpack traces an import statement from
an entry point or intermediate module. By default, Webpack natively
understands standard JavaScript and JSON. When it encounters other file
formats—such as TypeScript, SCSS, or static SVGs—it consults the
module.rules array declared in the configuration.
Each rule typically defines a regular expression in the
test property and an array of transformers in the
use field. Webpack matches the file’s absolute path against
these conditions. Once a match is confirmed, Webpack resolves the
necessary loader packages from node_modules and constructs
an execution pipeline specifically tailored to that resource.
The Two-Phase Pipeline: Pitching vs. Normal
Loaders do not simply execute linearly; they operate in two distinct stages known as the pitching phase and the normal phase.
Loader Pipeline: [Loader A, Loader B, Loader C]
1. Pitch Phase (Left-to-Right)
Loader A.pitch() -> Loader B.pitch() -> Loader C.pitch()
|
Fetch raw resource
|
2. Normal Phase (Right-to-Left)
Loader A() <- Loader B() <- Loader C()
- The Pitching Phase (Left to Right): Execution
traverses forward through the loader chain. If a loader exports a
pitchmethod, Webpack executes it before reading the target file. If apitchmethod returns a defined value, Webpack immediately short-circuits the pipeline, skipping the remaining pitch methods, bypassing reading the resource from disk, and passing that returned value directly to the previous loader's normal phase. This mechanism is crucial for caching, metadata inspection, and loaders likestyle-loaderthat inject inline runtime scripts without reading raw source code directly through the rest of the chain. - The Normal Phase (Right to Left / Bottom to Top): If no loader short-circuits during the pitch stage, Webpack reads the target file from the filesystem into memory as a string or Buffer. The loader chain then executes in reverse. The first loader in this phase (the last listed in configuration) receives the raw file contents, transforms it, and returns the modified result. Each preceding loader takes the output of its predecessor as input, progressively compiling the asset.
Concrete Transformation: An SCSS Pipeline
Consider a standard style pipeline configured as
use: ['style-loader', 'css-loader', 'sass-loader']:
sass-loaderexecutes first in the normal phase, turning raw SCSS syntax into standard CSS text.css-loaderaccepts the resulting CSS string and resolves@importrules, local url paths, and CSS Module mappings into CommonJS/ES module syntax.style-loaderwraps that output into runtime JavaScript code that creates `