Skip to content

fix: hash initial chunks before runtime chunks#20711

Closed
davidmurdoch wants to merge 4 commits intowebpack:mainfrom
davidmurdoch:fix/real-content-hash-watch-order
Closed

fix: hash initial chunks before runtime chunks#20711
davidmurdoch wants to merge 4 commits intowebpack:mainfrom
davidmurdoch:fix/real-content-hash-watch-order

Conversation

@davidmurdoch
Copy link
Copy Markdown

Fixes #20710

Summary

  • hash initial chunks before runtime chunks in Compilation.createHash()
  • add a watch regression test that reproduces the stale RealContentHashPlugin reference error

Testing

  • node node_modules/eslint/bin/eslint.js lib/Compilation.js test/RealContentHashPlugin.test.js
  • yarn test:base --runInBand --runTestsByPath test/Watch.test.js test/RealContentHashPlugin.test.js

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 26, 2026

🦋 Changeset detected

Latest commit: f392dee

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

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Mar 26, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

Copy link
Copy Markdown
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use integration tests, we have watchCases and hotCases, unittests are useless

@davidmurdoch
Copy link
Copy Markdown
Author

Is the watch case i added okay?

expect(currentChunkFile).not.toBe(STATE.previousChunkFile);
}

expect(serviceWorkerSource).toContain(currentChunkFile);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need it to compare content, it is useless too, just test shared value, also test itself without errors and warnings means that we fixed the problem

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use import mod from "./shared.js" and expect(mod).toBe("__SHARED__") and in the next expect(mod).toBe("__SHARED__CHANGED")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a simple test like:

import { sharedValue } from "./shared.js";

it("should update the runtime chunk filename map on rebuild", () => {
	expect(sharedValue).toBe(
		WATCH_STEP === "0" ? "__SHARED__" : "__SHARED__CHANGED"
	);
});

does not catch the bug if the fix in this PR is reverted. The emitted service-worker.js content check is what actually fails before the fix and passes after.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've updated the test with a clarifying comment.

please feel free to edit the code yourself if you know a better way!

@alexander-akait alexander-akait marked this pull request as ready for review March 27, 2026 11:11
Copilot AI review requested due to automatic review settings March 27, 2026 11:11
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 27, 2026

Merging this PR will improve performance by 25.82%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 143 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory benchmark "css-modules", scenario '{"name":"mode-production","mode":"production"}' 8.5 MB 6.8 MB +25.82%

Comparing davidmurdoch:fix/real-content-hash-watch-order (f392dee) with main (32a30c2)

Open in CodSpeed

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a watch-mode caching bug where runtime chunks could embed stale filename/hash references by ensuring initial chunks are hashed before runtime chunks during Compilation.createHash().

Changes:

  • Adjust chunk hashing order in Compilation.createHash() to hash initial chunks before runtime chunks.
  • Add a new watch regression test case covering runtime chunk filename map updates across rebuilds.
  • Add a changeset entry documenting the patch change.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
lib/Compilation.js Reorders chunk hashing so non-runtime (incl. initial) chunks are hashed before runtime chunks.
test/watchCases/cache/stale-runtime-chunk-filename-map/webpack.config.js Adds a dedicated watch-mode repro config with splitChunks + memory cache to exercise runtime filename mapping updates.
test/watchCases/cache/stale-runtime-chunk-filename-map/test.config.js Exposes a helper to read the emitted service worker asset for runtime-reference assertions.
test/watchCases/cache/stale-runtime-chunk-filename-map/0/service-worker.js Asserts that the runtime output references the current hashed shared chunk filename on each watch step.
test/watchCases/cache/stale-runtime-chunk-filename-map/0/offscreen.js Provides a second entry to force a shared initial chunk used by multiple entrypoints.
test/watchCases/cache/stale-runtime-chunk-filename-map/0/shared.js Baseline shared module for step 0.
test/watchCases/cache/stale-runtime-chunk-filename-map/1/shared.js Modified shared module for step 1 to force a rebuild and new chunk hash/filename.
.changeset/public-horses-visit.md Records the behavior change as a patch-level release note.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexander-akait
Copy link
Copy Markdown
Member

/cc @xiaoxiaojx Can you take a look at this, looks like something wrong with hashes, after changing of order, esm-async-chunks-hmr and node-async-chunks-hmr stop working, looks like we need more complex logic to fix both edge cases, thanks

@xiaoxiaojx
Copy link
Copy Markdown
Member

I’ll take a look — this seems a bit tricky. There’s a circular here.

Related issue: #19439, PR: #19570.

@alexander-akait
Copy link
Copy Markdown
Member

@xiaoxiaojx Yeah, you are right, maybe we can track circuital situations, no rush, but will be great to look at this

@davidmurdoch
Copy link
Copy Markdown
Author

Oh wow. That is tricky!

Feel free to close this one, I don't mind.

And ping me if you want to help testing solutions.

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

4 participants