Skip to content

using [name].[contenthash].css for filename is not deterministic  #701

Closed
@pieh

Description

@pieh
  • Operating System: macOS BigSur 11.1
  • Node Version: 12.18.2
  • NPM Version: 7.5.2
  • webpack Version: 5.22.0
  • mini-css-extract-plugin Version: 1.3.7

Expected Behavior

contentHash to be stable and deterministic

Actual Behavior

Building same project without making changes between build will "randomly" result in different contentHash sometimes

Code

I don't have minimal reproduction, but I did bit of a code dive so hopefully following explanation could replace reproduction setup.

In

compilation.hooks.contentHash.tap(pluginName, (chunk) => {
const { outputOptions, chunkGraph } = compilation;
const modules = isWebpack4
? Array.from(this.getChunkModules(chunk, chunkGraph)).filter(
(module) => module.type === MODULE_TYPE
)
: chunkGraph.getChunkModulesIterableBySourceType(chunk, MODULE_TYPE);
if (modules) {
const { hashFunction, hashDigest, hashDigestLength } = outputOptions;
const createHash = compiler.webpack
? compiler.webpack.util.createHash
: webpack.util.createHash;
const hash = createHash(hashFunction);
for (const m of modules) {
m.updateHash(hash, { chunkGraph });
}
// eslint-disable-next-line no-param-reassign
chunk.contentHash[MODULE_TYPE] = hash
.digest(hashDigest)
.substring(0, hashDigestLength);
}
});
for webpack@5 chunkGraph is used. chunkGraph.getChunkModulesIterableBySourceType(chunk, MODULE_TYPE); return SortedSet of modules, however they are actually not sorted. Per https://github.com/webpack/webpack/blob/911ec1aa67011e25aa1449610f5b0b557edd5459/test/SortableSet.unittest.js it seems SortedSet means that it exposes .sort() method to get the Set sorted.

Later on m.updateHash(hash, { chunkGraph }); is called in order of modules in the SortedSet (which actually isn't sorted, and order of modules actually seem that can change between builds). Finally this result in contentHash that is generated not to be stable/deterministic.

For part about getChunkModulesIterableBySourceType returning unsorted modules I find minor mention in https://github.com/webpack/webpack/projects/6 :

Should getChunkModulesIterableBySourceType be sorted in general?

And following code for that method ( https://github.com/webpack/webpack/blob/05768d9029b9024d9a8d5f1aa56e649d9b963f57/lib/ChunkGraph.js#L538-L549 for entry), we can see that SortedSet is used (in modulesBySourceType implementation), but .sort() or .sortWith() is not called on it resulting in preserving order of module creation (?) which itself is probably not deterministic due to lot of async execution.

How Do We Reproduce?

As mentioned above - I don't have minimal reproduction for this problem, but I hope my research and description explain the issue well?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions