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

Reproducible CSS Module names #96

Closed
joelmoss opened this issue Feb 22, 2022 · 7 comments
Closed

Reproducible CSS Module names #96

joelmoss opened this issue Feb 22, 2022 · 7 comments

Comments

@joelmoss
Copy link
Contributor

joelmoss commented Feb 22, 2022

It would be awesome if we could somehow control how CSS Module names are hashed, with the goal of being able to reproduce module class names outside of parcel.

Let me try and explain why...

I currently use Webpack and mini-css-extract-plugin, which supports CSS modules. It also allows me to configure the format of the class names to module names using the modules.localIdentName config option. And this actually has a nice side effect of allowing me to know the module names outside of webpack without needing to compile.

So as an example...

I set the modules.localIdentName to 'cssm_[md5:hash:hex:8]'. Then from this input:

.classOne {
  color: red;
}

I get output like this:

.cssm_abcd1234 {
  color: red;
}

All as you would expect. But of course, in order to actually find out what the resulting module names are, I have to run webpack to get the JSON output of class names to module names.

I have a better way :)

Because I know how the module names are created, i can actually guess what they are without needing to run webpack.

So in Ruby (my language of choice), I can get the module name:

css_path = 'path/to/my/css_modules.css'
class_name = 'classOne'
Digest::MD5.hexdigest("#{css_path}\x00#{class_name}")[0, 8]

I now know the module name without needing to compile webpack and reading the JSON.

Sorry for the slightly long winded description, but what I'm getting at, is could we have a deterministic way of doing the same with parcel-css? This way, all I would need from parcel-css is the CSS output. Then I can derive the class names myself, as I know how they are created.

I certainly don't need as many config options as mini-css-extract-plugin has. In fact, I don't need any.

Thoughts?

@joelmoss joelmoss changed the title CSS Module name hash Reproducible CSS Module names Mar 3, 2022
@joelmoss
Copy link
Contributor Author

joelmoss commented Mar 8, 2022

Would love to help with this. I'm not familiar with Rust, other than a skim over the basics, but I've found where the hashes are generated, and it seems straightforward enough.

My thinking is to use a hashing algorithm that is portable across languages and platforms, (MD5, SHAx, etc). I can't seem to figure what type of hashing is currently used though, but looks like its fairly specific to Rust.

I'm happy to create a PR, but would really appreciate any thughts and pointers.

Oh, and thx loads for an amazing lib!! 🤟

@joelmoss
Copy link
Contributor Author

@devongovett I'd love to give this a try. I can see where the hash is currently created, but my Rust is extremely rusty 😆 Would appreciate any pointers.

@devongovett
Copy link
Member

Hey sorry @joelmoss, I'm not ignoring this, I've just been thinking about how to handle it.

Rather than having to guess and hope that the hash function is implemented exactly the same way (sometimes they depend on the platform/architecture), what if we just let you pass it in if you wanted. By default, it is computed based on the filename, but you could compute it yourself and provide it as part of the options. It is appended to all class and id selectors following an underscore, so this should let you determine the names.

https://github.com/parcel-bundler/parcel-css/blob/27e4a3dfa340a6e82d423b29e4314c68b03f3200/src/stylesheet.rs#L132-L137

@joelmoss
Copy link
Contributor Author

joelmoss commented Mar 15, 2022

That is certainly one way, and is the most flexible, but not sure that is even needed. If a really common algo is used (something like MD5), then there is no need for any config or customisation options at all. And I'm pretty sure MD5 is not specific to the platform or architecture.

So if the hash is still calculated based on the filename, and I know the filename and each class name, then all should be nice and simple.

Oh and no matter how this is implemented, there would be no need to return the JSON output, which keeps things even simpler still.

thx again 🙏

@devongovett
Copy link
Member

I'm not sure I want to be locked into a specific hashing algorithm though. If it's specified, then it can never change to a faster algorithm for example. We may need the ability to pass in a hash for #110 as well.

@joelmoss
Copy link
Contributor Author

That makes sense, although that could easily be managed with major version bumps. was simply trying to keep this as simple as possible

@devongovett
Copy link
Member

Going to close as this is possible with #156.

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

No branches or pull requests

2 participants