Frontend Development 13 min read

Understanding Webpack Loaders: Types, Configuration, Execution Order, and API

This article explains what Webpack loaders are, their four classification types (pre, normal, inline, post), how to configure them with enforce, the inline loader prefixes, execution priority, the loader call chain, synchronous vs asynchronous handling, parameters, output, caching, and useful loader development tools.

ByteFE
ByteFE
ByteFE
Understanding Webpack Loaders: Types, Configuration, Execution Order, and API

What is a loader

Webpack can only understand JavaScript and JSON files out of the box; loaders enable it to process other file types by converting them into modules that can be added to the dependency graph. A loader is essentially a JavaScript module that exports a function.

Loader classification

In Webpack, loaders are divided into four categories: post , normal , inline , and pre .

enforce

The category of a loader is determined by the Rule.enforce value in the configuration. It can be pre , post , or omitted (defaulting to normal ).

inline

Inline loaders are written directly in the import / require statement. Three prefix syntaxes control which loaders are ignored:

! – ignore normal loaders.

-! – ignore pre and normal loaders.

!! – ignore all loaders ( pre , normal , post ).

After the prefix, loaders are separated by ! , and optional query parameters can be passed with ? .

example

Assume a-loader is a pre loader, b-loader is a normal loader, and c-loader is a post loader. Various import statements illustrate how the prefixes affect the execution order.

// No prefix
import "/Users/jiangyuereee/Desktop/loader/d-loader.js!./txt.txt";
// ! prefix
import "!/Users/jiangyuereee/Desktop/loader/d-loader.js!./txt.txt";
// -! prefix
import "-!/Users/jiangyuereee/Desktop/loader/d-loader.js!./txt.txt";
// !! prefix
import "!!/Users/jiangyuereee/Desktop/loader/d-loader.js!./txt.txt";

Loader priority

The call order from highest to lowest priority is pre > normal > inline > post . Within the same category, loaders are invoked from bottom to top and right to left (the normal functions run in reverse order, while pitch functions run left to right).

Loader call chain

Each loader has a normal function and an optional pitch function. The process starts by invoking all pitch functions from left to right; then the normal functions are called from right to left, forming an onion‑like model.

Loader – pitch

Loaders are always called from right to left. Some loaders only care about the metadata after the request and ignore the result of the previous loader. Before the right‑to‑left execution, their pitch methods are called from left to right.

If a pitch method returns a value, the remaining loaders are skipped and the returned value is passed up the chain as the content.

Synchronous / Asynchronous loader

In synchronous mode a loader can simply return the result. For asynchronous work, the loader must call this.async() to obtain a callback and then invoke that callback with err, content, sourceMap, meta .

Examples:

// Synchronous loader example
module.exports = function(content, map, meta) {
  this.callback(null, handleData(content), handleSourceMap(map), meta);
  return; // callback returns undefined
};
// Asynchronous loader example
module.exports = function(content, map, meta) {
  var callback = this.async();
  asyncHandleData(content, function(err, result) {
    if (err) return callback(err);
    callback(null, result, map, meta);
  });
};

Loader parameters

The initial loader receives the file content as a UTF‑8 string. Setting module.exports.raw = true makes it receive a Buffer . Loaders can also receive content , sourceMap , and meta via the callback.

pitch parameters

pitch receives three arguments:

remainingRequest – the request string for the loaders to the right of the current loader.

precedingRequest – the request string for the loaders to the left.

data – a shared object between pitch and normal phases.

Loader output

The compiler expects the final loader to emit a String or Buffer (representing the module's JavaScript source) and optionally a source map.

Additional files can be emitted with this.emitFile(name, content, sourceMap?) .

Loader caching

In development mode loaders are marked cacheable by default. To disable caching, set this.cacheable = false . Dependencies can be added with this.addDependency(filePath) to trigger re‑execution when those files change.

Loader API

Beyond the basic functions, loaders can use the full Loader Context API, which provides utilities such as this.emitFile , this.addDependency , and others.

Loader development toolkits

loader-runner – a package for developing and debugging loaders.

loader-utils – a collection of common helper functions for loader authors.

schema-utils – helps validate loader options.

References are listed at the end of the original article.

webpackbuild toolsloadermodule bundlerloader-api
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login 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.