Mini-css-extract-plugin: Empty module ID causes unreliable file hashes

Created on 19 Nov 2018  路  11Comments  路  Source: webpack-contrib/mini-css-extract-plugin

Original discussion: https://github.com/webpack-contrib/mini-css-extract-plugin/pull/284

ID of CssModule is currently set to empty string during initialization. When module ID is somehow empty, NamedModulesPlugin inside webpack creates name like ?abcdef. For regular ones (or Normal in webpack's nomenclature) it outputs something like ./foo/bar/baz.js?abcdef. Until that ?... hash is based on FULL request path (ex. /home/user/projects/foo/bar/baz.js), it's different for different repository clones, ex. on different workstations and on CI. It makes file hashes quite unpredictable as sorting modules by id gives different results on different machines and hash calculation depends on that order (hash.update('a') && hash.update('b') gives different results than hash.update('b') && hash.update('a')). It may be an issue even on CI, if repository is cloned to directory prefixed with build ID, so absolute path differs from build to build. In the worst case, file hash changes when its contents did not change, so the whole idea of hashing loses its sense.

The issue was discussed already in https://github.com/webpack-contrib/mini-css-extract-plugin/issues/281#issuecomment-423300860, but for some not obvious reason soultion proposed by @lfre was rejected.

All 11 comments

@erykpiast please create minimum reproducible test repo

@evilebottnawi Have you had time to look at example I've created?

@erykpiast sorry, no, working on sass-loader/style-loader/terser-webpack-plugin and webpack-dev-server, feel free to investigate and feedback, a lot of issues and very few developers :disappointed:

Sure, I understand. The thing is I actually have a solution (as described in the issue itself), but I need some people with knowledge and authority to judge if it's OK conceptually.

@erykpiast I took a look at your repo and there are a couple of issues.

First, both the identifier and context contain the full disk path. These are the ones causing the issue because even if you change the id, those identifiers produce the hash after. e.g ?abcd. I think you could either trim that to be just the filename or root path (which would fix your issue with CI producing different build id folders). More generally, this exposes a larger problem within webpack, that if you move the file to another folder or rename the filename, you'll get a different hash even when the contents haven't changed. However, if you change _identifier to be dependency.content, that'd fix the issue but I think the best way is for wherever the piece of code that produces the hash ?abcd to pick up this.content instead. I'm not sure where that is happening.

Second, there is an issue with the order as you mentioned. From chunk.modulesIterable https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/index.js#L242. In dir1 the order is foo.css, bar.css, but dir2 is bar.css, and foo.css, and since they have different content, triggering hash.update in a different order, will give you a different final hash. This would still change the hash even if you fixed the first issue. That's an issue on webpack. Ideally, the order should always match the import order from the files.

I can't speak for what possible issues changing this._identifier to dependency.content would do, so I'll defer to @evilebottnawi here.

Hope that helps everyone!

@lfre i am very busy, feel free to send a PR if you have ideas how we can fix it

Fixed in webpack@5

Output:

// ...
dir1/dist/main_26753f81.css
dir2/dist/main_26753f81.css
dir3/dist/main_26753f81.css
dir1/dist/main_0f0128e1.js
dir2/dist/main_0f0128e1.js
dir3/dist/main_0f0128e1.js

After investigation I want to say it is realy hard to fix on webpack@4 due some internal problems, and it can even break the hashes for other cases, so my recommendation - consider to update webpack to v5, anyway if you faced with the same problem again please open a new issue

Perfect! Thank you for handling this @evilebottnawi 鉂わ笍

Was this page helpful?
0 / 5 - 0 ratings