/
terser.ts
64 lines (56 loc) · 1.92 KB
/
terser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { Worker } from 'okie'
import type { Terser } from 'types/terser'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '..'
export function terserPlugin(config: ResolvedConfig): Plugin {
const makeWorker = () =>
new Worker(
async (basedir: string, code: string, options: Terser.MinifyOptions) => {
// when vite is linked, the worker thread won't share the same resolve
// root with vite itself, so we have to pass in the basedir and resolve
// terser first.
// eslint-disable-next-line node/no-restricted-require
const terserPath = require.resolve('terser', {
paths: [basedir]
})
return require(terserPath).minify(code, options) as Terser.MinifyOutput
}
)
let worker: ReturnType<typeof makeWorker>
return {
name: 'vite:terser',
async renderChunk(code, _chunk, outputOptions) {
// This plugin is included for any non-false value of config.build.minify,
// so that normal chunks can use the preferred minifier, and legacy chunks
// can use terser.
if (
config.build.minify !== 'terser' &&
// @ts-ignore injected by @vitejs/plugin-legacy
!outputOptions.__vite_force_terser__
) {
return null
}
// Do not minify ES lib output since that would remove pure annotations
// and break tree-shaking.
if (config.build.lib && outputOptions.format === 'es') {
return null
}
// Lazy load worker.
worker ||= makeWorker()
const res = await worker.run(__dirname, code, {
safari10: true,
...config.build.terserOptions,
sourceMap: !!outputOptions.sourcemap,
module: outputOptions.format.startsWith('es'),
toplevel: outputOptions.format === 'cjs'
})
return {
code: res.code!,
map: res.map as any
}
},
closeBundle() {
worker?.stop()
}
}
}