|
1 |
| -import { dirname } from 'path' |
2 |
| -import { fileURLToPath } from 'url' |
3 | 1 | import { Worker } from 'okie'
|
4 | 2 | import type { Terser } from 'types/terser'
|
5 | 3 | import type { Plugin } from '../plugin'
|
6 | 4 | import type { ResolvedConfig } from '..'
|
| 5 | +import { requireResolveFromRootWithFallback } from '../utils' |
7 | 6 |
|
8 |
| -// TODO: use import() |
9 |
| -const _dirname = dirname(fileURLToPath(import.meta.url)) |
| 7 | +let terserPath: string | undefined |
| 8 | +const loadTerserPath = (root: string) => { |
| 9 | + if (terserPath) return terserPath |
| 10 | + try { |
| 11 | + terserPath = requireResolveFromRootWithFallback(root, 'terser') |
| 12 | + } catch (e) { |
| 13 | + if (e.code === 'MODULE_NOT_FOUND') { |
| 14 | + throw new Error( |
| 15 | + 'terser not found. Since Vite v3, terser has become an optional dependency. You need to install it.' |
| 16 | + ) |
| 17 | + } else { |
| 18 | + const message = new Error(`terser failed to load:\n${e.message}`) |
| 19 | + message.stack = e.stack + '\n' + message.stack |
| 20 | + throw message |
| 21 | + } |
| 22 | + } |
| 23 | + return terserPath |
| 24 | +} |
10 | 25 |
|
11 | 26 | export function terserPlugin(config: ResolvedConfig): Plugin {
|
12 | 27 | const makeWorker = () =>
|
13 | 28 | new Worker(
|
14 |
| - async (basedir: string, code: string, options: Terser.MinifyOptions) => { |
15 |
| - // when vite is linked, the worker thread won't share the same resolve |
16 |
| - // root with vite itself, so we have to pass in the basedir and resolve |
17 |
| - // terser first. |
18 |
| - // eslint-disable-next-line node/no-restricted-require, no-restricted-globals |
19 |
| - const terserPath = require.resolve('terser', { |
20 |
| - paths: [basedir] |
21 |
| - }) |
22 |
| - // eslint-disable-next-line no-restricted-globals |
23 |
| - return require(terserPath).minify(code, options) as Terser.MinifyOutput |
| 29 | + async ( |
| 30 | + terserPath: string, |
| 31 | + code: string, |
| 32 | + options: Terser.MinifyOptions |
| 33 | + ) => { |
| 34 | + // test fails when using `import`. maybe related: https://github.com/nodejs/node/issues/43205 |
| 35 | + // eslint-disable-next-line no-restricted-globals -- this function runs inside cjs |
| 36 | + const terser = require(terserPath) |
| 37 | + return terser.minify(code, options) as Terser.MinifyOutput |
24 | 38 | }
|
25 | 39 | )
|
26 | 40 |
|
@@ -50,7 +64,8 @@ export function terserPlugin(config: ResolvedConfig): Plugin {
|
50 | 64 | // Lazy load worker.
|
51 | 65 | worker ||= makeWorker()
|
52 | 66 |
|
53 |
| - const res = await worker.run(_dirname, code, { |
| 67 | + const terserPath = loadTerserPath(config.root) |
| 68 | + const res = await worker.run(terserPath, code, { |
54 | 69 | safari10: true,
|
55 | 70 | ...config.build.terserOptions,
|
56 | 71 | sourceMap: !!outputOptions.sourcemap,
|
|
0 commit comments