Fading Coder

An Old Coder’s Final Dance

Home > Tech > Content

Configuring Webpack for CSS, Sass/SCSS, and CSS Modules

Tech 3

This guide walks through wiring up Webpack to handle plain CSS, upgrade to Sass/SCSS, and enable CSS Modules for scoped class names.

1) Load plain CSS into JavaScript with style-loader and css-loader

Install loaders:

yarn add -D style-loader css-loader

Minimal rule to inline CSS into the page and resolve @import/url():

// webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: { sourceMap: true },
          },
        ],
      },
    ],
  },
};

Usage in a React component:

/* src/components/DemoA/styles.css */
.container h2::before {
  content: '[A]';
}
// src/components/DemoA/index.tsx
import React from 'react';
import './styles.css';

export default function DemoA() {
  return (
    <section className="container">
      <h2>Demo A</h2>
    </section>
  );
}

2) Move from CSS to Sass/SCSS with sass-loader

Install Sass support. Prefer the modern sass package (Dart Sass):

yarn add -D sass-loader sass

Add a rule for .scss files:

// webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(scss|sass)$/i,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: { sourceMap: true },
          },
          {
            loader: 'sass-loader',
            options: { sourceMap: true },
          },
        ],
      },
    ],
  },
};

Example files:

/* src/components/DemoB/styles.scss */
.wrapper {
  h2::before {
    content: '[B]';
  }
}
// src/components/DemoB/index.tsx
import React from 'react';
import './styles.scss';

export default function DemoB() {
  return (
    <div className="wrapper">
      <h2>Demo B</h2>
    </div>
  );
}

3) Scope class names with CSS Modules

CSS Modules localize selectors to prevent clashes. Enable it through css-loader options. A common pattern is to treat files matching .module.scss (or .module.css) as modules and keep others global.

Recommended setup with separate rules:

// webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      // CSS Modules for *.module.(scss|sass|css)
      {
        test: /\.module\.(scss|sass|css)$/i,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[path][name]__[local]--[hash:base64:5]',
              },
              sourceMap: true,
            },
          },
          {
            loader: 'sass-loader',
            options: { sourceMap: true },
          },
        ],
      },

      // Global SCSS (not modules)
      {
        test: /\.(scss|sass)$/i,
        exclude: /\.module\.(scss|sass)$/i,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ],
  },
};

Module stylesheet and component:

/* src/components/DemoC/styles.module.scss */
.box {
  h2::before {
    content: '[C]';
  }
}
// src/components/DemoC/index.tsx
import React from 'react';
import styles from './styles.module.scss';

export default function DemoC() {
  return (
    <div className={styles.box}>
      <h2>Demo C</h2>
    </div>
  );
}

TypeScript typings for CSS Modules

TypeScript needs module declarations to import *.module.scss (and similar) as objects. Add a declaration file under src/types/css-modules.d.ts (or any included path):

// src/types/css-modules.d.ts
declare module '*.module.css' {
  const classes: { readonly [key: string]: string };
  export default classes;
}

declare module '*.module.scss' {
  const classes: { readonly [key: string]: string };
  export default classes;
}

declare module '*.module.sass' {
  const classes: { readonly [key: string]: string };
  export default classes;
}

Troubleshooting and tips

  • Use sass instead of node-sass (node-sass is deprecated and often fails to install on some Node versions). Ensure both sass and sass-loader are present.
  • Loader order matters. Webpack applies loaders from right to left: sass-loadercss-loaderstyle-loader.
  • Avoid overlapping rules that process the same files in different ways. If you mix module and global styles, use sepraate test/exclude patterns as shown.
  • Slow Sass installation can be network-related. Consider caching, mirrors, or a local registry proxy if installs time out.
Tags: webpack

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.