SharePointVault ~/gotchas/spfx ⌕ Search 404 pages, error messages, scripts…Ctrl K ★ Star
M↓ README.mdM↓ spfx-chunk-name-is-not-its-content.md
sharepoint-vault›gotchas›spfx›spfx-chunk-name-is-not-its-content.mdhistoryedit on GitHub
● GOTCHAspfx· 4 min read

An SPFx chunk's file name is not its content — realContentHash is off

applies to: SPFx production builds (verified on SPFx 1.22.2, @microsoft/spfx-heft-plugins); anyone sharing or deduplicating bundles across versionsreviewed: 2026-09-24#spfx#webpack#cdn#caching#deployment#git

SPFx builds with webpack's optimization.realContentHash switched off, so the hash in a chunk's file name is not recomputed from the bytes that ship. Measured: a lazy chunk that was byte-for-byte identical in two consecutive builds came out under a different name — and nothing in the build rules out the reverse. If you share or deduplicate chunks across versions (your own CDN, a cache keyed by file name), compare content — a hash of the bytes or the git blob — and never overwrite a file that is already published with different bytes.

SPFx staví s vypnutým optimization.realContentHash webpacku, takže hash ve jméně chunku se nepřepočítává z bajtů, které odcházejí ven. Změřeno: líně načítaný chunk, bajtově shodný ve dvou po sobě jdoucích buildech, vyšel pod jiným jménem – a opačný směr build nevylučuje ničím. Kdo chunky mezi verzemi sdílí nebo deduplikuje (vlastní CDN, cache podle jména souboru), musí porovnávat obsah – hash bajtů nebo git blob – a soubor, který už je publikovaný, nikdy nepřepisovat jinými bajty.

Symptom

You keep one copy of each lazy chunk across releases — a shared folder on your CDN — and decide what is new by file name, because the name carries a content hash. Then:

  • A chunk you know has not changed turns up under a new name in every build, so the shared folder keeps growing. Measured on one app: a 60 kB chunk, byte-identical between two releases, was renamed from chunk.294_7e16…js to chunk.294_54c1…js.
  • The dangerous direction is the one you cannot see: nothing guarantees that a toolchain change (a new minifier version, say) will not produce different bytes under a name that already exists. A name-based deduplication then either skips the new file — the new version runs old code — or overwrites the old one, and older versions start loading code they were never built with.

Cause

The webpack configuration that SPFx generates switches the setting off explicitly (@microsoft/spfx-heft-plugins 1.22.2, WebpackConfigurationGenerator.js):

optimization: {
  // TODO: turn this on when webpack5-localization-plugin can suppress RealHashPlugin re-processing files.
  realContentHash: false,
  …
}

while chunk names still use the [contenthash] template. Webpack's own documentation spells out the consequence: with realContentHash set to false, "internal data is used to calculate the hash and it can change when assets are identical". In production mode webpack would default to true; SPFx overrides it.

Fix

  • Deduplicate by content, not by name. Compare a hash of the bytes, or — on a git-backed host — the blob that is published (git rev-parse HEAD:<path>) with the blob the new file would become (git hash-object --path <path> <new-file>).
  • Never overwrite a published file with different bytes. If a name already exists with other content, publish that release the old, self-contained way (its own folder) instead. A duplicate costs a little space; an overwrite breaks every version that still points at the file.
  • Compare blobs, not the SHA of the file on disk. With core.autocrlf=true, a file restored by git checkout sits on disk with CRLF line endings while the commit — and therefore the published site — has LF. A disk hash then reports "different" for identical content; git hash-object --path applies the same conversion a commit would.

Notes

Was this helpful?ask or add your experience on GitHub →
Saved you an hour? A star on GitHub helps other SharePoint people find the vault.★ Star on GitHub
last reviewed: 2026-09-24last updated: 2026-09-24historyedit on GitHubview source