• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Forget CSS-In-JS: Combine Sass With CSS Modules Using Webpack

Webpack · May 6, 2020

I really dislike the CSS-In-JS trend. Nothing against anyone who is a fan, but writing CSS inside of Javascript doesn’t feel natural and honestly, it’s just an unnecessary abstraction. I understand why it became a thing, but the problems CSS-In-JS promises to solve have already been solved thanks to CSS Modules and Shadow DOM.

As usual, the front-end development community are focused on tooling and not on the end-user experience. Numerous benchmarks have proven CSS-In-JS can introduce performance issues into your application.

For cross-platform development, I will not dispute CSS-In-JS solutions can be useful, but many of us only target one platform most of the time. The thought of having to write components for even the most simple of UI tasks sounds daunting.

I am a big fan of using CSS Modules in my projects. They solve the naming issue in CSS giving you the same result as something like Styled Components, only you get to write CSS inside of CSS files. In combination with a pre-processor, even better.

Separating module and non-module SCSS

When using CSS Modules in your application, it is considered best practice to separate your module and non-module CSS styles. If you treat all CSS/SCSS as a CSS Module, when working with third-party packages with CSS/SCSS such as Bootstrap, you will run into problems.

I like to treat all CSS/SCSS as non-module by default. For CSS Modules, you want to specifically opt-in to use the modules functionality. This way you can have traditional global CSS and when you want localised component styles, you opt-in.

For module styles I like to use the .module.scss or .module.css naming convention. Inside of my components I will do something like this:

import styles from './mycomponent.module.scss';

In my case, I am using autoprefixer as well as cssnano to add browser prefixes and de-duplicate my CSS styles when imported. Your webpack.config.js configuration might look slightly different to this, alter to your taste.

Define the loaders

const cssModuleRules = [{
        loader: 'css-loader',
        options: {
            importLoaders: 2,
            sourceMap: true,
            modules: {
                localIdentName: '[name]__[local]____[hash:base64:5]',
            },
        }
    },
    {
        loader: 'postcss-loader',
        options: {
            plugins: () => [
                require('autoprefixer')(),
                require('cssnano')()
            ]
        }
    }
];

const cssRules = [{
        loader: 'css-loader'
    },
    {
        loader: 'postcss-loader',
        options: {
            plugins: () => [
                require('autoprefixer')(),
                require('cssnano')()
            ]
        }
    }
];

We have two CSS Loader configurations here, one for CSS Modules and one for standard CSS.

The following loader configurations going inside of the module rules property.

{
    test: /\.css$/i,
    use: extractCss ? [{ loader: MiniCssExtractPlugin.loader }, ...cssRules] : ['style-loader', ...cssRules]
},
{
    test: /\.scss$/,
    exclude: /\.module\.scss$/,
    use: extractCss ? [{ loader: MiniCssExtractPlugin.loader }, ...cssRules, ...sassRules] : ['style-loader', ...cssRules, ...sassRules],
},
{
    test: /\.module\.scss$/,
    use: extractCss ? [{ loader: MiniCssExtractPlugin.loader }, ...cssModuleRules, ...sassRules] : ['style-loader', ...cssModuleRules, ...sassRules]
}

We have a CSS rule for being able to deal with standard CSS, not using modules. Then we have a scss rule for non-module scss styling. And lastly, we have a rule for module styles using our CSS Modules configuration.

If you wanted to use CSS Modules with standard CSS, you could easily add another rule testing for .module.css to allow that as well.

That is all there really is to it. Now, you have CSS Modules allowing locally scoped CSS that will have randomly generated class name strings, allowing you to write specific CSS without global naming conflicts.

Dwayne

Leave a Reply Cancel reply

0 Comments
Inline Feedbacks
View all comments

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • How To Mock uuid In Jest
  • How to Use Neural DSP Archetype Plugins With the Quad Cortex
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Decompile And Compile Android APK's On A Mac Using Apktool
  • NBN Box Installed Inside of Garage, Where Do You Put The Modem?

Recent Comments

  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die
  • Dwayne on How to Create a Blockchain With TypeScript
  • kevmeister68 on PHP Will Not Die

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz