From 03a1bc7b946ab9efb3b4929e725d94e8f88efaa0 Mon Sep 17 00:00:00 2001 From: sapphi-red Date: Fri, 1 Jul 2022 12:36:01 +0900 Subject: [PATCH] fix: reverts #8471 This reverts commit 8d7bac416003cc0268a269cba6630162b1ac7412. --- packages/playground/css/__tests__/css.spec.ts | 6 ++++- packages/vite/src/node/importGlob.ts | 7 ++++-- packages/vite/src/node/plugins/css.ts | 24 +++++++++---------- .../src/node/plugins/importAnalysisBuild.ts | 22 +++++++++++++++-- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/playground/css/__tests__/css.spec.ts b/packages/playground/css/__tests__/css.spec.ts index 5573936d8ae408..24589d63b52451 100644 --- a/packages/playground/css/__tests__/css.spec.ts +++ b/packages/playground/css/__tests__/css.spec.ts @@ -422,7 +422,11 @@ test("relative path rewritten in Less's data-uri", async () => { test('PostCSS source.input.from includes query', async () => { const code = await page.textContent('.postcss-source-input') // should resolve assets - expect(code).toContain('/postcss-source-input.css?query=foo') + expect(code).toContain( + isBuild + ? '/postcss-source-input.css?used&query=foo' + : '/postcss-source-input.css?query=foo' + ) }) test('aliased css has content', async () => { diff --git a/packages/vite/src/node/importGlob.ts b/packages/vite/src/node/importGlob.ts index 0af49b8dc51268..70ad62321236bb 100644 --- a/packages/vite/src/node/importGlob.ts +++ b/packages/vite/src/node/importGlob.ts @@ -9,6 +9,7 @@ import { preloadMarker, preloadMethod } from './plugins/importAnalysisBuild' +import { isCSSRequest } from './plugins/css' import { blankReplacer, cleanUrl, @@ -149,14 +150,16 @@ export async function transformImportGlob( await fsp.readFile(path.join(base, files[i]), 'utf-8') )},` } else { + const importeeUrl = isCSSRequest(importee) ? `${importee}?used` : importee if (isEager) { const identifier = `__glob_${importIndex}_${i}` + // css imports injecting a ?used query to export the css string importsString += `import ${ isEagerDefault ? `` : `* as ` - }${identifier} from ${JSON.stringify(importee)};` + }${identifier} from ${JSON.stringify(importeeUrl)};` entries += ` ${JSON.stringify(file)}: ${identifier},` } else { - let imp = `import(${JSON.stringify(importee)})` + let imp = `import(${JSON.stringify(importeeUrl)})` if (!normalizeUrl && preload) { imp = `(${isModernFlag}` + diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 87add94d261845..e3532cec97cbf6 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -102,6 +102,7 @@ const htmlProxyRE = /(\?|&)html-proxy\b/ const commonjsProxyRE = /\?commonjs-proxy/ const inlineRE = /(\?|&)inline\b/ const inlineCSSRE = /(\?|&)inline-css\b/ +const usedRE = /(\?|&)used\b/ const varRE = /^var\(/i const enum PreprocessLang { @@ -369,19 +370,18 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { } let code: string - if (modulesCode) { - code = modulesCode - } else { - let content = css - if (config.build.minify) { - content = await minifyCSS(content, config) + if (usedRE.test(id)) { + if (modulesCode) { + code = modulesCode + } else { + let content = css + if (config.build.minify) { + content = await minifyCSS(content, config) + } + code = `export default ${JSON.stringify(content)}` } - // marking as pure to make it tree-shakable by minifier - // but the module itself is still treated as a non tree-shakable module - // because moduleSideEffects is 'no-treeshake' - code = `export default /* #__PURE__ */ (() => ${JSON.stringify( - content - )})()` + } else { + code = `export default ''` } return { diff --git a/packages/vite/src/node/plugins/importAnalysisBuild.ts b/packages/vite/src/node/plugins/importAnalysisBuild.ts index dbe2ffd79770bf..effa22a0e5651a 100644 --- a/packages/vite/src/node/plugins/importAnalysisBuild.ts +++ b/packages/vite/src/node/plugins/importAnalysisBuild.ts @@ -5,11 +5,11 @@ import { init, parse as parseImports } from 'es-module-lexer' import type { OutputChunk, SourceMap } from 'rollup' import type { RawSourceMap } from '@ampproject/remapping' import { transformImportGlob } from '../importGlob' -import { combineSourcemaps } from '../utils' +import { bareImportRE, combineSourcemaps } from '../utils' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '../config' import { genSourceMapUrl } from '../server/sourcemap' -import { removedPureCssFilesCache } from './css' +import { isCSSRequest, removedPureCssFilesCache } from './css' /** * A flag for injected helpers. This flag will be set to `false` if the output @@ -148,6 +148,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { e: end, ss: expStart, se: expEnd, + n: specifier, d: dynamicIndex } = imports[index] @@ -194,6 +195,23 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin { const replacement = `${preloadMethod}(() => ${original},${isModernFlag}?"${preloadMarker}":void 0)` str().overwrite(expStart, expEnd, replacement, { contentOnly: true }) } + + // Differentiate CSS imports that use the default export from those that + // do not by injecting a ?used query - this allows us to avoid including + // the CSS string when unnecessary (esbuild has trouble tree-shaking + // them) + if ( + specifier && + isCSSRequest(specifier) && + source.slice(expStart, start).includes('from') && + // edge case for package names ending with .css (e.g normalize.css) + !(bareImportRE.test(specifier) && !specifier.includes('/')) + ) { + const url = specifier.replace(/\?|$/, (m) => `?used${m ? '&' : ''}`) + str().overwrite(start, end, dynamicIndex > -1 ? `'${url}'` : url, { + contentOnly: true + }) + } } if (