You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We have been investigating an issue whereby generated class names would sometimes (but not always) change in-between builds, even when there are no changes in the source files. This is undesirable because it means generated assets will be cache busted for no good reason.
Run ./test.sh. This script runs webpack multiple times. Each time it will check the output for any differences between the latest build and the previous build.
When we run this test, we will see that sometimes (but not always) there is a change in the output of webpack. Specifically, the hash of a generated class name changes:
We noticed this issue seems to go away after upgrading css-loader to from 2.1.1 to the immediate next version—3.0.0. As to why this seems to fix the issue, we think (but not certain) that it's something to do with the changes made in css-modules/postcss-modules-local-by-default#13 (released in version 2.0.6 of this module). (css-loader 3.0.0 depends on a newer version of the postcss-modules-local-by-default module which includes this change.)
However, whilst debugging this issue we noticed that this module (postcss-modules-values) uses a mutable variable (importIndex) to compute the "imported name", in createImportedName:
This means that createImportedName is not deterministic. When we run a build multiple times, the order that createImportedName is called for different imports may be different. Therefore it will return different results, because it relies on a mutable variable.
If we log the result of createImportedName in our reduced test case, we can see that the animation class produces different results between builds:
let options = {};
let importIndex = 0;
let createImportedName =
(options && options.createImportedName) ||
((importName /*, path*/) =>
{
+ console.log({ importName, importIndex });
return `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`;
});
Despite the fact we were able to workaround this issue by a change in a separate module, I would like to ask why importIndex is used in this way? Is there a more reliable/deterministic value that can be used instead? It feels like using a mutable variable—scoped to the module—in this way could very easily lead to more bugs like the one I described above. The fact we were able to workaround by upgrading another module feels more like a coincidence than a real fix.
The text was updated successfully, but these errors were encountered:
@evilebottnawi I would be happy to contribute a fix but I'm not sure what to do. Maybe if you could answer these questions then I'll be able to work something out:
why importIndex is used in this way?
Why does the "imported name" need to contain the importIndex at all? What would happen if we just removed it?
Assuming there's a reason for the importIndex, we'll need to figure out a replacement.
Hi,
We have been investigating an issue whereby generated class names would sometimes (but not always) change in-between builds, even when there are no changes in the source files. This is undesirable because it means generated assets will be cache busted for no good reason.
We have created a reduced test case which you can view and run here: https://github.com/Magellol/webpack-css-modules-keyframe-name-bug/tree/olly-postcss-modules-values-bug. The reduced test case consumes this module via
css-loader
(using themodules
option).yarn
./test.sh
. This script runswebpack
multiple times. Each time it will check the output for any differences between the latest build and the previous build.When we run this test, we will see that sometimes (but not always) there is a change in the output of webpack. Specifically, the hash of a generated class name changes:
We noticed this issue seems to go away after upgrading
css-loader
to from 2.1.1 to the immediate next version—3.0.0. As to why this seems to fix the issue, we think (but not certain) that it's something to do with the changes made in css-modules/postcss-modules-local-by-default#13 (released in version 2.0.6 of this module). (css-loader
3.0.0 depends on a newer version of thepostcss-modules-local-by-default
module which includes this change.)However, whilst debugging this issue we noticed that this module (
postcss-modules-values
) uses a mutable variable (importIndex
) to compute the "imported name", increateImportedName
:postcss-modules-values/src/index.js
Lines 11 to 15 in de45a53
This means that
createImportedName
is not deterministic. When we run a build multiple times, the order thatcreateImportedName
is called for different imports may be different. Therefore it will return different results, because it relies on a mutable variable.If we log the result of
createImportedName
in our reduced test case, we can see that theanimation
class produces different results between builds:let options = {}; let importIndex = 0; let createImportedName = (options && options.createImportedName) || ((importName /*, path*/) => { + console.log({ importName, importIndex }); return `i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`; });
Sometimes the
importIndex
used inanimation
is0
:Other times it's
1
:Despite the fact we were able to workaround this issue by a change in a separate module, I would like to ask why
importIndex
is used in this way? Is there a more reliable/deterministic value that can be used instead? It feels like using a mutable variable—scoped to the module—in this way could very easily lead to more bugs like the one I described above. The fact we were able to workaround by upgrading another module feels more like a coincidence than a real fix.The text was updated successfully, but these errors were encountered: