diff --git a/docs/config/build-options.md b/docs/config/build-options.md index f49d5454716fff..0585be653671e6 100644 --- a/docs/config/build-options.md +++ b/docs/config/build-options.md @@ -209,6 +209,8 @@ npm add -D terser Additional [minify options](https://terser.org/docs/api-reference#minify-options) to pass on to Terser. +In addition, you can also pass a `maxWorkers: number` option to specify the max number of workers to spawn. Defaults to the number of CPUs minus 1. + ## build.write - **Type:** `boolean` diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 957ee92d046056..c1f5821e4a7b40 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -18,7 +18,6 @@ import type { RollupWatcher, WatcherOptions, } from 'rollup' -import type { Terser } from 'dep-types/terser' import commonjsPlugin from '@rollup/plugin-commonjs' import type { RollupCommonJSOptions } from 'dep-types/commonjs' import type { RollupDynamicImportVarsOptions } from 'dep-types/dynamicImportVars' @@ -27,7 +26,7 @@ import type { InlineConfig, ResolvedConfig } from './config' import { isDepsOptimizerEnabled, resolveConfig } from './config' import { buildReporterPlugin } from './plugins/reporter' import { buildEsbuildPlugin } from './plugins/esbuild' -import { terserPlugin } from './plugins/terser' +import { type TerserOptions, terserPlugin } from './plugins/terser' import { asyncFlatten, copyDir, @@ -143,8 +142,11 @@ export interface BuildOptions { /** * Options for terser * https://terser.org/docs/api-reference#minify-options + * + * In addition, you can also pass a `maxWorkers: number` option to specify the + * max number of workers to spawn. Defaults to the number of CPUs minus 1. */ - terserOptions?: Terser.MinifyOptions + terserOptions?: TerserOptions /** * Will be merged with internal rollup options. * https://rollupjs.org/configuration-options/ diff --git a/packages/vite/src/node/index.ts b/packages/vite/src/node/index.ts index b64e99942a9b1e..3d21243d0ab534 100644 --- a/packages/vite/src/node/index.ts +++ b/packages/vite/src/node/index.ts @@ -82,6 +82,7 @@ export type { ESBuildOptions, ESBuildTransformResult } from './plugins/esbuild' export type { Manifest, ManifestChunk } from './plugins/manifest' export type { ResolveOptions, InternalResolveOptions } from './plugins/resolve' export type { SplitVendorChunkCache } from './plugins/splitVendorChunk' +export type { TerserOptions } from './plugins/terser' export type { WebSocketServer, diff --git a/packages/vite/src/node/plugins/terser.ts b/packages/vite/src/node/plugins/terser.ts index 40f28cb9daccaf..c1522065750dbf 100644 --- a/packages/vite/src/node/plugins/terser.ts +++ b/packages/vite/src/node/plugins/terser.ts @@ -4,6 +4,16 @@ import type { Plugin } from '../plugin' import type { ResolvedConfig } from '..' import { requireResolveFromRootWithFallback } from '../utils' +export interface TerserOptions extends Terser.MinifyOptions { + /** + * Vite-specific option to specify the max number of workers to spawn + * when minifying files with terser. + * + * @default number of CPUs minus 1 + */ + maxWorkers?: number +} + let terserPath: string | undefined const loadTerserPath = (root: string) => { if (terserPath) return terserPath @@ -24,6 +34,8 @@ const loadTerserPath = (root: string) => { } export function terserPlugin(config: ResolvedConfig): Plugin { + const { maxWorkers, ...terserOptions } = config.build.terserOptions + const makeWorker = () => new Worker( async ( @@ -36,6 +48,9 @@ export function terserPlugin(config: ResolvedConfig): Plugin { const terser = require(terserPath) return terser.minify(code, options) as Terser.MinifyOutput }, + { + max: maxWorkers, + }, ) let worker: ReturnType @@ -67,7 +82,7 @@ export function terserPlugin(config: ResolvedConfig): Plugin { const terserPath = loadTerserPath(config.root) const res = await worker.run(terserPath, code, { safari10: true, - ...config.build.terserOptions, + ...terserOptions, sourceMap: !!outputOptions.sourcemap, module: outputOptions.format.startsWith('es'), toplevel: outputOptions.format === 'cjs',