[13.x] Fix Vite CSS not loaded from nested chunk imports#59662
Merged
taylorotwell merged 2 commits intoApr 16, 2026
Conversation
The `__invoke` method only resolved CSS from direct imports (one level deep). Vite 8 (Rolldown) keeps CSS on the chunk where the component is defined rather than hoisting it to the nearest entry, so CSS from deeply nested imports never received a `<link>` tag. This adds a `resolveImports` method that recursively walks the full import tree—matching the approach already used by the prefetch code and documented in Vite's backend integration guide. The fix is backward-compatible: with older Vite/Rollup builds where CSS was hoisted, nested chunks have empty `css` arrays, so the recursive walk produces identical output.
jonagoldman
pushed a commit
to deplox/laravel-framework
that referenced
this pull request
Apr 30, 2026
* [13.x] Fix Vite CSS not loaded from nested chunk imports The `__invoke` method only resolved CSS from direct imports (one level deep). Vite 8 (Rolldown) keeps CSS on the chunk where the component is defined rather than hoisting it to the nearest entry, so CSS from deeply nested imports never received a `<link>` tag. This adds a `resolveImports` method that recursively walks the full import tree—matching the approach already used by the prefetch code and documented in Vite's backend integration guide. The fix is backward-compatible: with older Vite/Rollup builds where CSS was hoisted, nested chunks have empty `css` arrays, so the recursive walk produces identical output. * Remove unnecessary pass-by-reference --------- Co-authored-by: Pascal Baljet <[email protected]>
7 tasks
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
The
__invokemethod inIlluminate\Foundation\Viteonly resolves CSS from direct imports of an entrypoint (one level deep). When Vite 8 (which uses Rolldown instead of Rollup) builds the manifest, it keeps CSS on the chunk where the component is defined rather than hoisting it to the nearest entry. This causes CSS from deeply nested imports to never receive a<link rel="stylesheet">tag in the rendered HTML.The problem
Given this manifest structure:
The current code at line 399 iterates
$chunk['imports']but does not recurse into those imports' own imports:The fix
This PR extracts import resolution into a
resolveImports()method that recursively walks the full import tree with cycle detection via a$seenarray. The single call site in__invokechanges from:to:
This matches the approach already used by the prefetch code in the same file, which recursively walks imports using a closure.
Why this is backward-compatible
With older Vite versions (5–7) that use Rollup, CSS from nested components was hoisted to the nearest entry or parent chunk. In those manifests, nested chunks have empty or no
cssarrays, so the recursive walk produces identical output to the current code. The fix only adds CSS tags for chunks that actually declare CSS — which only happens with Vite 8+ (Rolldown) manifests.References
Impact
In a real-world project with 100+ entrypoints, this bug caused 18 CSS files to silently go missing from production builds after upgrading to Vite 8, while everything worked correctly in dev mode (where Vite's dev server handles CSS inline).
Tests
testViteWithNestedCssImportthat creates a manifest with a 3-level import chain (entry → layout → header), each with its own CSS, and asserts both CSS files are loadedtestItGeneratesPreloadDirectivesForJsAndCssImportsto reflect the new (depth-first) discovery order of preload directives