fix(build): deduplicate shared CSS chunks between prerender and client builds#16447
Draft
aubergene wants to merge 1 commit intowithastro:mainfrom
Draft
fix(build): deduplicate shared CSS chunks between prerender and client builds#16447aubergene wants to merge 1 commit intowithastro:mainfrom
aubergene wants to merge 1 commit intowithastro:mainfrom
Conversation
🦋 Changeset detectedLatest commit: 9cd7022 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
10d185f to
2a3534a
Compare
a0871f7 to
3f95157
Compare
…t builds When a CSS module is shared between a hydrated (client:load) component and a client-only (client:only) component, Vite places it in a separate shared CSS chunk. That chunk's modules record contains only the CSS module ID, not any JS component modules, so the existing shouldDeleteCSSChunk guard returned false — leaving the chunk in the client bundle even when allCssInSSR was true (i.e. the prerender build had already emitted and linked that CSS). The result was the same stylesheet linked twice on the page: once from the prerender build's combined chunk and once from the client build's shared chunk. Fix: inside the allCssInSSR branch, distinguish between pure CSS chunks (the modules record contains only CSS virtual module IDs, no JS) and mixed JS+CSS chunks. Pure CSS chunks are safe to delete unconditionally because they carry only shared CSS the prerender build already emitted. Mixed chunks keep the existing shouldDeleteCSSChunk() guard so that CSS is not removed when a component is also used via normal SSR rendering on a different page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50a78a4 to
9cd7022
Compare
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.
Changes
<link>tags when a CSS module (e.g.base.css) is shared between aclient:load(hydrated) component and aclient:onlycomponent.modulesrecord contains only the CSS module ID — not any JS component modules — the existing deduplication guard (shouldDeleteCSSChunk) never fired, leaving a redundant<link>in the page HTML even though the prerender build had already emitted and linked the same styles.plugin-css.ts, before the existing per-page assignment logic, we now check whether every CSS module in a client-build chunk is already tracked ininternals.cssModuleToChunkIdMap(populated by the prerender build). If so, the redundant client-side CSS assets are deleted immediately — regardless of whether the chunk also contains component JS.Testing
Added a new integration test (
test/css-ssr-client-dedup.test.ts) with a dedicated fixture (fixtures/css-ssr-client-dedup/) that reproduces the exact scenario:Nav(client:load) — importsbase.css+nav.css; processed in both the prerender and client builds.Share(client:only) — importsbase.css+share.css; processed only in the client build.base.cssbeing shared between both islands previously caused a redundant<link>tag. The tests assert (a) no CSS file's content is a subset of another linked file, and (b) all component styles are present exactly once on the page.All existing CSS integration tests continue to pass (46/46).
Docs
No user-facing API or behaviour change — this is a build output bug fix. No documentation update needed.