From a873af5d3d0b59ee8c1f982ad6ff821b7119c8fb Mon Sep 17 00:00:00 2001
From: Bjorn Lu
Date: Sun, 19 Feb 2023 02:30:14 +0800
Subject: [PATCH] fix(css): handle pure css chunk heuristic with special
queries (#12091)
---
packages/vite/src/node/plugins/css.ts | 16 +++++++++-------
.../__tests__/css-codesplit.spec.ts | 5 +++++
playground/css-codesplit/chunk.css | 3 +++
playground/css-codesplit/index.html | 2 ++
playground/css-codesplit/main.js | 6 ++++++
playground/css-codesplit/other.js | 5 +++++
playground/css-codesplit/vite.config.js | 8 ++++++++
7 files changed, 38 insertions(+), 7 deletions(-)
create mode 100644 playground/css-codesplit/chunk.css
diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts
index 72ac5821348f9e..c53c1def013550 100644
--- a/packages/vite/src/node/plugins/css.ts
+++ b/packages/vite/src/node/plugins/css.ts
@@ -464,15 +464,17 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
let isPureCssChunk = true
const ids = Object.keys(chunk.modules)
for (const id of ids) {
- if (
- !isCSSRequest(id) ||
- cssModuleRE.test(id) ||
- commonjsProxyRE.test(id)
- ) {
- isPureCssChunk = false
- }
if (styles.has(id)) {
chunkCSS += styles.get(id)
+ // a css module contains JS, so it makes this not a pure css chunk
+ if (cssModuleRE.test(id)) {
+ isPureCssChunk = false
+ }
+ } else {
+ // if the module does not have a style, then it's not a pure css chunk.
+ // this is true because in the `transform` hook above, only modules
+ // that are css gets added to the `styles` map.
+ isPureCssChunk = false
}
}
diff --git a/playground/css-codesplit/__tests__/css-codesplit.spec.ts b/playground/css-codesplit/__tests__/css-codesplit.spec.ts
index e1d34784117fbb..e1b4f26fc6a9e3 100644
--- a/playground/css-codesplit/__tests__/css-codesplit.spec.ts
+++ b/playground/css-codesplit/__tests__/css-codesplit.spec.ts
@@ -5,6 +5,7 @@ test('should load all stylesheets', async () => {
expect(await getColor('h1')).toBe('red')
expect(await getColor('h2')).toBe('blue')
expect(await getColor('.dynamic')).toBe('green')
+ expect(await getColor('.chunk')).toBe('magenta')
})
test('should load dynamic import with inline', async () => {
@@ -40,4 +41,8 @@ describe.runIf(isBuild)('build', () => {
expect(manifest['index.html'].css.length).toBe(2)
expect(manifest['other.js'].css.length).toBe(1)
})
+
+ test('should not mark a css chunk with ?url and normal import as pure css chunk', () => {
+ expect(findAssetFile(/chunk-.*\.js$/)).toBeTruthy()
+ })
})
diff --git a/playground/css-codesplit/chunk.css b/playground/css-codesplit/chunk.css
new file mode 100644
index 00000000000000..a8aa47c2d96134
--- /dev/null
+++ b/playground/css-codesplit/chunk.css
@@ -0,0 +1,3 @@
+.chunk {
+ color: magenta;
+}
diff --git a/playground/css-codesplit/index.html b/playground/css-codesplit/index.html
index 37baa5dd37a848..7d2a4991f20e0a 100644
--- a/playground/css-codesplit/index.html
+++ b/playground/css-codesplit/index.html
@@ -12,5 +12,7 @@ This should be blue
+This should be magenta
+
diff --git a/playground/css-codesplit/main.js b/playground/css-codesplit/main.js
index e128734112ee5a..e548142add8786 100644
--- a/playground/css-codesplit/main.js
+++ b/playground/css-codesplit/main.js
@@ -2,6 +2,12 @@ import './style.css'
import './main.css'
import './order'
+import './chunk.css'
+import chunkCssUrl from './chunk.css?url'
+
+// use this to not treeshake
+globalThis.__test_chunkCssUrl = chunkCssUrl
+
import('./async.css')
import('./inline.css?inline').then((css) => {
diff --git a/playground/css-codesplit/other.js b/playground/css-codesplit/other.js
index cab743adef7757..4560c4d53c29ac 100644
--- a/playground/css-codesplit/other.js
+++ b/playground/css-codesplit/other.js
@@ -1 +1,6 @@
import './style.css'
+import './chunk.css'
+import chunkCssUrl from './chunk.css?url'
+
+// use this to not treeshake
+globalThis.__test_chunkCssUrl = chunkCssUrl
diff --git a/playground/css-codesplit/vite.config.js b/playground/css-codesplit/vite.config.js
index 7f493850ff10d5..870060f7e6c382 100644
--- a/playground/css-codesplit/vite.config.js
+++ b/playground/css-codesplit/vite.config.js
@@ -8,6 +8,14 @@ module.exports = {
main: resolve(__dirname, './index.html'),
other: resolve(__dirname, './other.js'),
},
+ output: {
+ manualChunks(id) {
+ // make `chunk.css` it's own chunk for easier testing of pure css chunks
+ if (id.includes('chunk.css')) {
+ return 'chunk'
+ }
+ },
+ },
},
},
}