SCSS kebab-case does not work with scss modules in React (typescript template)

Viewed 369

I have created a new React project using create-react-app with Typescript template. I use SCSS and try to use CSS modules approach. But I see that my SCSS classes are applied when I specify them in camelCase notation only. This is not good for me. I would like to use classical kebab-case CSS notation.

This works for me, but I dislike it:

.authContainer {
  background-color: red;
}

this does not work, but I like it

.auth-container {
  background-color: red;
}

Here is the example of the component:

import * as React from 'react';
import styles from './Kek.module.scss';

const Kek = () => {
    return (
        <div className={styles.authContainer}>
            !!!!!!!!!!! HELLO WORLD !!!!!!!!!!!
        </div>
    );
};

export default Kek;

Here is an illustration what is going on enter image description here

How to fix that? Am I supposed to create a webpack.config.js to override something? I made some research, and I think, yes, I'm. But, I'm not sure about how this overriding might look like. Too little information about this case.

UPDATE

As I was advised in comments, I tried to override exportLocalsConvention of css-loader. Documentation link

But it's not so easy to override something from webpack.config.js. To do that I installed the react-app-rewired npm package. I added the following config to my project:

module.exports = function override(config, env) {
    config.module.rules.push({
        loader: 'css-loader',
        options: {
            modules: {
                exportLocalsConvention : 'dashes'
            }
        }
    });
    console.log(config)

    return config;
}

console.log(config) shows me that I really have objects from the webpack.config.js. But then there is a problem. When I open my application, I see this: enter image description here

I have installed css-lodaer. What is the problem?

1 Answers

If you're overriding CRA's webpack config, you probably want to keep the original config as much as possible to avoid unwanted errors. You can see the original config of CRA here.

Writing something like this should allow you to change exportLocalsConvention without changing anything else:

const cssLoader = require.resolve("css-loader");
const isTestingSassModuleRegex = (test) => test.toString() === "/\.module\.(scss|sass)$/";

module.exports = {
    webpack: function (config) {
        config.module.rules.forEach(rule => {
            if (!rule.hasOwnProperty("oneOf")) return;

            rule.oneOf.forEach(loader => {
                if (!loader.test || !isTestingSassModuleRegex(loader.test)) return;

                loader.use.forEach(styleLoader => {
                    if (styleLoader.loader !== cssLoader) return;
                    styleLoader.options.modules.exportLocalsConvention = "asIs";
                });
            });
        });

        return config;
    }
};

This should be compatible with CRA v5.0.0.

This config will only override the loader for SASS module files (it targets this part of the original config), since it seems to be what you use. If you need to change the options for CSS or regular SASS files as well, you need to remove or change the condition !isTestingSassModuleRegex(loader.test).

Related