fix(css): preserve CSS modules linked from HTML in build#22259
fix(css): preserve CSS modules linked from HTML in build#22259semimikoh wants to merge 1 commit intovitejs:mainfrom
Conversation
|
Why did it work in Vite v7 without this change? |
|
It likely worked in Vite v7 because this edge case wasn't exposed in the previous build pipeline the same way. The underlying issue is that a CSS Module linked from HTML is converted into a JS import during build, even though from HTML we only need its CSS side effect. In Vite v8, CSS Modules that generate JS exports can be treated as tree-shakeable, so an HTML-linked CSS Module may be removed when those exports are unused. So I wouldn't frame this as "v7 handled it correctly and v8 regressed because of one specific change" so much as: the HTML-linked CSS Module case was ambiguous before, and Vite v8 made that ambiguity observable. This PR makes that intent explicit by treating those imports as CSS side-effect imports instead. |
Why were it not treated as tree-shakeable in v7? But is in v8. |
|
I don't think this is best explained as "v7 always preserved CSS Modules and #16051 changed that", since the CSS Modules This PR makes that explicit by treating HTML-linked CSS Modules as CSS side-effect imports instead of normal CSS Module JS imports. |
|
What is the concrete change that makes this observable in v8? If Without knowing what that change is, I'm not sure this is the right place to fix it. It might belong closer to whatever actually changed (e.g. how we emit the JS module, or something else in the CSS/HTML pipeline). |
|
That’s fair. I don’t think I’ve pinned down the concrete change with enough confidence yet. What I have confirmed so far is the Vite-side structure around this path, but not the exact behavioral difference that made it become observable only in v8. I’ll dig into that more before asserting that this is definitely the right layer to fix. |
Description
Fixes a dev/build inconsistency where CSS Modules referenced directly from HTML with
<link rel="stylesheet">were applied in dev butcould be dropped from production builds.
In build, HTML stylesheet links are converted into JS imports. For CSS Modules, that meant the imported module produced JS exports and
was marked side-effect-free, so Rollup could tree-shake the import when the exports were unused. The CSS was then not collected into the
final CSS asset.
This change marks CSS Modules imported from HTML stylesheet links with an internal
?html-stylequery. The CSS still goes through thenormal CSS Modules/PostCSS pipeline, but the generated JS module is empty and kept as a side-effect import so the processed CSS is
included in the build output.
Changes
?html-stylemarker for CSS Modules linked from HTML stylesheets.?html-styleCSS Modules from being tree-shaken during build.<link rel="stylesheet" href="./html-linked.module.css">.Tests
git diff --checkpnpm run test-build playground/cssNotes
pnpm run test-serve playground/csshung without output in the local environment and was terminated. The regression is build-specificand is covered by the passing build playground test.
Fixes #22242