Skip to content

Commit a873af5

Browse files
authored
fix(css): handle pure css chunk heuristic with special queries (#12091)
1 parent 4b5cc9f commit a873af5

File tree

7 files changed

+38
-7
lines changed

7 files changed

+38
-7
lines changed

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

+9-7
Original file line numberDiff line numberDiff line change
@@ -464,15 +464,17 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
464464
let isPureCssChunk = true
465465
const ids = Object.keys(chunk.modules)
466466
for (const id of ids) {
467-
if (
468-
!isCSSRequest(id) ||
469-
cssModuleRE.test(id) ||
470-
commonjsProxyRE.test(id)
471-
) {
472-
isPureCssChunk = false
473-
}
474467
if (styles.has(id)) {
475468
chunkCSS += styles.get(id)
469+
// a css module contains JS, so it makes this not a pure css chunk
470+
if (cssModuleRE.test(id)) {
471+
isPureCssChunk = false
472+
}
473+
} else {
474+
// if the module does not have a style, then it's not a pure css chunk.
475+
// this is true because in the `transform` hook above, only modules
476+
// that are css gets added to the `styles` map.
477+
isPureCssChunk = false
476478
}
477479
}
478480

playground/css-codesplit/__tests__/css-codesplit.spec.ts

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test('should load all stylesheets', async () => {
55
expect(await getColor('h1')).toBe('red')
66
expect(await getColor('h2')).toBe('blue')
77
expect(await getColor('.dynamic')).toBe('green')
8+
expect(await getColor('.chunk')).toBe('magenta')
89
})
910

1011
test('should load dynamic import with inline', async () => {
@@ -40,4 +41,8 @@ describe.runIf(isBuild)('build', () => {
4041
expect(manifest['index.html'].css.length).toBe(2)
4142
expect(manifest['other.js'].css.length).toBe(1)
4243
})
44+
45+
test('should not mark a css chunk with ?url and normal import as pure css chunk', () => {
46+
expect(findAssetFile(/chunk-.*\.js$/)).toBeTruthy()
47+
})
4348
})

playground/css-codesplit/chunk.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.chunk {
2+
color: magenta;
3+
}

playground/css-codesplit/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ <h2>This should be blue</h2>
1212
<button class="order-bulk-update">change to green</button>
1313
</p>
1414

15+
<p class="chunk">This should be magenta</p>
16+
1517
<script type="module" src="/main.js"></script>
1618
<div id="app"></div>

playground/css-codesplit/main.js

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import './style.css'
22
import './main.css'
33
import './order'
44

5+
import './chunk.css'
6+
import chunkCssUrl from './chunk.css?url'
7+
8+
// use this to not treeshake
9+
globalThis.__test_chunkCssUrl = chunkCssUrl
10+
511
import('./async.css')
612

713
import('./inline.css?inline').then((css) => {

playground/css-codesplit/other.js

+5
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
import './style.css'
2+
import './chunk.css'
3+
import chunkCssUrl from './chunk.css?url'
4+
5+
// use this to not treeshake
6+
globalThis.__test_chunkCssUrl = chunkCssUrl

playground/css-codesplit/vite.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ module.exports = {
88
main: resolve(__dirname, './index.html'),
99
other: resolve(__dirname, './other.js'),
1010
},
11+
output: {
12+
manualChunks(id) {
13+
// make `chunk.css` it's own chunk for easier testing of pure css chunks
14+
if (id.includes('chunk.css')) {
15+
return 'chunk'
16+
}
17+
},
18+
},
1119
},
1220
},
1321
}

0 commit comments

Comments
 (0)