Keep genuine configured entries when reclassifying emitted lazy facades - #347
Merged
Conversation
normalizeEmittedLazyEntries demoted every chunk that is a dynamic-import target, so the real client entry lost isEntry whenever it absorbed a module that is also dynamically imported elsewhere. Solid 2 produces that shape on its own: @solidjs/web/frames/client lazily imports the serialization decoder, so a static import of @solidjs/web/serialization/decode anywhere in the client graph merges the decoder into the entry chunk and the entry lists itself under its own dynamicImports. Downstream manifest capture (TanStack Start, TanStack/router#8214) then failed with "No entry file found", and under rolldown the chunk ended up neither entry nor dynamic entry because only isEntry is synced back from generateBundle (update_output_chunk keeps the original is_dynamic_entry). Derive the genuine entries from the configured build input (rollupOptions / rolldownOptions input in any spelling, lib entry, or Vite's default index.html — the start-mode virtual client entry included) and never demote their facade chunks, in the raw bundle and in the manifest load path (keyed the way Vite keys entry records, and restoring isEntry that an older build already stripped). Ignore a chunk's dynamic import of itself. Emitted lazy() facades are still reclassified by their emit references; a demotion that matches neither is reported with a warning describing the graph shape. The virtual manifest repairs isDynamicEntry on facades rolldown left flagless. css-matrix now builds the exact graph shape (static decoder import next to frames/client in the entry) and asserts the bundle as a post plugin sees it, .vite/manifest.json, and the baked virtual:solid-manifest. Fixes #342
🦋 Changeset detectedLatest commit: 1f5f6ca The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
commit: |
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.
Fixes #342
Root cause
normalizeEmittedLazyEntriesclearedisEntryon every chunk that is any dynamic-import target. The real client entry becomes one as soon as it absorbs a module that is also dynamically imported: with Solid 2,@solidjs/web/frames/clientlazily imports the serialization decoder (loadCodec()), so a static import of@solidjs/web/serialization/decodeanywhere in the client graph merges the decoder into the entry chunk and the entry lists itself underdynamicImports. The genuine entry was then demoted, and downstream manifest capture (TanStack Start, TanStack/router#8214) failed with "No entry file found".Rolldown wrinkle (why the chunk ended up
isEntry=false isDynamicEntry=false): rolldown hands each plugin'sgenerateBundlea fresh proxy over the native chunk; writes land in a per-hook JS cache and are synced back throughupdate_output_chunk, which only copiescode,map,imports,dynamicImports,isEntryand the file name —is_dynamic_entryis kept from the original chunk. SoisEntry = falsesticks butisDynamicEntry = trueis discarded before the next plugin (and Vite's native manifest plugin) sees the bundle. That's a rolldown limitation no plugin-side write can work around; the plugin now repairs the flag in the one artifact it fully controls,virtual:solid-manifest.Fix
rollupOptions/rolldownOptionsinputin string/array/record form,lib.entry, or Vite's defaultindex.html— the start-mode virtual client entry included), in every spelling a facade id can take (as written, root-resolved, realpath).generateBundle: never demote a chunk whosefacadeModuleIdmatches a configured entry; ignore a chunk's dynamic import of itself; emittedlazy()facades are still reclassified by their emit references (fix: make lazy facade entry reclassification effective under rolldown-vite #269/fix: reclassify lazy facades without importers #271 behavior preserved).loadpath: protect records by manifest key /src(the same root-relative key Vite derives), restoreisEntryon a configured entry that an older build already stripped, and setisDynamicEntryon demoted facades rolldown left flagless.Tests
@solidjs/web2.0.0-rc.6, vite 8.2.2): before —isEntry=false isDynamicEntry=false dynamicImports=[self], manifest record withoutisEntry; after —isEntry=true, control case unchanged (decodestays its own dynamic entry).examples/css-matrix(where the fix: make lazy facade entry reclassification effective under rolldown-vite #269/fix: reclassify lazy facades without importers #271 single-entry assertion lives): the entry now statically imports the decoder next toframes/client, producing the exact self-import shape; assertions cover the raw bundle as a post-order plugin sees it (.vite/bundle-chunks.jsonprobe),.vite/manifest.json, and the bakedvirtual:solid-manifest. Against the pre-fix build this fixture fails 15/49 (entry lost → no client entry CSS/asset resolution); with the fix 49/49.