Skip to content

fix(rspack): use contenthash for chunkFilename to prevent stale chunks#36136

Merged
FrozenPandaz merged 1 commit into
masterfrom
gh-36014
Jun 29, 2026
Merged

fix(rspack): use contenthash for chunkFilename to prevent stale chunks#36136
FrozenPandaz merged 1 commit into
masterfrom
gh-36014

Conversation

@leosvelperez

Copy link
Copy Markdown
Member

Current Behavior

NxAppRspackPlugin maps outputHashing: 'all' (the default) to two different hash placeholders: output.filename uses [contenthash], but output.chunkFilename uses [chunkhash]. rspack's [chunkhash] hashes a chunk's module bodies but not each contained module's assigned id. With the production default optimization.moduleIds: 'deterministic', a module's id can be renumbered by an unrelated change to the module graph, which changes a chunk's emitted bytes without changing its [chunkhash] filename. Long-term-cached clients then keep the old chunk against a freshly built entry that references the new id and crash with Uncaught TypeError: Cannot read properties of null (reading 'call'). optimization.realContentHash does not mitigate this, since it only re-hashes [contenthash].

Expected Behavior

output.chunkFilename uses [contenthash], matching output.filename, so a chunk's filename always changes when its emitted content does. This is rspack's recommended hash for long-term caching and matches the defaults of Angular CLI, create-react-app, and Vue CLI.

Implementation Details

getOutputHashFormat in packages/rspack/src/plugins/utils/hash-format.ts now uses [contenthash] for chunk in both the bundles and all options. Confirmed against rspack source: [contenthash] folds the module id into the hash (web-infra-dev/rspack#2292, released in v0.1.2, below the @rspack/core ^1 || ^2 support floor) while [chunkhash] does not.

@nx/webpack carries the same [chunkhash] default but was deliberately left unchanged: webpack's [chunkhash] already folds module ids into the chunk hash (via getModuleHash), so it does not exhibit this stale-chunk problem.

Related Issue(s)

Fixes #36014


View session information ↗

Production builds could serve stale lazy or vendor chunks after a
redeploy, crashing with "Cannot read properties of null (reading
'call')". NxAppRspackPlugin set output.chunkFilename to [chunkhash]
while output.filename used [contenthash]. rspack's [chunkhash] hashes a
chunk's module bodies but omits each module's assigned id, so a
deterministic-moduleIds renumber changes the chunk's emitted bytes
without changing its [chunkhash] filename; long-term-cached clients then
keep the old chunk against an entry that references the new id.
realContentHash does not help, since it only re-hashes [contenthash].

chunkFilename now uses [contenthash], matching output.filename and the
defaults of Angular CLI, create-react-app, and Vue CLI, so the filename
changes whenever the chunk's content does.
@netlify

netlify Bot commented Jun 29, 2026

Copy link
Copy Markdown

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 8ba329f
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/6a4251da733d5000084dfeeb
😎 Deploy Preview https://deploy-preview-36136--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Jun 29, 2026

Copy link
Copy Markdown

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 8ba329f
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/6a4251dabd6d9c00082db8c2
😎 Deploy Preview https://deploy-preview-36136--nx-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nx-cloud

nx-cloud Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 8ba329f

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 4m 57s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 5s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 1m View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 18s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 5s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-29 12:09:36 UTC

@leosvelperez leosvelperez self-assigned this Jun 29, 2026

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We investigated the two failing tasks (eslint:test and vue:test) and confirmed they are unrelated to this PR's changes — both fail due to stale test snapshots that expect package versions of 0.0.1 while the environment now reports 24.0.0. Our changes only touch packages/rspack/src/plugins/utils/hash-format.ts and have no effect on ESLint or Vue package version resolution.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@leosvelperez
leosvelperez marked this pull request as ready for review June 29, 2026 12:22
@leosvelperez
leosvelperez requested a review from a team as a code owner June 29, 2026 12:22
@FrozenPandaz
FrozenPandaz merged commit 15871f0 into master Jun 29, 2026
26 of 28 checks passed
@FrozenPandaz
FrozenPandaz deleted the gh-36014 branch June 29, 2026 14:50
FrozenPandaz pushed a commit that referenced this pull request Jul 9, 2026
#36136)

## Current Behavior

`NxAppRspackPlugin` maps `outputHashing: 'all'` (the default) to two
different hash placeholders: `output.filename` uses `[contenthash]`, but
`output.chunkFilename` uses `[chunkhash]`. rspack's `[chunkhash]` hashes
a chunk's module bodies but not each contained module's assigned id.
With the production default `optimization.moduleIds: 'deterministic'`, a
module's id can be renumbered by an unrelated change to the module
graph, which changes a chunk's emitted bytes without changing its
`[chunkhash]` filename. Long-term-cached clients then keep the old chunk
against a freshly built entry that references the new id and crash with
`Uncaught TypeError: Cannot read properties of null (reading 'call')`.
`optimization.realContentHash` does not mitigate this, since it only
re-hashes `[contenthash]`.

## Expected Behavior

`output.chunkFilename` uses `[contenthash]`, matching `output.filename`,
so a chunk's filename always changes when its emitted content does. This
is rspack's recommended hash for long-term caching and matches the
defaults of Angular CLI, create-react-app, and Vue CLI.

## Implementation Details

`getOutputHashFormat` in
`packages/rspack/src/plugins/utils/hash-format.ts` now uses
`[contenthash]` for `chunk` in both the `bundles` and `all` options.
Confirmed against rspack source: `[contenthash]` folds the module id
into the hash (web-infra-dev/rspack#2292, released in v0.1.2, below the
`@rspack/core ^1 || ^2` support floor) while `[chunkhash]` does not.

`@nx/webpack` carries the same `[chunkhash]` default but was
deliberately left unchanged: webpack's `[chunkhash]` already folds
module ids into the chunk hash (via `getModuleHash`), so it does not
exhibit this stale-chunk problem.

## Related Issue(s)

Fixes #36014

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/gh-36014-54fdd58d)
<!-- polygraph-session-end -->

(cherry picked from commit 15871f0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@nx/rspack: output.chunkFilename uses [chunkhash] not [contenthash], serving stale chunks when module ids renumber

2 participants