Loaders

webpack · Essentials · 12 min

Loaders are how webpack handles anything beyond plain JavaScript.

Out of the box webpack understands JavaScript and JSON. Loaders teach it other file types or transform code, configured in module.rules:

  • test: a regex matched against the file path, e.g. /\.css$/i.
  • use: one loader or an array of loaders (with options objects).
  • exclude / include: limit which files a rule applies to, e.g. exclude: /node_modules/ for Babel.

Loader chains run right to left (bottom to top). For CSS:

  • css-loader resolves @import and url() and turns CSS into a JavaScript module.
  • style-loader takes that result and injects it into the page via <style> tags.

So use: ["style-loader", "css-loader"] runs css-loader first. Add "sass-loader" at the end for Sass, or "postcss-loader" between them for autoprefixing.

Common loaders:

  • babel-loader for modern syntax and JSX; alternatives swc-loader and esbuild-loader are much faster.
  • ts-loader for TypeScript, or Babel/SWC to strip types and run tsc --noEmit separately.
  • css-loader with modules: true (or files named *.module.css by default) for CSS modules.

Images and fonts no longer need loaders in webpack 5; they use asset modules (next lesson).

Example

// webpack.config.js
module.exports = {
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],   // runs right to left
      },
      {
        test: /\.m?jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: { presets: [["@babel/preset-env", { targets: "defaults" }]] },
        },
      },
    ],
  },
};
// src/index.js:  import "./style.css";   -> styles injected at runtime

Remember

  • module.rules: test + use (+ include/exclude)
  • Loader chains execute right to left
  • style-loader + css-loader for CSS; babel/swc/esbuild loaders for JS
  • Exclude node_modules from expensive transforms

Watch out for

  • Writing ["css-loader", "style-loader"], which feeds raw CSS to style-loader and fails.

Check yourself

  1. In `use: ['style-loader', 'css-loader', 'sass-loader']`, which loader runs first?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: webpack.js.org/concepts/loaders/