Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to change camelCase option for CSS modules #6389

Closed
mbifulco opened this issue Apr 2, 2019 · 11 comments
Closed

Add ability to change camelCase option for CSS modules #6389

mbifulco opened this issue Apr 2, 2019 · 11 comments

Comments

@mbifulco
Copy link

mbifulco commented Apr 2, 2019

(I think this is a feature request - it may just be a bug, or a small cry for help 😉)

Is your feature request related to a problem? Please describe.
Hi there - I'm building a storybook and Gatsby front end for thegymnasium.com. Our goal is to use storybook to prototype new UI enhancements which will get promoted into a gatsby front end once they're tested and ready for production.

I'm currently running into a configuration issue with Storybook and CSS Modules. What I would like is to be able to use camelCase in our JavaScript code to reference style names for CSS classes imported via CSS module. That configuration option looks like it lives within the webpack css-loader.

By default, it seems that Storybook's CSS module config only produces class names that are hyphen-separated. Our team would prefer to use camelCase here, which means setting the camelCase option to either true or only, from what I can tell.

Describe the solution you'd like
I've been digging through docs on how to correctly customize the webpack config for storybook to both use CSS modules and provide that camelcase option, but I haven't been able to get it right yet. I'm under the impression that what I need to do is something like this, but I think I also need to modify the css-loader in that config. I could use some help there.

Describe alternatives you've considered
An alternative for us would be to use only skewer-case css class names, however for the sake of code legibility, we'd prefer to use class names like:

<div className={classes.myCssClass} />

as opposed to

<div className={classes['my-css-class']} />

Are you able to assist bring the feature to reality?
Yes, I think I can - but I'm not sure where to start in order to find the base config to use for css modules and css-loader that storybook uses by default.

Additional context
This problem came to my attention because I've been developing our new react components side-by-side in storybook and Gatsby. Obviously, the goal is for them to be rendered exactly the same in both environments. Because we rely on camelCase css classNames from within our javaScript code, any classes defined by a .hyphenated-class-name in CSS do not work in Storybook. This is a side-by-side shot of our footer component running the same code in Gatsby and Storybook:

Pasted_Image_4_2_19__2_51_PM

If I console.log the css class names being generated by the css modules in both gatsby and storybook, I see the following:

gatsby generated class names

image

storybook generated class names

image

You can see that gatsby generates both hyphenated and camelCase class names, and storybook only does the former.

I should also add that I commented about this in a recent PR on the gatsby repo - in the screenshot there, you can see that the problem I've highlighted above is still present.

Reproducing

If you'd like to reproduce this issue, you can:

  1. pull down our repo for the combined gatsby and storybook front end here: https://github.com/gymnasium/gym-front-end
  2. run yarn install
  3. run yarn storydev, which will start both storybook and gatsby together. You can inspect class names in the footer to see that some are missing in the storybook version.

I hope that's enough information to be clear about what I'm going for here. Thanks!

@mbifulco
Copy link
Author

👋 Hi again! I'm still hoping for some advice/tips on what I might be missing here.

@mbifulco
Copy link
Author

I'm still stumped on this - would love some help!

@kempsterrrr
Copy link

@mbifulco did you find a solution this ?

@mbifulco
Copy link
Author

@kempsterrrr unfortunately not 😭

@stale
Copy link

stale bot commented Jun 10, 2019

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Jun 10, 2019
@ndelangen
Copy link
Member

Sorry for the late reply, You can tweak the config by creating a webpack.config.js in the storybook folder.

To determine what to change, you can run storybook with the --debug-webpack flag. That will print the full webpack config for you, so you know what to edit.

Note that storybook 5 requires your webpack.config.js to export a function, not an object.

I think your modification to the config would be something like:

  • config.module.rules.find() find the correct rule to make the modification on
  • mutate the object so the options are what you want

verify the changes are correctly applied by running storybook with --debug-webpack again.

@stale
Copy link

stale bot commented Jul 2, 2019

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@stale stale bot added the inactive label Jul 2, 2019
@stale
Copy link

stale bot commented Aug 1, 2019

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed Aug 1, 2019
@stevensacks
Copy link
Contributor

@ndelangen It's unfortunately unclear how to make the modification that is required to support exportLocalsConvention: 'camelCase' to webpackFinal. I've been trying for awhile and cannot figure it out.

This is a fairly common need, and making this change does not remove the hyphenated versions, it just adds camelCase ones. How difficult would it be for you to add support for this to Storybook as an option?

@oailloud
Copy link

oailloud commented Aug 28, 2020

EDIT: I'm aware the original question was related to Gatsby but I thought I might put this here as I found this thread googling for CRA.

For those using create-react-app, here's a (kind of dirty) fix to activate camel case on CSS modules.
To apply edit, just edit your main.js file:

module.exports = {
        // ...
	webpackFinal: async (config, { configType }) => {
                // ...
		const oneOfRule = config.module.rules.find(rule => rule.oneOf);
		oneOfRule.oneOf.forEach(rule => {
                        // if the rule handles CSS or SASS modules
			if (!rule.exclude && (".module.css".match(rule.test) || ".module.scss".match(rule.test))) {
                                // look for css loader
				const cssLoader = rule.use.find(use => use.loader && use.loader.match(/\/css-loader\//));
				cssLoader.options = {
					...cssLoader.options,
					localsConvention: "camelCase",
				};
			}
		});
                return config;
        },
}

@mthaak
Copy link

mthaak commented Jun 19, 2023

@oailloud's solution didn't work for me, but this did (in main.js):

module.exports = {
  ...
  webpackFinal: async (config) => {
    // Set options for CSS modules
    config.module.rules.forEach((rule) => {
      if (rule.use) {
        rule.use.forEach((use) => {
          if (use.loader && use.loader.includes("/css-loader/")) {
            use.options = {
              ...use.options,
              modules: {
                ...use.options?.modules,
                // Use a similar naming convention for generated class names as create-react-app
                // See https://github.com/webpack-contrib/css-loader#localidentname
                localIdentName: "[name]_[local]__[hash:base64:5]",
                // Export class names from CSS modules as original and in camelCase
                // Say your class is called .top-bar, then you can refer to it
                // in your *.jsx/*.tsx files as styles["top-bar"] or styles.topBar
                // See https://github.com/webpack-contrib/css-loader#exportlocalsconvention
                exportLocalsConvention: "camelCase",
              },
            };
          }
        });
      }
    });

    return config;
  },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants