Настройка minify: esbuild, terser, false

Опция build.minify управляет минификацией итогового production-бандла в Vite. Минификация уменьшает размер JavaScript-кода, удаляет лишние пробелы, комментарии, сокращает имена локальных переменных и делает выходные файлы компактнее.

Настройка располагается внутри секции build:

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: 'esbuild'
  }
})

Поддерживаются три основных значения:

minify: 'esbuild'
minify: 'terser'
minify: false

Каждый вариант имеет собственные особенности производительности, совместимости и качества сжатия.


Значение minify: 'esbuild'

Общая характеристика

esbuild — минификатор по умолчанию в Vite. Он обеспечивает очень высокую скорость сборки и хорошее качество сжатия.

Пример:

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: 'esbuild'
  }
})

Эквивалентная запись:

build: {
  minify: true
}

По умолчанию Vite автоматически использует esbuild.


Преимущества esbuild

Высокая скорость

Главное преимущество — производительность.

Даже крупные проекты собираются значительно быстрее по сравнению с terser.

Особенно заметна разница:

  • в больших SPA
  • в монорепозиториях
  • при CI/CD-сборках
  • при Docker-сборках
  • в проектах с большим количеством чанков

Низкое потребление ресурсов

esbuild написан на Go и работает крайне эффективно:

  • меньше потребление памяти
  • быстрее cold start
  • меньше нагрузка на CPU

Встроенная интеграция в Vite

Vite глубоко интегрирован с esbuild:

  • transpilation
  • transform
  • dependency pre-bundling
  • minification

Это уменьшает количество внешних зависимостей.


Что делает esbuild при минификации

Во время production-сборки:

function sum(a, b) {
  return a + b
}

console.log(sum(10, 20))

превращается в:

function o(n,r){return n+r}console.log(o(10,20));

Удаляются:

  • переносы строк
  • лишние пробелы
  • комментарии
  • неиспользуемые конструкции
  • длинные имена локальных переменных

Ограничения esbuild

Несмотря на скорость, esbuild уступает terser по глубине оптимизации.

Иногда итоговый bundle:

  • немного больше по размеру
  • менее агрессивно оптимизирован
  • содержит менее эффективный dead code elimination

Отсутствие тонкой настройки

У esbuild нет такого количества параметров минификации, как у terser.

Например, нельзя гибко настраивать:

  • compress
  • mangle
  • keep_classnames
  • keep_fnames
  • passes
  • pure_funcs

Когда выбирать esbuild

esbuild подходит в большинстве случаев:

  • стандартные SPA
  • React/Vue/Svelte-проекты
  • административные панели
  • корпоративные приложения
  • SSR
  • большие CI/CD pipelines

Чаще всего именно этот вариант используется в production.


Значение minify: 'terser'

Подключение terser

terser не входит в Vite автоматически. Его необходимо установить отдельно.

npm install terser -D

После этого можно включить минификацию:

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: 'terser'
  }
})

Особенности terser

terser — классический JavaScript-минификатор, используемый во многих bundler’ах:

  • Webpack
  • Rollup
  • Parcel
  • старые production pipelines

Он медленнее esbuild, но обеспечивает более агрессивное сжатие.


Более компактный bundle

В крупных проектах terser иногда уменьшает размер итогового файла на несколько процентов сильнее.

Особенно это заметно:

  • при сложной бизнес-логике
  • при большом количестве utility-функций
  • в legacy-коде
  • в проектах с длинными именами функций

Гибкая настройка

Главное преимущество terser — огромное количество опций.

Пример:

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      },
      mangle: true
    }
  }
})

terserOptions

Удаление console.log

terserOptions: {
  compress: {
    drop_console: true
  }
}

Исходный код:

console.log('debug')

После сборки:

// код удалён

Удаление debugger

terserOptions: {
  compress: {
    drop_debugger: true
  }
}

Исходный код:

debugger

После сборки:

// код удалён

Сохранение имён функций

Иногда framework или библиотека завязаны на имя функции.

Тогда используется:

terserOptions: {
  keep_fnames: true
}

Сохранение имён классов

terserOptions: {
  keep_classnames: true
}

Полезно:

  • при reflection
  • в DI-контейнерах
  • в некоторых ORM
  • в serialization logic

Несколько проходов оптимизации

terserOptions: {
  compress: {
    passes: 3
  }
}

Чем больше passes, тем агрессивнее оптимизация, но тем медленнее сборка.


Удаление pure-функций

terserOptions: {
  compress: {
    pure_funcs: ['console.log']
  }
}

Позволяет удалять вызовы функций, считающихся не влияющими на результат выполнения.


Когда выбирать terser

terser оправдан:

  • при критичном размере bundle
  • в performance-sensitive проектах
  • в CDN-first архитектуре
  • для библиотек
  • в legacy production pipelines
  • если нужна тонкая настройка минификации

Недостатки terser

Медленная сборка

Основная проблема — скорость.

В крупных проектах разница может быть очень заметной:

  • esbuild — секунды
  • terser — десятки секунд

Повышенное потребление памяти

terser значительно тяжелее:

  • больше RAM
  • выше нагрузка на CPU
  • медленнее CI

Дополнительная зависимость

Необходимо вручную устанавливать пакет:

npm install terser -D

Значение minify: false

Полное отключение минификации

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    minify: false
  }
})

В этом режиме Vite не минимизирует итоговый код.


Как выглядит результат

Исходный код:

function calculatePrice(price, tax) {
  return price + tax
}

console.log(calculatePrice(100, 20))

После build:

function calculatePrice(price, tax) {
  return price + tax;
}

console.log(calculatePrice(100, 20));

Код остаётся читаемым.


Когда отключают минификацию

Анализ production-кода

Иногда требуется:

  • читать итоговый bundle
  • искать ошибки
  • анализировать tree shaking
  • проверять output Rollup

Отладка production-сборки

Без минификации:

  • легче искать stack traces
  • проще читать sourcemaps
  • понятнее структура output

Разработка библиотек

Иногда библиотеки публикуют:

  • minified build
  • non-minified build

Пример структуры:

dist/
  library.js
  library.min.js

Минусы отключения минификации

Большой размер файлов

Bundle может увеличиться в несколько раз.


Более медленная загрузка

Увеличивается:

  • время скачивания
  • parse time
  • execution time

Хуже кеширование CDN

Большие файлы менее эффективны для distributed delivery.


Сравнение esbuild, terser и false

Параметр esbuild terser false
Скорость Очень высокая Низкая Максимальная
Размер bundle Хороший Лучший Очень большой
Настраиваемость Минимальная Очень высокая Нет
Потребление RAM Низкое Высокое Низкое
Подходит для production Да Да Обычно нет
Удаление console.log Нет Да Нет
Дополнительная установка Нет Да Нет

Использование sourcemap вместе с minify

Минификация часто комбинируется с sourcemaps:

export default defineConfig({
  build: {
    minify: 'esbuild',
    sourcemap: true
  }
})

Это позволяет:

  • видеть оригинальный код в DevTools
  • нормально читать stack traces
  • анализировать production errors

Комбинация terser и sourcemap

export default defineConfig({
  build: {
    minify: 'terser',
    sourcemap: true,
    terserOptions: {
      compress: {
        drop_console: true
      }
    }
  }
})

Типичная production-конфигурация.


Минификация CSS

build.minify влияет не только на JavaScript, но и на CSS.

Пример:

.container {
  padding: 20px;
  margin: 10px;
}

После минификации:

.container{padding:20px;margin:10px}

Влияние на tree shaking

Минификация тесно связана с tree shaking.

После удаления неиспользуемого кода минификатор дополнительно:

  • объединяет выражения
  • удаляет пустые конструкции
  • сокращает объявления

Production-конфигурация для большинства проектов

Быстрая сборка

export default defineConfig({
  build: {
    minify: 'esbuild'
  }
})

Максимальное сжатие

export default defineConfig({
  build: {
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    }
  }
})

Отладочная production-сборка

export default defineConfig({
  build: {
    minify: false,
    sourcemap: true
  }
})

Частые ошибки

Использование terser без установки пакета

Ошибка:

terser not found

Решение:

npm install terser -D

Ожидание удаления console.log через esbuild

esbuild в Vite не предоставляет полноценного аналога:

drop_console: true

Для подобных задач обычно используют terser.


Слишком медленная production-сборка

Причина часто связана с:

minify: 'terser'

Особенно в больших проектах.


Отсутствие sourcemap

Минифицированный код без sourcemap сложно анализировать при production-ошибках.


Практические рекомендации

Для большинства проектов

minify: 'esbuild'

Оптимальный баланс:

  • скорости
  • размера bundle
  • стабильности

Для библиотек и CDN

minify: 'terser'

Позволяет добиться максимального сжатия.


Для анализа output

minify: false

Удобно для:

  • debugging
  • bundle inspection
  • анализа Rollup output
  • проверки tree shaking