javascriptcssreactjscreate-react-appbabel-plugin-react-css-modules

babel-plugin-react-css-modules does not change class name in style tag


I want to use babel-plugin-react-css-modules to create unique class names, so I did a PoC: I ejected create-ract-app, then I add babel-plugin-react-css-modules to plugins in package.json:

"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      "babel-plugin-react-css-modules"
    ]
  },

When I start application I see that class in HTML is set correctly, but inside <style> tag it's regular .App name:

enter image description here

Am I missing something? I think it should be pretty easy to set up and I make some stupid mistake I can't see. Thank you in advance for every answer.

Edit: App.js code:

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

function App() {
  return (
    <div styleName="App">
      Test app
    </div>
  );
}

export default App;

Solution

  • Rant: One of the many reasons I'm against the create-react-app (CRA) is because of how inflexible it can be when it comes to customization. If you're looking to include features, I'd recommend creating your own webpack configuration. Why? You'll become more familiar with Webpack, how to configure it, how to work within its limits, and how to add/change/adjust packages to your needs.

    That said, the CRA comes preconfigured with both global and local (module) CSS imports and it conflicts with babel-plugin-react-css-modules (BPRCM). The CRA expects .css files without module.css to be normal global imports. Meanwhile, BPRCM expects .css files to be local imports. Not only is that a conflict, but the localIdentNames are mismatched. By default, CRA looks for App.module.css where module.css specifies it's a modulated import, like so: import { App } from "./App.module.css";. As such it assigns localIdentNames as [file/folder]_[local]_[hash] as mentioned here, here and within an ejected config/webpack.config.js (Lines 432-456 -- it utilizes the react-dev-utils/getCSSModuleLocalIdent package).

    In order to resolve these conflicts, you'll need to establish a localIdentName (by default BPCRM uses this generateScopedName: [path]___[name]__[local]___[hash:base64:5] (4th option in the table), so I'll be using it for my example below), then you'll need to add BPRCM to the webpack.config.js under babel-loader because the CRA doesn't look for a babel configuration, then you'll have to remove the CSS module imports rule, and lastly, you'll need to add some options to their global CSS rule to make it local and utilize the localIdentName.


    Here's a working example: https://github.com/mattcarlotta/cra-css-modules

    To utilize the repo above:

    What I changed: