-
-
Notifications
You must be signed in to change notification settings - Fork 27k
CSS Modules – random vs deterministic class names in production #3972
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
Comments
I'm 100% with you. The current localident is to verbose. And more importantly if you have third parties relying on your dom you should add other target points like data-target="Foo" and not rely on how you style your components. |
I'd like to emphasize that CSS styles being tied to HTML classes is a coincidence. Originally HTML classes were meant to describe the semantic meaning of an element in the markup regardless of the styling. CSS then targets these markup elements via one or more types of selectors (one being selector by HTML class) to add styles to them. |
At Facebook we're using something similar to CSS Modules but with a different syntax. Our class names look like this:
I feel like this achieves a nice balance. In development it's obvious you shouldn't rely on them, and in production they're even shorter than hashes. I guess keeping a database doesn't really work in CRA context though. For debugging, we use a special query parameters that serves "development-like" CSS class names. Again, this is something we can't easily do with webpack and static builds, but I hope this is helpful as a reference point. |
Keep the same |
I'm closing the discussion in favor of the earlier discussion in #3965. In particular, I propose this solution: #3965 (review). |
Firstly, many thanks to @ro-savage for implementing CSS Modules in #2285 (merged and ready for release in [email protected] – see #3815) 🎉
I'm opening this issue to continue the discussion regarding random-vs-deterministic
localIdentName
class names in production builds.a15df83
).For ease of reading, I'm copying the relevant comments from here:
Click 👈
and here:
Click 👈
and here:
Click 👈
and here (you'll need to click the "Show outdated" link to see the comments):
Click 👈
I think there are two key points which merit further discussion:
1️⃣ The concerns of @klzns and @amannn regarding exposing the source code's file paths in production builds.
I share their concerns – I would feel uncomfortable seeing class names such as
src-components-Button__Button-module___primary
in production. I understand the benefits of deterministic/predictable class names which don't change with each build (so that elements can be targeted by class name), but this can be achieved without exposing the source code's file paths.2️⃣ The fact that
css-loader
's[hash]
token forlocalIdentName
is actually deterministic (not random), as @heavi5ide and @simonrelet noticed.Click for details of getLocalIdent() and interpolateName() 👈
CreateReactApp / ReactScripts currently uses
css-loader
v0.28.7. Looking at the source code, thelocalIdentName
template is passed togetLocalIdent()
, which effectively generates the class name in this way:interpolateName()
is provided by Webpack'sloader-utils
library, and the description of the[hash]
token is:The default template for
localIdentName
is"[hash:base64]"
, which generates the MD5 hash (as raw binary data) and then base64-encodes it.So
[hash]
is not random. It's the digest of:<Source CSS relative filepath> "+" <Source CSS class name>
So my recommendation is to change
localIdentName
inpackages/react-scripts/config/webpack.config.prod.js
from:to something like:
The hash will be deterministic, predictable, unique and targetable, without exposing the source code's file paths.
The text was updated successfully, but these errors were encountered: