Skip to content

Commit 17d71ec

Browse files
authored
fix(css): treeshake css modules (#16051)
1 parent dd49505 commit 17d71ec

File tree

10 files changed

+47
-5
lines changed

10 files changed

+47
-5
lines changed

packages/vite/src/node/plugins/css.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
542542
map: { mappings: '' },
543543
// avoid the css module from being tree-shaken so that we can retrieve
544544
// it in renderChunk()
545-
moduleSideEffects: inlined ? false : 'no-treeshake',
545+
moduleSideEffects: modulesCode || inlined ? false : 'no-treeshake',
546546
}
547547
},
548548

playground/css/__tests__/css.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,3 +533,8 @@ test.runIf(isBuild)('manual chunk path', async () => {
533533
findAssetFile(/dir\/dir2\/manual-chunk-[-\w]{8}\.css$/),
534534
).not.toBeUndefined()
535535
})
536+
537+
test.runIf(isBuild)('CSS modules should be treeshaken if not used', () => {
538+
const css = findAssetFile(/\.css$/, undefined, undefined, true)
539+
expect(css).not.toContain('treeshake-module-b')
540+
})

playground/css/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ <h1>CSS</h1>
105105
<p>Imported SASS module:</p>
106106
<pre class="modules-sass-code"></pre>
107107

108+
<p class="modules-treeshake">CSS modules should treeshake in build</p>
109+
108110
<p>Imported compose/from CSS/SASS module:</p>
109111
<p class="path-resolved-modules-css">
110112
CSS modules composes path resolving: this should be turquoise

playground/css/main.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import sassMod from './mod.module.scss'
2020
document.querySelector('.modules-sass').classList.add(sassMod['apply-color'])
2121
text('.modules-sass-code', JSON.stringify(sassMod, null, 2))
2222

23+
import { a as treeshakeMod } from './treeshake-module/index.js'
24+
document
25+
.querySelector('.modules-treeshake')
26+
.classList.add(treeshakeMod()['treeshake-module-a'])
27+
2328
import composesPathResolvingMod from './composes-path-resolving.module.css'
2429
document
2530
.querySelector('.path-resolved-modules-css')

playground/css/treeshake-module/a.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import style from './a.module.css'
2+
3+
export function a() {
4+
return style
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.treeshake-module-a {
2+
color: red;
3+
}

playground/css/treeshake-module/b.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import style from './b.module.css'
2+
3+
export function b() {
4+
return style
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.treeshake-module-b {
2+
color: red;
3+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { a } from './a.js'
2+
export { b } from './b.js'

playground/test-utils.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ export function findAssetFile(
156156
match: string | RegExp,
157157
base = '',
158158
assets = 'assets',
159+
matchAll = false,
159160
): string {
160161
const assetsDir = path.join(testDir, 'dist', base, assets)
161162
let files: string[]
@@ -167,10 +168,21 @@ export function findAssetFile(
167168
}
168169
throw e
169170
}
170-
const file = files.find((file) => {
171-
return file.match(match)
172-
})
173-
return file ? fs.readFileSync(path.resolve(assetsDir, file), 'utf-8') : ''
171+
if (matchAll) {
172+
const matchedFiles = files.filter((file) => file.match(match))
173+
return matchedFiles.length
174+
? matchedFiles
175+
.map((file) =>
176+
fs.readFileSync(path.resolve(assetsDir, file), 'utf-8'),
177+
)
178+
.join('')
179+
: ''
180+
} else {
181+
const matchedFile = files.find((file) => file.match(match))
182+
return matchedFile
183+
? fs.readFileSync(path.resolve(assetsDir, matchedFile), 'utf-8')
184+
: ''
185+
}
174186
}
175187

176188
export function readManifest(base = ''): Manifest {

0 commit comments

Comments
 (0)