From 89a3db0d9f7f34278da2d8e03f656bdd5c8934a7 Mon Sep 17 00:00:00 2001 From: patak Date: Fri, 28 Jul 2023 11:50:31 +0200 Subject: [PATCH] fix: multiple entries with shared css and no JS (#13962) --- packages/vite/src/node/plugins/html.ts | 4 +++- .../css-codesplit/__tests__/css-codesplit.spec.ts | 8 ++++++++ playground/css-codesplit/shared-css-empty-1.js | 4 ++++ playground/css-codesplit/shared-css-empty-2.js | 4 ++++ playground/css-codesplit/shared-css-main.js | 10 ++++++++++ playground/css-codesplit/shared-css-no-js.html | 4 ++++ playground/css-codesplit/shared-css-theme.css | 3 +++ playground/css-codesplit/shared-css-with-js.html | 6 ++++++ playground/css-codesplit/vite.config.js | 2 ++ 9 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 playground/css-codesplit/shared-css-empty-1.js create mode 100644 playground/css-codesplit/shared-css-empty-2.js create mode 100644 playground/css-codesplit/shared-css-main.js create mode 100644 playground/css-codesplit/shared-css-no-js.html create mode 100644 playground/css-codesplit/shared-css-theme.css create mode 100644 playground/css-codesplit/shared-css-with-js.html diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 1948c169b..707345a55 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -600,7 +600,9 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { js = `import "${modulePreloadPolyfillId}";\n${js}` } - return js + // Force rollup to keep this module from being shared between other entry points. + // If the resulting chunk is empty, it will be removed in generateBundle. + return { code: js, moduleSideEffects: 'no-treeshake' } } }, diff --git a/playground/css-codesplit/__tests__/css-codesplit.spec.ts b/playground/css-codesplit/__tests__/css-codesplit.spec.ts index 99d1f2d70..2f7d5ab5f 100644 --- a/playground/css-codesplit/__tests__/css-codesplit.spec.ts +++ b/playground/css-codesplit/__tests__/css-codesplit.spec.ts @@ -43,6 +43,14 @@ describe.runIf(isBuild)('build', () => { expect(findAssetFile(/async.*\.js$/)).toBe('') }) + test('should remove empty chunk, HTML without JS', async () => { + const sharedCSSWithJSChunk = findAssetFile('shared-css-with-js.*.js$') + expect(sharedCSSWithJSChunk).toMatch(`/* empty css`) + // there are functions and modules in the src code that should be tree-shaken + expect(sharedCSSWithJSChunk).not.toMatch('function') + expect(sharedCSSWithJSChunk).not.toMatch(/import(?!".\/modulepreload)/) + }) + test('should generate correct manifest', async () => { const manifest = readManifest() expect(manifest['index.html'].css.length).toBe(2) diff --git a/playground/css-codesplit/shared-css-empty-1.js b/playground/css-codesplit/shared-css-empty-1.js new file mode 100644 index 000000000..80636d362 --- /dev/null +++ b/playground/css-codesplit/shared-css-empty-1.js @@ -0,0 +1,4 @@ +function shouldBeTreeshaken_1() { + // This function should be treeshaken, even if { moduleSideEffects: 'no-treeshake' } + // was used in the JS corresponding to the HTML entrypoint. +} diff --git a/playground/css-codesplit/shared-css-empty-2.js b/playground/css-codesplit/shared-css-empty-2.js new file mode 100644 index 000000000..7ce6d3062 --- /dev/null +++ b/playground/css-codesplit/shared-css-empty-2.js @@ -0,0 +1,4 @@ +export default function shouldBeTreeshaken_2() { + // This function should be treeshaken, even if { moduleSideEffects: 'no-treeshake' } + // was used in the JS corresponding to the HTML entrypoint. +} diff --git a/playground/css-codesplit/shared-css-main.js b/playground/css-codesplit/shared-css-main.js new file mode 100644 index 000000000..639861b66 --- /dev/null +++ b/playground/css-codesplit/shared-css-main.js @@ -0,0 +1,10 @@ +import shouldTreeshake from './shared-css-empty-2.js' +document.querySelector('#app').innerHTML = ` +
+

Shared CSS, with JS

+
+` +function shouldBeTreeshaken_0() { + // This function should be treeshaken, even if { moduleSideEffects: 'no-treeshake' } + // was used in the JS corresponding to the HTML entrypoint. +} diff --git a/playground/css-codesplit/shared-css-no-js.html b/playground/css-codesplit/shared-css-no-js.html new file mode 100644 index 000000000..27c666af8 --- /dev/null +++ b/playground/css-codesplit/shared-css-no-js.html @@ -0,0 +1,4 @@ + + +

Share CSS, no JS

+ diff --git a/playground/css-codesplit/shared-css-theme.css b/playground/css-codesplit/shared-css-theme.css new file mode 100644 index 000000000..adc68fa6a --- /dev/null +++ b/playground/css-codesplit/shared-css-theme.css @@ -0,0 +1,3 @@ +h1 { + color: red; +} diff --git a/playground/css-codesplit/shared-css-with-js.html b/playground/css-codesplit/shared-css-with-js.html new file mode 100644 index 000000000..aaa856f2c --- /dev/null +++ b/playground/css-codesplit/shared-css-with-js.html @@ -0,0 +1,6 @@ + + + + +

Replaced by shared-css-main.js

+ diff --git a/playground/css-codesplit/vite.config.js b/playground/css-codesplit/vite.config.js index 3e0d3ac35..5042b6d9b 100644 --- a/playground/css-codesplit/vite.config.js +++ b/playground/css-codesplit/vite.config.js @@ -9,6 +9,8 @@ export default defineConfig({ main: resolve(__dirname, './index.html'), other: resolve(__dirname, './other.js'), style2: resolve(__dirname, './style2.js'), + 'shared-css-with-js': resolve(__dirname, 'shared-css-with-js.html'), + 'shared-css-no-js': resolve(__dirname, 'shared-css-no-js.html'), }, output: { manualChunks(id) {