What is a Loader?
Loaders are transformations applied to the source code of a module. They allow you to pre-process files as youimport or “load” them. Loaders can transform files from different languages (like TypeScript) to JavaScript, or inline images as data URLs.
How Loaders Work
Loaders are executed from right to left (or bottom to top) in a chain. Each loader in the chain applies transformations to the processed resource. The final loader is expected to return JavaScript.Basic Loader Structure
A loader is a JavaScript module that exports a function:The
this context in a loader is provided by webpack and contains useful methods and properties known as the LoaderContext API.Loader Execution Phases
Loaders run in two phases:1. Pitching Phase
Loaders are executed from left to right (or top to bottom) during the pitching phase. Pitching loaders can short-circuit the loader chain.2. Normal Phase
Loaders are executed from right to left (or bottom to top) during the normal phase, processing the actual source code.Synchronous vs Asynchronous Loaders
Synchronous Loaders
Return the transformed source directly:Asynchronous Loaders
Usethis.async() for async operations:
Promise-based Loaders
Return a Promise for async operations:Raw Loaders
By default, loaders receive the resource file as a UTF-8 string. Setraw to true to receive raw Buffer:
Returning Multiple Values
Loaders can return source maps and additional metadata usingthis.callback():
Common Loader Patterns
Basic Transformation
With Options
With Validation
Emitting Files
Adding Dependencies
Make webpack watch additional files:Caching
Loaders are cacheable by default. Opt out if your loader has external dependencies:Error Handling
Synchronous Errors
Asynchronous Errors
Warnings
Loader Context
Loaders have access to many useful methods viathis:
this.addDependency(file)- Add a file dependencythis.async()- Make the loader asyncthis.callback()- Return multiple valuesthis.emitFile(name, content)- Emit a filethis.emitWarning(warning)- Emit a warningthis.emitError(error)- Emit an errorthis.getOptions()- Get loader optionsthis.resolve()- Resolve a request
Real-World Example: Markdown Loader
Guidelines
1. Keep Loaders Simple
Each loader should do one thing well. Chain multiple loaders for complex transformations.2. Use Module Utilities
Leverage webpack’s utilities likethis.resolve() instead of Node.js require.resolve().
3. Mark Dependencies
Always usethis.addDependency() for external files to enable proper watching.
4. Resolve Modules Relatively
Usethis.resolve() to resolve modules relative to the current module.
5. Extract Common Code
Extract common code into a runtime module usingthis.emitFile().
6. Avoid Absolute Paths
Generate relative paths or use webpack’s utilities to make loaders portable.7. Use Peer Dependencies
If your loader depends on a library, list it as apeerDependency.
Testing Loaders
Next Steps
- LoaderContext API - Complete API reference
- Pitching Loaders - Advanced loader execution
- Writing a Loader - Step-by-step tutorial
Further Reading
- Official Loader API
- loader-runner - The loader execution engine