Repository: vitejs/vite
File: packages/vite/src/node/plugins/terser.ts (TypeScript)

Code before:
      )
    } else {
      const message = new Error(`terser failed to load:\n${e.message}`)
      message.stack = e.stack + '\n' + message.stack
      throw message
    }
  }
  return terserPath
}

export function terserPlugin(config: ResolvedConfig): Plugin {
  const { maxWorkers, ...terserOptions } = config.build.terserOptions

  const makeWorker = () =>
    new WorkerWithFallback(
      () =>
        async (
          terserPath: string,
          code: string,
          options: TerserMinifyOptions,
        ) => {
          try {
            // test fails when using `import`. maybe related: https://github.com/nodejs/node/issues/43205
            // eslint-disable-next-line no-restricted-globals -- this function runs inside cjs
            const terser = require(terserPath)
            return (await terser.minify(code, options)) as TerserMinifyOutput
          } catch (e) {
            // convert to a plain object as additional properties of Error instances are not
            // sent back to the main thread
            throw { ...e }
          }
        },
      {
        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,
      },
    )

  let worker: ReturnType<typeof makeWorker>

  return {
    name: 'vite:terser',

Review comment (suggestion):
Adding `await` here changes the function signature from synchronous to asynchronous, but the function is not declared as `async`. This will cause the function to return a Promise instead of the expected synchronous result.

Code after:
        'terser not found. Since Vite v3, terser has become an optional dependency. You need to install it.',
      )
    } else {
      const message = new Error(`terser failed to load:\n${e.message}`)
      message.stack = e.stack + '\n' + message.stack
      throw message
    }
  }
  return terserPath
}

export function terserPlugin(config: ResolvedConfig): Plugin {
  const { maxWorkers, ...terserOptions } = config.build.terserOptions

  const makeWorker = () =>
    new WorkerWithFallback(
      () =>
        async (
          terserPath: string,
          code: string,
          options: TerserMinifyOptions,
        ) => {
          const terser: typeof import('terser') = (await import(terserPath))
            .default
          try {
            return (await terser.minify(code, options)) as TerserMinifyOutput
          } catch (e) {
            // convert to a plain object as additional properties of Error instances are not
            // sent back to the main thread
            throw { stack: e.stack /* stack is non-enumerable */, ...e }
          }
        },
      {
        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,
      },
    )

  let worker: ReturnType<typeof makeWorker>

  return {
    name: 'vite:terser',