-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Description
Describe the bug
When using Vite with Vue 3 CSS modules and the build.ssrEmitAssets
option enabled, unused component styles are incorrectly included in the server build output (dist/server/assets/static/
). This occurs when importing from an index file that also re-exports components with CSS modules.
The styles are only incorrectly included in the server build directory, not in the client build directory.
Reproduction
https://github.com/alexmnv/vite-ssr-css-issue-demo/
Steps to reproduce
- Initialize
ssr-vue
template
npm create vite-extra@latest demo-app -- --template ssr-vue
cd demo-app
npm install
-
Enable
build.ssrEmitAssets
invite.config.js
-
Create the following structure:
src/ ├─ feature/ │ ├─ Feature.vue │ ├─ FeatureInner.vue │ └─ index.js └─ App.vue
-
In
feature/index.js
, re-export a component and a constant:// src/feature/index.js export { default as Feature } from './Feature.vue'; export const foo = 'foo';
-
In
Feature.vue
, import another component and use CSS modules:<!-- src/feature/Feature.vue --> <template> <div :class="$style.feature"> <FeatureInner /> </div> </template> <script setup> import FeatureInner from './FeatureInner.vue'; </script> <style module> .feature { color: red; } </style>
-
In
FeatureInner.vue
, also use CSS modules:<!-- src/feature/FeatureInner.vue --> <template> <div :class="$style.featureInner">Inner</div> </template> <style module> .featureInner { color: blue; } </style>
-
In another component (e.g.
App.vue
), import only the constant, not the component:<script setup> import { foo } from './feature'; </script> <template>{{ foo }}</template>
-
Build:
npm run build
Expected Behavior
Only the styles of actually used components (in this case, App.vue
) should be emitted.
No CSS related to Feature.vue
or FeatureInner.vue
should be present.
Actual behavior
- ✅ Client build (
dist/client/assets/static/
): Correctly excludes unused component styles - ❌ Server build (
dist/server/assets/static/
): Incorrectly includes styles fromFeatureInner
component
The styles are included in the server build even though the components are never imported or rendered.
Note that only the styles from FeatureInner
are included, while the Feature
component’s styles are not.
Additional notes
- This issue only occurs when using Vue 3 CSS modules (
<style module>
). Regular<style>
or<style scoped>
do not trigger this bug. - Steps 2 - 7 are implemented in this commit of reproduction demo.
System Info
System:
OS: Linux 6.8 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
CPU: (16) x64 AMD Ryzen 7 5800U with Radeon Graphics
Memory: 4.44 GB / 30.66 GB
Container: Yes
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 23.9.0 - /home/pumbo/.nvm/versions/node/v23.9.0/bin/node
npm: 10.9.2 - /home/pumbo/.nvm/versions/node/v23.9.0/bin/npm
Browsers:
Chrome: 140.0.7339.127
Firefox: 143.0.4
Firefox Developer Edition: 143.0.4
Used Package Manager
npm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.