Radek Anuszewski
Radek Anuszewski

Reputation: 1910

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;

Upvotes: 1

Views: 2406

Answers (1)

Matt Carlotta
Matt Carlotta

Reputation: 19762

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:

  • open a terminal window on the ~/Desktop and clone the repo: git clone [email protected]:mattcarlotta/cra-css-modules.git
  • cd into the cra-css-modules folder and type yarn install or npm install
  • type yarn start or npm start to run the example

What I changed:

  • Declared a localIdentName to match BPRCM's default scoped class name (you can change this name to whatever you like and it'll still work with the example repo above).
  • Added BPRCM to the babel-loader rule.
  • Added a modules configuration to switch the global CSS rule to a local CSS rule
  • Removed the local modules CSS rule.
  • Changed all classNames to styleName in the App.js file.

Upvotes: 4

Related Questions