Skip to content

fix: correct chunk hashing order to prevent stale content hashes in watch mode - #20730

Closed
sujalgoel wants to merge 3 commits into
webpack:mainfrom
sujalgoel:fix/contenthash-runtime-chunk-watch
Closed

sujalgoel wants to merge 3 commits into
webpack:mainfrom
sujalgoel:fix/contenthash-runtime-chunk-watch

Conversation

@sujalgoel

Copy link
Copy Markdown

Summary

Fixes #20710

When using runtimeChunk: "single" together with splitChunks and output.filename: "[contenthash].js", watch rebuilds could produce a runtime chunk that references the wrong content-hashed filename for split chunks. This caused the runtime's __webpack_require__.u mapping to point to a non-existent file, breaking chunk loading on rebuild.

Root cause: In Compilation.createHash(), runtime chunks were being hashed before initial/split chunks. GetChunkFilenameRuntimeModule (which generates the __webpack_require__.u filename map) reads each split chunk's contentHash at hash time. Because the split chunks hadn't been hashed yet, it used a stale value from the previous compilation, producing an incorrect module hash. This caused the asset cache to return the previous compilation's runtime asset on subsequent rebuilds, embedding the old split chunk filename.

This contradicts the comment already present in the same method:

"all non-runtime chunks need to be hashed first, since runtime chunk might use their hashes."

Fix: Swap the order so initial chunks are hashed before runtime chunks.

Test plan

  • Added test/watchCases/long-term-caching/contenthash-with-runtime-chunk/ which reproduces the issue:
    • Two entries share a split chunk with a content-hashed filename
    • On watch rebuild the shared module changes, giving the split chunk a new hash
    • The test verifies the runtime correctly reflects the updated filename
  • Test fails on the buggy code, passes with the fix

…atch mode

When using runtimeChunk: "single" with splitChunks and contenthash-based
filenames, the runtime chunk was being hashed before initial/split chunks.
This caused GetChunkFilenameRuntimeModule to embed stale or incorrect content
hashes into __webpack_require__.u, leading to broken asset references on
watch rebuilds.

The fix ensures initial chunks are always hashed before the runtime chunk,
consistent with the comment at createHash() that states "all non-runtime
chunks need to be hashed first, since runtime chunk might use their hashes."

Fixes webpack#20710
@changeset-bot

changeset-bot Bot commented Mar 28, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4923b29

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
webpack Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Entry chunks may depend on the runtime chunk hash (via
createChunkHashHandler for ESM/CJS entries that import the runtime).
By splitting them into a 4th dedicated hashing pass after runtime chunks,
hash dependencies always flow in one direction:

  async/initial → runtime → entry

Also updates the comment block to document all four hashing categories
and their dependency relationships.
Add an assertion that tracks the split chunk filename across watch steps
and confirms it updates when the shared module changes. This directly
targets the stale-hash symptom: with the buggy hashing order the runtime
embeds the step-0 hash and the referenced file does not exist at runtime.
@xiaoxiaojx

Copy link
Copy Markdown
Member

Thanks for the PR. This uses the same fix as an earlier PR #20724, so it’s a duplicate and has been closed. If this was submitted automatically by AI, please check for related PRs first. Also, it’d be best to follow the PR template when writing the description.

@xiaoxiaojx xiaoxiaojx closed this Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RealContentHashPlugin watch rebuild can keep stale runtime chunk filename hashes

2 participants