CSS modules not working for react version 16.6.0

Viewed 35221

I was trying to use CSS Modules in React.

Here my code of App.js

import React from 'react';
import styles from './index.css'

const App = () => {
    const REACT_VERSION = React.version;

  return (
    <div>
      Main app
      <div style={styles.test}>Green</div>
      <div>Yellow</div>
      <div>React version: {REACT_VERSION}</div>
    </div>
  );
};

export default App;

Here is my code of index.css

.test {
  background: black;
  color: white;
  font-size: 34px;
  border: 34px;
}

Here is the output

enter image description here

I know that I have to modify

  • webpack.config.dev.js
  • webpack.config.prod.js

but when I read this article I could not find that code.

16 Answers

I had this same problem and solved it by renaming my css file to:

myName.module.css

and also importing like this:

import styles from './myName.module.css'

There is no need to follow the steps of updating the webpack files any more.

The person in other question was totally right but with a little mistake, without updating the config you can do it. Just put .module in front of your name of css file like that:

myName.module.css

Then call it :

import styles from './myName.module.css'

Working on React 16.6

in react 16.13 and react-scripts@2.0.0 and higher you don't need to eject your project. Your CSS files must be named camelCase + .modules.css and import to your projects like this:

import React, { Component } from 'react';
import styles from './app.module.css'; // Import css modules stylesheet as styles
class App extends Component {
  render() {
    return <button className={styles.test}>Error Button</button>;
  }
}
export default App;

and in app.module.css

.test{
  color: blue;
}

if you eject projects, in webpack.config.js file, in css modules change like this:

   test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: true,

Your CSS files must be named like "yourFileName.module.css". And import into your JS file like below: import yourVariableName from "./yourFileName.module.css";

Works fine on React version:

"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "3.1.0"

I think it will definitely help you out. open config/webpack.config.js and find block like this.

        {
          test: cssRegex,
          exclude: cssModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 1,
              sourceMap: isEnvProduction && shouldUseSourceMap,
            },
            'css-loader'
          ),
         sideEffects: true,
        },

and change that like this :

        {
          test: cssRegex,
          exclude: cssModuleRegex,
          use: getStyleLoaders({
            importLoaders: 1,
            sourceMap: isEnvProduction
                ? shouldUseSourceMap
                : isEnvDevelopment,
            modules: {
              getLocalIdent: getCSSModuleLocalIdent,
              localIdentName: '[name]__[local]__[hash:base64:5]'
            }

          }),
          sideEffects: true,
        },

Do same for cssModuleRegex block right after above block and restart your server and you'll get css modules enabled.

Checked with React 17.0.1

This is what you need to do:

  1. Rename your css file, from: 'index.css' to: 'index.module.css'. It doesn't matter the notation for the naming of that css file (now as a *.module.css file). It won't make any difference if is 'myFile.module.css' or 'MyFile.module.css'. The solution is not there precisely.

  2. Import your *.module.css from your js file:

    import style from './CourseGoalList.module.css';

  3. Access to your css clases with the usual CSS Modules syntax:

    ... className={style.NameOfTheCssClass}...

  4. In the case you have css classes with dashes, you can do two things. Either remove the dashes renaming them to UpperCase or camelCase or you can access them like to a Map object (with key: value pairs). Even when you will be able to access/see those classes from your JS file (with the usual autocomplete code feature in your IDE), as camelCase classes,... they still wont work that way (with camelCase notation on your .js file and exactly as they are in the css file). It is imperative to either change the css classes name to UpperCase or camelCase (accessing with UpperCase or camelCase notation from the *.js file) or leave them as they are and then access them like if they were a Map object.

Example: You can do one of two things:

Variant A: It works perfectly

JS File:

import React from 'react';
import CourseGoalItem from '../CourseGoalItem/CourseGoalItem';
import style from './CourseGoalList.module.css';

const CourseGoalList = props => {
  return (
    <ul className={style.GoalList}>
      {props.items.map(goal => (
        <CourseGoalItem
          key={goal.id}
          id={goal.id}
          onDelete={props.onDeleteItem}
        >
          {goal.text}
        </CourseGoalItem>
      ))}
    </ul>
  );
};

export default CourseGoalList;

CSS File:

.GoalList {
  list-style: none;
  margin: 0;
  padding: 0;
}

OR:

Variant B: It works perfectly

JS File:

import React from 'react';
import CourseGoalItem from '../CourseGoalItem/CourseGoalItem';
import style from './CourseGoalList.module.css';

const CourseGoalList = props => {
  return (
    <ul className={style['goal-list']}>
      {props.items.map(goal => (
        <CourseGoalItem
          key={goal.id}
          id={goal.id}
          onDelete={props.onDeleteItem}
        >
          {goal.text}
        </CourseGoalItem>
      ))}
    </ul>
  );
};

export default CourseGoalList;

CSS File:

.goal-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

But this WONT work:

Variant C: It doesn't works (even if the css class is "visible" from your js file using a good IDE, like WebStorm for example)

JS File:

import React from 'react';
import CourseGoalItem from '../CourseGoalItem/CourseGoalItem';
import style from './CourseGoalList.module.css';

const CourseGoalList = props => {
  return (
    <ul className={style.goalList}>
      {props.items.map(goal => (
        <CourseGoalItem
          key={goal.id}
          id={goal.id}
          onDelete={props.onDeleteItem}
        >
          {goal.text}
        </CourseGoalItem>
      ))}
    </ul>
  );
};

export default CourseGoalList;

CSS File:

.goal-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

I don't know if you found solution or not but this worked for me. I was following a tutorial to use CSS module but tutor's react version was different from mine. he had react 16.0.0, and I have 16.7.0. I don't have dev or prod version on webpack. I only have webpack.config.js. so what I did, I had a code on line 400

{
     test: cssRegex,  // cssRegex defined above as /\.css$/; 
     exclude: cssModuleRegex,
     use: getStyleLoaders({
          importLoaders: 1,
          sourceMap: isEnvProduction && shouldUseSourceMap,

          //this is the code tutor wrote.
         //================================================
          modules: true,
          getLocalIdent: getCSSModuleLocalIdent,
          localIdentName: '[name]__[local]__[hash:base64:5]'
          //================================================


     }),
     // Don't consider CSS imports dead code even if the
     // containing package claims to have no side effects.
     // Remove this when webpack adds a warning or an error for this.
     // See https://github.com/webpack/webpack/issues/6571
     sideEffects: true,
},

I hope it helps.

Note: the only thing I wrote is what I mentioned in block, everything else was already there.

I think this work for you.

  • My react version is 16.8.2 and after 16.2.0 you don't have config/webpack.config.dev.js or config/webpack.config.prod.js version on webpack.
  • You only have config/webpack.config.js and config/webpackDevServer.config.js files after eject operation in react app.So to resolve this issue open config/webpack.config.js file and update these changes.(See line:- 391 to 464)

            {
          test: cssRegex,
          exclude: cssModuleRegex,
          use: getStyleLoaders({
            importLoaders: 1,
            sourceMap: isEnvProduction
              ? shouldUseSourceMap
              : isEnvDevelopment,
    
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
            localIdentName: '[name]__[local]__[hash:base64:5]'
          }),
          // Don't consider CSS imports dead code even if the
          // containing package claims to have no side effects.
          // Remove this when webpack adds a warning or an error for this.
          // See https://github.com/webpack/webpack/issues/6571
          sideEffects: true,
        },
        // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
        // using the extension .module.css
        {
          test: cssModuleRegex,
          use: getStyleLoaders({
            importLoaders: 1,
            sourceMap: isEnvProduction
              ? shouldUseSourceMap
              : isEnvDevelopment,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
            localIdentName: '[name]__[local]__[hash:base64:5]'
          }),
        },
        // Opt-in support for SASS (using .scss or .sass extensions).
        // By default we support SASS Modules with the
        // extensions .module.scss or .module.sass
        {
          test: sassRegex,
          exclude: sassModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 2,
              sourceMap: isEnvProduction
                ? shouldUseSourceMap
                : isEnvDevelopment,
            modules: true,
            getLocalIdent: getCSSModuleLocalIdent,
            localIdentName: '[name]__[local]__[hash:base64:5]'
            },
            'sass-loader'
          ),
          // Don't consider CSS imports dead code even if the
          // containing package claims to have no side effects.
          // Remove this when webpack adds a warning or an error for this.
          // See https://github.com/webpack/webpack/issues/6571
          sideEffects: true,
        },
        // Adds support for CSS Modules, but using SASS
        // using the extension .module.scss or .module.sass
        {
          test: sassModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 2,
              sourceMap: isEnvProduction
                ? shouldUseSourceMap
                : isEnvDevelopment,
              modules: true,
              getLocalIdent: getCSSModuleLocalIdent,
              localIdentName: '[name]__[local]__[hash:base64:5]'
            },
            'sass-loader'
          ),
        },
    
  1. You have to create the project in this way:

    create-react-app projectname --scripts-version 1.1.5
    
  2. Apply:

    npm run eject
    
  3. CSS-loader to webpack.config.prod.js and webpack.config.dev.js files. It is necessary to add the following settings for options. Otherwise, react CSS modules structure does not work.

    {
       loader: require.resolve('css-loader'),
           options: {
              importLoaders: 1,
              modules: true,
              localIdentName:'[name]__[local]__[hash:base64:5]'
    }
    

Adding .module in the name of css files enables the css loader in the higher version of React. Post doing this, you can simple use className={styles.classname(from css file)} in the mail file. This will apply the particular class property to that HTML element.

At the top of the file Just Import import styles from './mystyle.module.css'

It will work..

* as fixed my problem.

import * as headerStyles from './header.module.scss'

Add class instead of style like

<div className="test">Green</div>

if ur using CSS class or id so no need to as a variable use import CSS.

 import React from 'react';
 import './index.css'

    const App = () => {
        const REACT_VERSION = React.version;

      return (
        <div >
          Main app
          <div className="test">Green</div>
          <div>Yellow</div>
          <div>React version: {REACT_VERSION}</div>
        </div>
      );
    };

    export default App;

or

import React from 'react';
const style ={
  background: black,
  color: white,
  fontSize: 34px,
  border: 34px
}

    const App = () => {
        const REACT_VERSION = React.version;

      return (
        <div >
          Main app
          <div style={style}>Green</div>
          <div>Yellow</div>
          <div>React version: {REACT_VERSION}</div>
        </div>
      );
    };

It depends on the React version as you know. The recent version requires you to name CSS and sass files as follows:

[name].moudle.css or [name].moudule.scss.

If renaming files this way is not working. you should enable it manual. if you did create your project with react-create-app and didn't eject it to have access to all your config files. do as follow :

npm run eject 

it will create a config folder. inside that config file open your webpack.config files(there should be two) you have to add this in your test: /.css$/ option :

modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'

it should look like this

 test: /\.css$/,
                    use: [
                        require.resolve('style-loader'),
                        {
                            loader: require.resolve('css-loader'),
                            options: {
                                importLoaders: 1,
                                modules: true,
                                localIdentName: '[name]__[local]__[hash:base64:5]'
                            },
                        },

do it in both webpack.config files

Note: do note tweak something else there unless you know what you are doing

Changing the css filename to something like "myfile.module.css" and them importing it "import styles from './myfile.module.css' solved my issue. Even though I don't know why I have to use module in my filename.

This needs latest react-scripts atleast greater than 4.0.0. So run npm install --save react-scripts@latest and try which worked for me

Related