fix(html): skip html comments in tag injection (fix #18386)#22368
Open
maruthang wants to merge 1 commit into
Open
fix(html): skip html comments in tag injection (fix #18386)#22368maruthang wants to merge 1 commit into
maruthang wants to merge 1 commit into
Conversation
The head/body injection regexes were applied to the raw HTML and matched the first occurrence of markers like `<head>` or `</body>`, even when those markers lived inside an HTML comment. As a result, a leading commented-out HTML document caused Vite to inject `<script>`/CSS tags into the comment instead of the real document. Mask comment contents (preserving byte offsets) before testing or replacing, so injection always targets real markup. fixes vitejs#18386
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.
Description
fixes #18386When an HTML file begins with a commented-out HTML document (e.g. an old template kept as a reference at the top of the file), Vite was injecting
<script>/ CSS tags into the comment instead of into the real<head>. The injected assets were therefore never loaded and dev/build silently broke.Root cause: the injection regexes in
packages/vite/src/node/plugins/html.ts(headInjectRE,headPrependInjectRE,bodyInjectRE,bodyPrependInjectRE,htmlInjectRE,htmlPrependInjectRE,doctypePrependInjectRE) were applied directly to the raw HTML via.test()/.replace()and matched the first occurrence of markers like<head>or</body>— including markers that lived inside<!-- ... -->.Fix: introduced a small helper
maskHtmlComments(html)that replaces the contents of HTML comments with same-length spaces so byte indices stay aligned, plustestOutsideComments/replaceFirstOutsideCommentswrappers.injectToHead,injectToBody, andprependInjectFallbacknow use these wrappers; the existing regexes themselves are unchanged.injectToHeadandinjectToBodyare nowexported so the regression tests can exercise them directly (mirrorsgetCssFilesForChunk).What is the purpose of this pull request?
Additional context
Alternatives considered:
Regression tests (added in
packages/vite/src/node/__tests__/html.spec.ts):<head></head>inside a comment — inject still targets the real</head></body>inside a comment — inject still targets the real</body><head>plus a real<body>— exercises theprependInjectFallbackpathVerified the bug shape against the reporter's exact HTML via a standalone repro before the fix; with the fix, an end-to-end Vite build of that HTML correctly injects into the real
<head>and leaves the leading comment intact.Validation run locally:
pnpm run typecheck— passpnpm run test-unit— 783 passed, 4 skipped (incl. the 4 new tests)pnpm run test-build playground/html— 54 passed, 8 skippedpnpm run test-serve playground/html— 54 passed, 8 skippedpnpm run build— passpnpm run lint— pass (only a pre-existing parse error inplayground/preserve-symlinks/module-a/linked.js, unrelated to this PR)