Skip to content

Commit 0b25cc1

Browse files
authored
fix(css): remove ?used hack (fixes #6421, #8245) (#8278)
1 parent 0667585 commit 0b25cc1

File tree

4 files changed

+16
-52
lines changed

4 files changed

+16
-52
lines changed

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ const htmlProxyRE = /(\?|&)html-proxy\b/
108108
const commonjsProxyRE = /\?commonjs-proxy/
109109
const inlineRE = /(\?|&)inline\b/
110110
const inlineCSSRE = /(\?|&)inline-css\b/
111-
const usedRE = /(\?|&)used\b/
112111
const varRE = /^var\(/i
113112

114113
const cssBundleName = 'style.css'
@@ -406,18 +405,19 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin {
406405
}
407406

408407
let code: string
409-
if (usedRE.test(id)) {
410-
if (modulesCode) {
411-
code = modulesCode
412-
} else {
413-
let content = css
414-
if (config.build.minify) {
415-
content = await minifyCSS(content, config)
416-
}
417-
code = `export default ${JSON.stringify(content)}`
418-
}
408+
if (modulesCode) {
409+
code = modulesCode
419410
} else {
420-
code = `export default ''`
411+
let content = css
412+
if (config.build.minify) {
413+
content = await minifyCSS(content, config)
414+
}
415+
// marking as pure to make it tree-shakable by minifier
416+
// but the module itself is still treated as a non tree-shakable module
417+
// because moduleSideEffects is 'no-treeshake'
418+
code = `export default /* #__PURE__ */ (() => ${JSON.stringify(
419+
content
420+
)})()`
421421
}
422422

423423
return {

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

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import type { ImportSpecifier } from 'es-module-lexer'
44
import { init, parse as parseImports } from 'es-module-lexer'
55
import type { OutputChunk, SourceMap } from 'rollup'
66
import type { RawSourceMap } from '@ampproject/remapping'
7-
import { bareImportRE, combineSourcemaps, isRelativeBase } from '../utils'
7+
import { combineSourcemaps, isRelativeBase } from '../utils'
88
import type { Plugin } from '../plugin'
99
import type { ResolvedConfig } from '../config'
1010
import { genSourceMapUrl } from '../server/sourcemap'
11-
import { isCSSRequest, removedPureCssFilesCache } from './css'
11+
import { removedPureCssFilesCache } from './css'
1212

1313
/**
1414
* A flag for injected helpers. This flag will be set to `false` if the output
@@ -145,14 +145,7 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
145145
let needPreloadHelper = false
146146

147147
for (let index = 0; index < imports.length; index++) {
148-
const {
149-
s: start,
150-
e: end,
151-
ss: expStart,
152-
se: expEnd,
153-
n: specifier,
154-
d: dynamicIndex
155-
} = imports[index]
148+
const { ss: expStart, se: expEnd, d: dynamicIndex } = imports[index]
156149

157150
const isDynamic = dynamicIndex > -1
158151

@@ -166,27 +159,6 @@ export function buildImportAnalysisPlugin(config: ResolvedConfig): Plugin {
166159
})`
167160
)
168161
}
169-
170-
// Differentiate CSS imports that use the default export from those that
171-
// do not by injecting a ?used query - this allows us to avoid including
172-
// the CSS string when unnecessary (esbuild has trouble tree-shaking
173-
// them)
174-
if (
175-
specifier &&
176-
isCSSRequest(specifier) &&
177-
// always inject ?used query when it is a dynamic import
178-
// because there is no way to check whether the default export is used
179-
(source.slice(expStart, start).includes('from') || isDynamic) &&
180-
// already has ?used query (by import.meta.glob)
181-
!specifier.match(/\?used(&|$)/) &&
182-
// edge case for package names ending with .css (e.g normalize.css)
183-
!(bareImportRE.test(specifier) && !specifier.includes('/'))
184-
) {
185-
const url = specifier.replace(/\?|$/, (m) => `?used${m ? '&' : ''}`)
186-
str().overwrite(start, end, isDynamic ? `'${url}'` : url, {
187-
contentOnly: true
188-
})
189-
}
190162
}
191163

192164
if (

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import type { ViteDevServer } from '../server'
1818
import type { ModuleNode } from '../server/moduleGraph'
1919
import type { ResolvedConfig } from '../config'
2020
import { normalizePath, slash } from '../utils'
21-
import { isCSSRequest } from './css'
2221

2322
const { isMatch, scan } = micromatch
2423

@@ -393,9 +392,6 @@ export async function transformGlobImport(
393392
let importPath = paths.importPath
394393
let importQuery = query
395394

396-
if (isCSSRequest(file))
397-
importQuery = importQuery ? `${importQuery}&used` : '?used'
398-
399395
if (importQuery && importQuery !== '?raw') {
400396
const fileExtension = basename(file).split('.').slice(-1)[0]
401397
if (fileExtension && restoreQueryExtension)

playground/css/__tests__/css.spec.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,5 @@ test("relative path rewritten in Less's data-uri", async () => {
415415
test('PostCSS source.input.from includes query', async () => {
416416
const code = await page.textContent('.postcss-source-input')
417417
// should resolve assets
418-
expect(code).toContain(
419-
isBuild
420-
? '/postcss-source-input.css?used&query=foo'
421-
: '/postcss-source-input.css?query=foo'
422-
)
418+
expect(code).toContain('/postcss-source-input.css?query=foo')
423419
})

0 commit comments

Comments
 (0)