Skip to content

Commit d90409e

Browse files
authored
feat: respect esbuild minify config for css (#8811)
1 parent d5c5099 commit d90409e

File tree

10 files changed

+107
-7
lines changed

10 files changed

+107
-7
lines changed

docs/config/shared-options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ export default defineConfig({
280280
})
281281
```
282282

283-
When [`build.minify`](./build-options.md#build-minify) is `true`, you can configure to only minify [certain aspects](https://esbuild.github.io/api/#minify) of the code by setting either of `esbuild.minifyIdentifiers`, `esbuild.minifySyntax`, and `esbuild.minifyWhitespace` to `true`. Note the `esbuild.minify` option can't be used to override `build.minify`.
283+
When [`build.minify`](./build-options.md#build-minify) is `true`, all minify optimizations are applied by default. To disable [certain aspects](https://esbuild.github.io/api/#minify) of it, set any of `esbuild.minifyIdentifiers`, `esbuild.minifySyntax`, or `esbuild.minifyWhitespace` options to `false`. Note the `esbuild.minify` option can't be used to override `build.minify`.
284284

285285
Set to `false` to disable esbuild transforms.
286286

packages/vite/src/node/__tests__/plugins/esbuild.spec.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,31 @@ describe('resolveEsbuildTranspileOptions', () => {
4141
expect(options).toEqual(null)
4242
})
4343

44+
test('resolve specific minify options', () => {
45+
const options = resolveEsbuildTranspileOptions(
46+
defineResolvedConfig({
47+
build: {
48+
minify: 'esbuild'
49+
},
50+
esbuild: {
51+
keepNames: true,
52+
minifyIdentifiers: false
53+
}
54+
}),
55+
'es'
56+
)
57+
expect(options).toEqual({
58+
target: undefined,
59+
format: 'esm',
60+
keepNames: true,
61+
minify: false,
62+
minifyIdentifiers: false,
63+
minifySyntax: true,
64+
minifyWhitespace: true,
65+
treeShaking: true
66+
})
67+
})
68+
4469
test('resolve no minify', () => {
4570
const options = resolveEsbuildTranspileOptions(
4671
defineResolvedConfig({
@@ -140,6 +165,7 @@ describe('resolveEsbuildTranspileOptions', () => {
140165
keepNames: true,
141166
minify: false,
142167
minifyIdentifiers: true,
168+
minifySyntax: true,
143169
minifyWhitespace: false,
144170
treeShaking: true
145171
})
@@ -157,7 +183,7 @@ describe('resolveEsbuildTranspileOptions', () => {
157183
esbuild: {
158184
keepNames: true,
159185
minifyIdentifiers: true,
160-
minifyWhitespace: true,
186+
minifySyntax: false,
161187
treeShaking: true
162188
}
163189
}),
@@ -169,6 +195,7 @@ describe('resolveEsbuildTranspileOptions', () => {
169195
keepNames: true,
170196
minify: false,
171197
minifyIdentifiers: true,
198+
minifySyntax: false,
172199
minifyWhitespace: true,
173200
treeShaking: true
174201
})

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

+22-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type Sass from 'sass'
1919
import type Stylus from 'stylus'
2020
import type Less from 'less'
2121
import type { Alias } from 'types/alias'
22+
import type { TransformOptions } from 'esbuild'
2223
import { formatMessages, transform } from 'esbuild'
2324
import type { RawSourceMap } from '@ampproject/remapping'
2425
import { getCodeWithSourcemap, injectSourcesContent } from '../server/sourcemap'
@@ -55,6 +56,7 @@ import {
5556
publicFileToBuiltUrl,
5657
resolveAssetFileNames
5758
} from './asset'
59+
import type { ESBuildOptions } from './esbuild'
5860

5961
// const debug = createDebugger('vite:css')
6062

@@ -1211,8 +1213,8 @@ async function minifyCSS(css: string, config: ResolvedConfig) {
12111213
try {
12121214
const { code, warnings } = await transform(css, {
12131215
loader: 'css',
1214-
minify: true,
1215-
target: config.build.cssTarget || undefined
1216+
target: config.build.cssTarget || undefined,
1217+
...resolveEsbuildMinifyOptions(config.esbuild || {})
12161218
})
12171219
if (warnings.length) {
12181220
const msgs = await formatMessages(warnings, { kind: 'warning' })
@@ -1231,6 +1233,24 @@ async function minifyCSS(css: string, config: ResolvedConfig) {
12311233
}
12321234
}
12331235

1236+
function resolveEsbuildMinifyOptions(
1237+
options: ESBuildOptions
1238+
): TransformOptions {
1239+
if (
1240+
options.minifyIdentifiers != null ||
1241+
options.minifySyntax != null ||
1242+
options.minifyWhitespace != null
1243+
) {
1244+
return {
1245+
minifyIdentifiers: options.minifyIdentifiers ?? true,
1246+
minifySyntax: options.minifySyntax ?? true,
1247+
minifyWhitespace: options.minifyWhitespace ?? true
1248+
}
1249+
} else {
1250+
return { minify: true }
1251+
}
1252+
}
1253+
12341254
export async function hoistAtRules(css: string): Promise<string> {
12351255
const s = new MagicString(css)
12361256
const cleanCss = emptyCssComments(css)

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -318,22 +318,27 @@ export function resolveEsbuildTranspileOptions(
318318

319319
// If user enable fine-grain minify options, minify with their options instead
320320
if (
321-
options.minifyIdentifiers ||
322-
options.minifySyntax ||
323-
options.minifyWhitespace
321+
options.minifyIdentifiers != null ||
322+
options.minifySyntax != null ||
323+
options.minifyWhitespace != null
324324
) {
325325
if (isEsLibBuild) {
326326
// Disable minify whitespace as it breaks tree-shaking
327327
return {
328328
...options,
329329
minify: false,
330+
minifyIdentifiers: options.minifyIdentifiers ?? true,
331+
minifySyntax: options.minifySyntax ?? true,
330332
minifyWhitespace: false,
331333
treeShaking: true
332334
}
333335
} else {
334336
return {
335337
...options,
336338
minify: false,
339+
minifyIdentifiers: options.minifyIdentifiers ?? true,
340+
minifySyntax: options.minifySyntax ?? true,
341+
minifyWhitespace: options.minifyWhitespace ?? true,
337342
treeShaking: true
338343
}
339344
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import fs from 'node:fs'
2+
import path from 'node:path'
3+
import { expect, test } from 'vitest'
4+
import { isBuild, readFile, testDir } from '~utils'
5+
6+
test.runIf(isBuild)('no minifySyntax', () => {
7+
const assetsDir = path.resolve(testDir, 'dist/assets')
8+
const files = fs.readdirSync(assetsDir)
9+
10+
const jsFile = files.find((f) => f.endsWith('.js'))
11+
const jsContent = readFile(path.resolve(assetsDir, jsFile))
12+
13+
const cssFile = files.find((f) => f.endsWith('.css'))
14+
const cssContent = readFile(path.resolve(assetsDir, cssFile))
15+
16+
expect(jsContent).toContain('{console.log("hello world")}')
17+
expect(cssContent).toContain('color:#ff0000')
18+
})

playground/minify/index.html

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<h1>Minify</h1>
2+
3+
<script type="module" src="./main.js"></script>

playground/minify/main.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import './test.css'
2+
3+
if (window) {
4+
console.log('hello world')
5+
}

playground/minify/package.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "test-minify",
3+
"private": true,
4+
"version": "0.0.0",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"debug": "node --inspect-brk ../../packages/vite/bin/vite",
9+
"preview": "vite preview"
10+
}
11+
}

playground/minify/test.css

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
h1 {
2+
/* do not minify as red text */
3+
color: #ff0000;
4+
}

playground/minify/vite.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vite'
2+
3+
export default defineConfig({
4+
esbuild: {
5+
minifySyntax: false
6+
}
7+
})

0 commit comments

Comments
 (0)