Repository navigation
fix: stop webpack from rewriting unquoted chunk names - #854
Merged
Merged
Conversation
RealContentHashPlugin replaces content hashes by string replacement in every emitted asset. Route chunk names are simpleHash(modulePath, 8) - the same shape as a hash - so a colliding name was rewritten as well, after Terser had already unquoted it. That produced an invalid object key (4003635d:"13401") and made the whole German bundle unparsable: no React hydration, so dead menu and dead hero animation on every /de page, while the build stayed green. Disabling realContentHash keeps the chunk names intact.
Parses every build/**/assets/js/*.js with Node's own parser (vm.Script, no dependency). Runs at the end of yarn build, not in yarn test, because CI calls yarn test before a build exists.
`yarn build --locale en` (the CI invocation) appends the flag to the end of the script chain, so the guard received --locale as its directory and exited 1, while docusaurus build kept building every locale. Take the directory explicitly and ignore further arguments. Also fall back to entry.path for Node < 20.12 (.node-version pins 20.0, where Dirent.parentPath does not exist yet) and correct the header comment: fe25bf46 was the chunk name, 4003635d the hash that replaced it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
yarn buildafter adding my changes without getting any errors.yarn.lock.Updating documentation or Bugfix
The German site is broken in production right now:
/de/ships a bundle that does not parse, so nothing hydrates.Every German page logs two errors:
React therefore never hydrates: the navbar toggle does nothing, the homepage hero animation never mounts (
#medusa-rootstays empty), and the locale dropdown and search are dead.en,ja,esandviare unaffected. A deploy after merge fixes it.Root cause
One object key in the emitted German bundles lost its quotes:
fe25bf46is a chunk name: Docusaurus names route chunkssimpleHash(modulePath, 8), which looks exactly like an 8-character content hash. Webpack'sRealContentHashPluginreplaces content hashes by plain string replacement in every emitted asset, so it cannot tell a hash from a chunk name that has the same shape: it also replaced this name (with the real hash4003635d) wherever the string appeared, including as an object key. Terser had already dropped the quotes around that name (it is a valid identifier, so unquoting is legal), so the replacement produced4003635d:->Identifier directly after number-> the whole bundle is unparsable.Stage trace from the German client compilation:
fe25bf464003635dPROCESS_ASSETS_STAGE_OPTIMIZE(before Terser)PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE(after Terser)PROCESS_ASSETS_STAGE_OPTIMIZE_HASH(RealContentHashPlugin)Only
debroke because only in that locale did an intermediate content hash collide with a chunk name. The build itself stayed green, so nothing caught it before deploy.Why not just redeploy?
A deploy with new content probably makes the symptom disappear: the collision is with an
intermediate content hash, and any content change shuffles those hashes. That is luck
though, not a fix - the same deployment shows it:
fe25bf46(same module,@site/blog/2021-09-20-september/index.md?truncated=true) was rewritten in the German bundle (fe25bf460x,4003635d3x) and left untouched in the English one (fe25bf463x,4003635d0x),Any future content or dependency change can collide again, in any locale, and the build
stays green while that locale is dead in the browser. This PR removes the mechanism (no
more textual hash rewriting) and adds the guard, so a recurrence fails the build instead
of reaching users.
Approach
docusaurus.config.js:optimization: { realContentHash: false }in the existingcustom-webpack-configplugin, with a comment explaining why. Docusaurus deep-mergesconfigureWebpackresults (mergeWithCustomize), sominimize,minimizerandsplitChunksare untouched - verified: the output is still minified,common.*.jsand*.LICENSE.txtare still emitted. Filenames keep a[contenthash:8]; it is just no longer recomputed by a second textual pass.scripts/check-js-assets.js(new, 48 lines, no dependency - parses with Node's ownvm.Script): exits non-zero when any emitted JS asset does not parse.package.json: the guard runs at the end ofyarn build, so both CI (yarn build --locale en) and the deploy build fail on an unparsable asset. It is deliberately not part ofyarn test: CI runsyarn testbefore any build exists, so the check would fail there for the wrong reason.Note on CI
.github/workflows/yarn-build.ymlrunsyarn build --locale en. Yarn appends extra arguments to the end of a chained script, so the flag never reachesdocusaurus build(measured: that command runs five client compilations and emitsbuild/de,build/es,build/ja,build/vias well - which is why CI can catch a locale-specific asset like this one). The guard therefore takes its directory explicitly (node scripts/check-js-assets.js build) and ignores any further arguments, soyarn build --locale enstays green: verified, exit 0,7415 JS assets parsed successfully.Verification
yarn build(all locales) before the fix:2 of 7415assets unparsable (de/assets/js/main,de/assets/js/runtime~main). After the fix:check-js-assets: 7415 JS assets parsed successfully./de/renders German with a clean console, the hero canvas mounts, the mobile menu opens.yarn build --locale en(the exact CI command): exit 0,7415 JS assets parsed successfully.4003635d:key makes the guard exit 1 withInvalid or unexpected token; a non-existent directory also exits 1.How to test
yarn buildyarn serve, then openhttp://localhost:3000/de/- hero animation runs, menu works, console stays clean (before this change: twoInvalid or unexpected tokenerrors).node scripts/check-js-assets.js build/deagainst the old build -> exit 1.Notes
realContentHash: falsecan be dropped again; the guard stays useful either way.Files changed
docusaurus.config.js(+14)package.json(+3/-1)scripts/check-js-assets.js(new, 50 lines)(3 files changed, 64 insertions, 1 deletion)