Skip to content

CSS side-effect imports become unreferenced when multiple entry points import the same CSS file #22209

@jimmy-sc

Description

@jimmy-sc

Describe the bug

When two or more entry points independently import the same CSS file as a side effect (import './style.css'), the CSS asset is emitted but no output chunk references it. The CSS is completely disconnected from the module graph — no chunk has it in viteMetadata.importedCss, and no JS file in the build output contains any reference to it.

Reproduction

https://github.com/jimmy-sc/vite-css-orphan-repro

git clone https://github.com/jimmy-sc/vite-css-orphan-repro
cd vite-css-orphan-repro
pnpm install
npx vite build

The setup:

  • src/search.js — imports search.css, exports SearchView
  • src/settings-search.js — independently imports search.css, exports its own view
  • src/mail-search.js (+ calendar, contacts, tasks, files) — imports SearchView from search.js
  • preserveEntrySignatures: 'strict' with entryFileNames: '[name].js'

Steps to reproduce

Run npx vite build. The debug plugin in vite.config.js logs chunk metadata:

search.js:              css=[], imports=[assets/search-xxx.js]
settings-search.js:     css=[], imports=[assets/search-xxx.js]
assets/search-xxx.js:   css=[assets/search-yyy.css], codeLen=0, imports=[]

CSS asset "assets/search-yyy.css": referenced by NOTHING (bug!)

The orphaned chunk assets/search-xxx.js has the CSS reference but has empty code and is not written to disk. grep -r "search-yyy" src/dist/ returns nothing — zero references to the CSS file anywhere in the output.

Expected behavior

Each entry chunk that imports search.css should have the CSS file in its viteMetadata.importedCss, or the CSS should be on a chunk that is reachable through the entry's import chain and written to disk.

Root cause

This appears to be caused by Rolldown's side-effect deduplication (rolldown#8804). When multiple entries import the same CSS file, Rolldown deduplicates the CSS import into a single empty chunk. That chunk exists in the generateBundle bundle object but is not written to disk, and no written chunk imports it.

Real-world impact

In our application (~600 entry points), this affects 48 modules. CSS loads in the main app because a bundle plugin walks the full import graph and collects CSS from all chunks. But when modules are loaded individually (e.g. in child browser windows), the CSS is missing because the entry chunk's import chain never reaches the CSS reference.

System Info

System:
  OS: macOS 26.4
  CPU: (14) arm64 Apple M4 Pro
  Memory: 134.08 MB / 48.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 25.9.0 - /opt/homebrew/bin/node
  npm: 11.12.1 - /opt/homebrew/bin/npm
  pnpm: 10.33.0 - /opt/homebrew/bin/pnpm
Browsers:
  Chrome: 146.0.7680.178
  Safari: 26.4

Broken: vite 8.0.3+ (rolldown 1.0.0-rc.12+) through vite 8.0.8 (rolldown 1.0.0-rc.15)
Works: vite 8.0.0 (rolldown 1.0.0-rc.9)

Used Package Manager

pnpm

Logs

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions