Skip to content

Support css.myClass conversion to css['my-class'] #12972

@AHHusam

Description

@AHHusam

Background

Was reading Dan's comment: #99 (comment) and I think there's a valid specific override that could be useful.
As you'll see, it's too much code for a simple task that feels like it should be supported out of the box.

Is your proposal related to a problem?

When using CSS modules I have to either reference classes using bracket notation css['my-class'] (which can impact readability for more complex accessors)

<p className={css['my-class']} />
.my-class { /* <<< */
  color: red;
}

Or I can use dot notation css.myClass. BUT my CSS rule should also be camelCase

<p className={css.myClass} />
.myClass { /* <<< */
  color: red;
}

And if I use dot notation css.myClass in JSX

<p className={css.myClass} />

and kebab-case in CSS

.my-class {
  color: red;
}

Then styles are not applied.

Describe the solution you'd like

Maybe we could have some sort of webpack overrides in package.json for specific use cases, such as exportLocalsConvention: 'camelCase' for css-modules. (I didn't give it too much thought, it's just a quick suggestion)

{
  "react-scripts": {
    "webpack": {
      "css-modules": {
        "exportLocalsConvention": "camelCase"
      }
    }
  }
}

Something similar to jest's property in package.json

{
  "jest": {
       "resetMocks": false
   }
}

Describe alternatives you've considered

Alternative 1

I tried rewire.
I created a file called build.js at root level, with this content:

const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');
const config = defaults.__get__('config');

const cssModulesOptions =
    config.module.rules[1].oneOf.at(-4).use[1].options.modules;
config.module.rules[1].oneOf.at(-4).use[1].options.modules = { // try to ignore that I'm accessing with `at(-4)` and not a smarter lookup, because it's just to simplify the example here and get the point accross.
    ...cssModulesOptions,
    exportLocalsConvention: 'camelCase',
};

Then in my package.json, I replaced react-scripts build by node ./build.js

That worked, but only for production builds.
When running a development version (yarn dev) the development CSS code doesn't convert to kebab-case. That's because yarn dev uses react-scripts start which in turn uses the original webpack config.

One solution to this development issue might be to use rewire-webpack (as rewire's README suggests) but I haven't tried that yet.

Alternative 2

Ejecting works fine too, but then you'd open pandora's box.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions