Skip to content

Commit 94ce7ab

Browse files
committed
fix: don't force terser on non-legacy (fix vitejs#6266)
This fixes two misbehaviors of the legacy plugin: 1. Respect {minify: false} for legacy assets. 2. Don't inflict es2019/terser on non-legacy chunks. For the first problem, we could have fixed by checking for false in viteLegacyPlugin.config(). Unfortunately that would have left the second problem unsolved. Without adding significant complexity to the config, there's no easy way to use different minifiers in the build depending on the individual chunk. So instead we include terserPlugin() whenever minify is enabled, even true or 'esbuild', then check the actual configuration in the plugin. This allows the legacy plugin to inject its special override, leaving all the non-legacy stuff intact and uncomplicated. See also, previous attempts: vitejs#5157 vitejs#5168
1 parent 1f945f6 commit 94ce7ab

File tree

4 files changed

+33
-19
lines changed

4 files changed

+33
-19
lines changed

packages/playground/legacy/__tests__/legacy.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isBuild, readManifest, untilUpdated } from '../../testUtils'
1+
import { findAssetFile, isBuild, listAssets, readManifest, untilUpdated } from '../../testUtils'
22

33
test('should work', async () => {
44
expect(await page.textContent('#app')).toMatch('Hello')
@@ -53,4 +53,19 @@ if (isBuild) {
5353
'../../../vite/legacy-polyfills'
5454
)
5555
})
56+
57+
test('should minify legacy chunks with terser', async () => {
58+
// This is a ghetto heuristic, but terser output seems to reliably start
59+
// with one of the following, and non-terser output (including unminified or
60+
// ebuild-minified) does not!
61+
const terserPatt = /^(?:!function|System.register)/
62+
63+
expect(findAssetFile(/chunk-async-legacy/)).toMatch(terserPatt)
64+
expect(findAssetFile(/chunk-async\./)).not.toMatch(terserPatt)
65+
expect(findAssetFile(/immutable-chunk-legacy/)).toMatch(terserPatt)
66+
expect(findAssetFile(/immutable-chunk\./)).not.toMatch(terserPatt)
67+
expect(findAssetFile(/index-legacy/)).toMatch(terserPatt)
68+
expect(findAssetFile(/index\./)).not.toMatch(terserPatt)
69+
expect(findAssetFile(/polyfills-legacy/)).toMatch(terserPatt)
70+
})
5671
}

packages/plugin-legacy/index.js

+5-17
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,6 @@ function viteLegacyPlugin(options = {}) {
105105
name: 'vite:legacy-generate-polyfill-chunk',
106106
apply: 'build',
107107

108-
config() {
109-
return {
110-
build: {
111-
minify: 'terser'
112-
}
113-
}
114-
},
115-
116-
configResolved(config) {
117-
if (!config.build.ssr && genLegacy && config.build.minify === 'esbuild') {
118-
throw new Error(
119-
`Can't use esbuild as the minifier when targeting legacy browsers ` +
120-
`because esbuild minification is not legacy safe.`
121-
)
122-
}
123-
},
124-
125108
async generateBundle(opts, bundle) {
126109
if (config.build.ssr) {
127110
return
@@ -297,6 +280,11 @@ function viteLegacyPlugin(options = {}) {
297280
// legacy-unsafe code - e.g. rewriting object properties into shorthands
298281
opts.__vite_skip_esbuild__ = true
299282

283+
// @ts-ignore force terser for legacy chunks. This only takes effect if
284+
// minification isn't disabled, because that leaves out the terser plugin
285+
// entirely.
286+
opts.__vite_force_terser__ = true
287+
300288
const needPolyfills =
301289
options.polyfills !== false && !Array.isArray(options.polyfills)
302290

packages/vite/src/node/build.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export function resolveBuildPlugins(config: ResolvedConfig): {
365365
post: [
366366
buildImportAnalysisPlugin(config),
367367
buildEsbuildPlugin(config),
368-
...(options.minify === 'terser' ? [terserPlugin(config)] : []),
368+
...(options.minify ? [terserPlugin(config)] : []),
369369
...(options.manifest ? [manifestPlugin(config)] : []),
370370
...(options.ssrManifest ? [ssrManifestPlugin(config)] : []),
371371
buildReporterPlugin(config),

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

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
2121
name: 'vite:terser',
2222

2323
async renderChunk(code, _chunk, outputOptions) {
24+
// This plugin is included for any non-false value of config.build.minify,
25+
// so that normal chunks can use the preferred minifier, and legacy chunks
26+
// can use terser.
27+
if (
28+
config.build.minify !== 'terser' &&
29+
// @ts-ignore injected by @vitejs/plugin-legacy
30+
!outputOptions.__vite_force_terser__
31+
) {
32+
return null
33+
}
34+
2435
// Do not minify ES lib output since that would remove pure annotations
2536
// and break tree-shaking
2637
if (config.build.lib && outputOptions.format === 'es') {

0 commit comments

Comments
 (0)