Skip to content

Conditional dynamic imports share one __vitePreload deps array, dropping CSS/preloads for one branch #23221

Description

@EduardZaydler

Describe the bug

When two dynamic import() calls are used in mutually-exclusive branches (if/else)
and get wrapped by Vite's __vitePreload helper, minification merges the two
__vitePreload(...) calls into a single call. The first argument correctly becomes a
ternary selecting the right import target, but the second argument (the deps array)
does not
— it keeps only one branch's deps, silently dropping the other branch's
preloaded assets (JS chunk preload + its CSS-code-split stylesheet).

In practice: whichever branch's deps got dropped never gets its
<link rel="stylesheet"> injected, even though that branch's JS module still loads
correctly via the (still-correct) ternary's native import(). Production builds
render completely unstyled for that branch, silently — no error, no warning.

Reproduction

https://codesandbox.io/p/devbox/focused-dubinsky-dw47ym?workspaceId=ws_PFv5Ae8htKWU39qbDgtegb

Steps to reproduce

yarn vite build

System Info

System:
    OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (2) x64 AMD EPYC
    Memory: 1.85 GB / 4.01 GB
    Container: Yes
    Shell: Unknown
  Binaries:
    Node: 20.19.6 - /usr/local/share/nvm/versions/node/v20.19.6/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.8.2 - /usr/local/share/nvm/versions/node/v20.19.6/bin/npm
    pnpm: 8.15.6 - /usr/local/share/npm-global/bin/pnpm
  npmPackages:
    @vitejs/plugin-react: ^4.3.4 => 4.7.0 
    vite: 8.0.16 => 8.0.16

Used Package Manager

npm

Logs

Hit this in production on a real app that conditionally loads one of two top-level
bundles (import("./mobile.bundle") / import("./desktop.bundle")) based on a
runtime user-agent check. The mobile bundle's CSS silently never loaded in
production (page rendered completely unstyled on mobile) while desktop worked —
desktop happened to be the "surviving" branch in the merged deps array. The JS
itself always loaded fine; only CSS-preload was affected.

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions