feat: build the client head snapshot from the DOM without html-react-parser - #4
Merged
Merged
Conversation
|
| delete env.NO_COLOR; | ||
|
|
||
| const npm = (args, cwd, capture = false) => | ||
| execFileSync('npm', args, { |
|
|
🎉 This PR is included in version 2.2.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.







Goal
Ship no HTML parser in the browser bundle and stop the manager from destroying root attributes it does not own.
Changes
analyzeClientHead()reads the existing<head>,<html>and<body>from the live DOM (attributes, text oftitle/style/script/noscript) instead of parsinginnerHTMLwithhtml-react-parser; entries get their DOM node attached by identity instead of by child index, so whitespace or comments between head tags no longer misalign them. Keys, order, container ownership and status stay identical to the parser algorithm, proven by an oracle test that runs the old algorithm (kept as a test helper) over fixtures including the real server-rendered head of the minimal template.className/class,htmlFor/for,charSet/charset,httpEquiv/http-equiv,crossOrigin,referrerPolicy,tabIndex,hrefLang,imageSrcSet,imageSizes,fetchPriority,noModule,srcSet,acceptCharset,itemProp,itemScope,itemType,itemID,itemRef);syncMetacompares mapped names, so<html lang="en" class="dark">keeps its class after the first<Meta>push (before:classremoved and a uselessclassnameattribute written); boolean props write empty attributes andfalse/null/undefinedremove them.data-theme) survive Meta pushes, removals, navigation and the delayed sync.html-react-parserstays a runtime dependency for the server helper only;sideEffects: false;npm run test:packagebuilds, packs and checks a temporary consumer (client graph free of parser packages, server entry works).rollup-plugin-tsis loaded through its CommonJS entry (declaration output byte-identical to the Node 20 build); CI uses Node 22.23.2 (Node 20 reached end of life in April 2026).Verification
npm run lint:check,npm run ts:check,npm teston React 18.2.0 and 19.2.8 (36 tests each),npm run buildon Node 22,npm run test:package.html-react-parser,html-dom-parser,htmlparser2,domhandler,entities,style-to-jsorinline-style-parsersources;npm run smokegreen.<head>, no console errors;document.documentElement.classList.add('dark')and a runtimedata-themeon<body>survive/→/about→/navigation; title and description return to the home values on the way back (with the published 2.1.2 they stay on the About values).