Skip to content

Avoid hash collisions by default with random hashPrefix? #413

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

Closed
claudiorodriguez opened this issue Jan 27, 2017 · 22 comments
Closed

Avoid hash collisions by default with random hashPrefix? #413

claudiorodriguez opened this issue Jan 27, 2017 · 22 comments

Comments

@claudiorodriguez
Copy link

Hey everyone, just sharing a problem I found, to see if I'm missing something or if the suggested improvement could be a good idea.

If you go with the default options, or define your own localIdentName, the generated hash, without a hashPrefix, will be a digest of the relative path and the local classname.
This causes collision when you have two separate modules built with webpack that have a file with the same path, with the same classname in it (both modules have src/blah/styles.scss with the class .classname in it)
To solve this collision, I added a hashPrefix to the query, making it random on each build (something like <package-name> + Date.now() works great).
Isn't it a good idea to make a random hashPrefix be default behaviour?

@AdamJo
Copy link

AdamJo commented Feb 3, 2017

Running into the same issue. Any advice would be much appreciated.

@jeffijoe
Copy link

@claudiorodriguez do you have an example for your solution? Running into this as well.

@claudiorodriguez
Copy link
Author

@AdamJo @jeffijoe the easiest workaround is to add hashPrefix to your css-loader query, e.g.

{
  loader: 'css-loader',
  query: {
    hashPrefix: 'package-name' + Date.now()
    localIdentName: [local]_[hash:base64:5],
    modules: true
  }
}

@jeffijoe
Copy link

@claudiorodriguez oh okay! I was looking through docs to see if I could find any hashPrefix variable anywhere but I couldn't - isn't this documented?

@claudiorodriguez
Copy link
Author

I think it's undocumented. It's used here https://github.com/webpack-contrib/css-loader/blob/master/lib/getLocalIdent.js#L12

@jeffijoe
Copy link

Damn, I looked at that file for like 10 minutes and I didn't spot that - @claudiorodriguez thank you!

@mitkaaa
Copy link

mitkaaa commented Mar 3, 2017

If you are use LoaderOptionsPlugin, then you can add context

new webpack.LoaderOptionsPlugin({
                options: {
                    context: __dirname,
...

classes will be unique

@plrthink
Copy link

@mitkaaa thanks, this works for me. but could you please explain why this would solve this issue?

@dcworldwide
Copy link

Agree @mitkaaa i'm a bit confused by the solution... is this global config or local to css loader?

@cobacious
Copy link

I think you can set context to __dirname on the options object passed in to css-loader, you shouldn't need to use LoaderOptionsPlugin.

@plrthink @dcworldwide I believe this works because css-loader uses the value of options.context when generating the hash used in the localIdentName. By default context is just the local directory name of the module but by setting it to __dirname it includes the full absolute system path to that module, e.g. '/Users/bob/example' instead of just 'example', resulting in a different hash each time.

@jeffijoe
Copy link

jeffijoe commented May 4, 2017

Won't __dirname just set it to the path of the webpack config?

@cobacious
Copy link

Yeah, you're right. Seems to work anyway. ¯_(ツ)_/¯ Will try and dig into it further at some point.

@mrchief
Copy link

mrchief commented May 5, 2017

__dirname is not resolved when webpack loads. Its tucked away in a lazy function (getLocalIdent) that gets evaluated when a css file is bring processed. So it'll point to correct path everytime.

@jeffijoe
Copy link

jeffijoe commented May 5, 2017

If you specify context: __dirname in your webpack config, then it should be evaluated when webpack loads: https://nodejs.org/docs/latest/api/globals.html#globals_dirname

@cobacious
Copy link

cobacious commented May 5, 2017

__dirname is set In webpack config to the config's file path but getLocalIdent then resolves the relative path from there to the stylesheet, thereby generating a unique string for each for use in the hashing algorithm.

@jeffijoe
Copy link

jeffijoe commented May 5, 2017

Ah, I see. My bad.

@anhdn
Copy link

anhdn commented Jun 20, 2017

@mitkaaa you saved me!

@alexander-akait
Copy link
Member

Feel free to documentation this!

@qrew
Copy link

qrew commented Feb 19, 2018

Got same problem after moving to webpack-4.0.0beta. Updating css-loader with context fix this issue for me too. Config example:

{ loader: 'css-loader', options: { modules: true, context: __dirname, localIdentName: '[local]-[hash:base64:6]', }

Thanks so much for this solution!

@user1736
Copy link

I've opened a PR to refer this problem and workaround in docs #770

@alexander-akait
Copy link
Member

Somebody can create minimum reproducible test repo?

@alexander-akait alexander-akait removed this from the 2.0.1 milestone Mar 5, 2019
@alexander-akait
Copy link
Member

Closing due impossible reproduce. Feel free to create new issue if you faced with problem. Thanks!

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