Css-loader: Chunks Hash changes every time when using css-modules

Created on 23 Jul 2017  路  10Comments  路  Source: webpack-contrib/css-loader

What is the current behavior?
using modules: true options breaks webpack chunkhash algorithm and generates a new hash for every chunk on every build. This makes long term caching impossible when using css-modules.
I also tried extract-text-plugin but I get same behaviour.

If the current behavior is a bug, please provide the steps to reproduce.
Follow the steps using official webpack caching guide here. create some async chunks and split points. you'll see that each chunk hash only changes if you change your files content. but if you load a css file using css-modules that chunk's hash changes on every build.

webpack: v2.7.0
css-loader: latest
style-loader: latest

4 (important) Patch 4 (inconvenient) Bug

Most helpful comment

@HosseinAgha sorry for big delay, but problem in <[emoji]> (a random emoji representation of options.content), so you get random class name and so chunkhash changed every build. It is expected. Just remove <[emoji]>, it is not safe for long cache term. https://github.com/webpack/loader-utils/blob/master/lib/interpolateName.js#L20 (here Math.random()).

Also we have another issue when you build project on linux or window (due / windows slashes css-loader generate difference class name), but it was fixed in https://github.com/webpack-contrib/css-loader/pull/812

All 10 comments

@HosseinAgha thanks for issue. Can your provide minimum reproducible test repo?

I md5 my chuks using webpack-chunk-hash and do not experience this problem

We recently ran into this same problem. After we implemented code splitting we noticed that chunkhashes were changing will each build. Problem was not fixed by separating out the webpack manifest into it's own file. Problem wound up being css-module hashes.

We wound up with temporary fix by using this for file naming instead:
const LOCAL_IDENT_NAME = '[name]-[local]-[path]';

This is aesthetically unappealing and adds a lot of characters to the dom.

@mryarbles Can you create minimum reproducible test repo?

@evilebottnawi I have created a minimum reproducible test: https://github.com/HosseinAgha/css-loader-chunkhash-problem as you have requested.
Run yarn build multiple times. as you'll see, importing a css file in Modules.js module causes its chunkhash to change on every build. But Normal.js chunkhash never changes.
Master branch uses webpack 4. If you want to check for webpack 3 use webpack3 branch (yarn install to install new dependencies).
I think this is a sev3 bug because it renders css-loader useless in production apps that use code splitting (no chunk caching possible because of file name change on every build).

@evilebottnawi I think we can fix this issue by simply adding a module-content based hashing option so classnames don't change on every build. So chunk hash won't change because the files content are fixed.

you can use 'contenthash',the chunkhash will change if the js content change

new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash:8].css')
    }),

@Oscar-ren this is not working as css files content (class) will change on every build when using css modules

@HosseinAgha sorry for big delay, but problem in <[emoji]> (a random emoji representation of options.content), so you get random class name and so chunkhash changed every build. It is expected. Just remove <[emoji]>, it is not safe for long cache term. https://github.com/webpack/loader-utils/blob/master/lib/interpolateName.js#L20 (here Math.random()).

Also we have another issue when you build project on linux or window (due / windows slashes css-loader generate difference class name), but it was fixed in https://github.com/webpack-contrib/css-loader/pull/812

@evilebottnawi Thank you very much I can confirm it is fixed now.
I cannot believe it is one and a half year since we talked about this issue 馃槅, I almost forgot about it.

Was this page helpful?
0 / 5 - 0 ratings