From 12b612d8be2a18456fd94a2f0291d32d1ffb29d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=20/=20green?= Date: Wed, 18 Dec 2024 05:32:18 +0900 Subject: [PATCH] fix: fallback terser to main thread when function options are used (#18987) Co-authored-by: Wout Mertens --- packages/vite/package.json | 1 + .../src/node/__tests__/plugins/terser.spec.ts | 55 +++++++++++++++++++ packages/vite/src/node/plugins/terser.ts | 14 ++++- pnpm-lock.yaml | 3 + 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 packages/vite/src/node/__tests__/plugins/terser.spec.ts diff --git a/packages/vite/package.json b/packages/vite/package.json index e1a248654953d7..d28214f6777783 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -145,6 +145,7 @@ "sirv": "^3.0.0", "source-map-support": "^0.5.21", "strip-literal": "^2.1.1", + "terser": "^5.37.0", "tinyglobby": "^0.2.10", "tsconfck": "^3.1.4", "tslib": "^2.8.1", diff --git a/packages/vite/src/node/__tests__/plugins/terser.spec.ts b/packages/vite/src/node/__tests__/plugins/terser.spec.ts new file mode 100644 index 00000000000000..9fed1ec2c5ee7e --- /dev/null +++ b/packages/vite/src/node/__tests__/plugins/terser.spec.ts @@ -0,0 +1,55 @@ +import { resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import { describe, expect, test } from 'vitest' +import { build } from 'vite' +import type { RollupOutput } from 'rollup' +import type { TerserOptions } from '../../plugins/terser' + +const __dirname = resolve(fileURLToPath(import.meta.url), '..') + +describe('terser', () => { + const run = async (terserOptions: TerserOptions) => { + const result = (await build({ + root: resolve(__dirname, '../packages/build-project'), + logLevel: 'silent', + build: { + write: false, + minify: 'terser', + terserOptions, + }, + plugins: [ + { + name: 'test', + resolveId(id) { + if (id === 'entry.js') { + return '\0' + id + } + }, + load(id) { + if (id === '\0entry.js') { + return `const foo = 1;console.log(foo)` + } + }, + }, + ], + })) as RollupOutput + return result.output[0].code + } + + test('basic', async () => { + await run({}) + }) + + test('nth', async () => { + const resultCode = await run({ + mangle: { + nth_identifier: { + get: (n) => { + return 'prefix_' + n.toString() + }, + }, + }, + }) + expect(resultCode).toContain('prefix_') + }) +}) diff --git a/packages/vite/src/node/plugins/terser.ts b/packages/vite/src/node/plugins/terser.ts index 9c254dee1043af..3b35024d21e684 100644 --- a/packages/vite/src/node/plugins/terser.ts +++ b/packages/vite/src/node/plugins/terser.ts @@ -1,5 +1,5 @@ import type { Terser } from 'dep-types/terser' -import { Worker } from 'artichokie' +import { WorkerWithFallback } from 'artichokie' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '..' import { requireResolveFromRootWithFallback } from '../utils' @@ -37,7 +37,7 @@ export function terserPlugin(config: ResolvedConfig): Plugin { const { maxWorkers, ...terserOptions } = config.build.terserOptions const makeWorker = () => - new Worker( + new WorkerWithFallback( () => async ( terserPath: string, @@ -50,6 +50,16 @@ export function terserPlugin(config: ResolvedConfig): Plugin { return terser.minify(code, options) as Terser.MinifyOutput }, { + shouldUseFake(_terserPath, _code, options) { + return !!( + (typeof options.mangle === 'object' && + (options.mangle.nth_identifier?.get || + (typeof options.mangle.properties === 'object' && + options.mangle.properties.nth_identifier?.get))) || + typeof options.format?.comments === 'function' || + typeof options.output?.comments === 'function' + ) + }, max: maxWorkers, }, ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90a196a6eecbcb..8c995e2fb93a89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -393,6 +393,9 @@ importers: strip-literal: specifier: ^2.1.1 version: 2.1.1 + terser: + specifier: ^5.37.0 + version: 5.37.0 tinyglobby: specifier: ^0.2.10 version: 0.2.10