@rollup/plugin-terser

Rollup @rollup/plugin-terser представляет собой официальный плагин экосистемы Rollup, предназначенный для минификации итоговых бандлов с использованием Terser. Его задача — уменьшение размера JavaScript-кода за счёт удаления пробелов, сокращения идентификаторов, устранения мёртвого кода и применения различных оптимизаций AST-уровня.

Плагин используется на этапе финальной сборки и обычно подключается только для production-сборок, так как процесс минификации увеличивает время билда.


Rollup сам по себе ориентирован на создание оптимальных ES-модулей и не включает встроенную минификацию. Это принципиальное отличие от некоторых других бандлеров.

Минификация в Rollup решается через плагины, и @rollup/plugin-terser является стандартным решением.

Основные эффекты применения:

  • уменьшение размера JavaScript-файлов
  • ускорение загрузки в браузере
  • снижение сетевого трафика
  • частичная защита кода через обфускацию

Установка

Плагин устанавливается вместе с terser:

npm install -D @rollup/plugin-terser terser

или

yarn add -D @rollup/plugin-terser terser

Важно понимать, что terser является peer dependency и должен быть установлен отдельно.


Базовая конфигурация Rollup

Минимальная интеграция выглядит следующим образом:

import terser from '@rollup/plugin-terser';

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.min.js',
    format: 'esm'
  },
  plugins: [
    terser()
  ]
};

В этом случае Rollup сначала собирает модульный граф, а затем передаёт итоговый код в Terser для минификации.


Условное подключение (production-only)

В реальных проектах минификация применяется только в production:

import terser from '@rollup/plugin-terser';

const isProd = process.env.NODE_ENV === 'production';

export default {
  input: 'src/index.js',
  output: {
    file: isProd ? 'dist/bundle.min.js' : 'dist/bundle.js',
    format: 'esm',
    sourcemap: true
  },
  plugins: [
    isProd && terser()
  ]
};

Rollup игнорирует false-значения в массиве plugins, что делает такой подход стандартной практикой.


Опции @rollup/plugin-terser

Плагин передаёт настройки напрямую в Terser, поэтому большинство параметров совпадает с terser API.

mangle

Управляет переименованием идентификаторов:

terser({
  mangle: {
    toplevel: true
  }
})

toplevel: true позволяет минифицировать имена переменных верхнего уровня.


compress

Основной блок оптимизаций:

terser({
  compress: {
    drop_console: true,
    drop_debugger: true
  }
})

Часто используемые опции:

  • drop_console — удаление console.*
  • drop_debugger — удаление debugger
  • dead_code — удаление недостижимого кода (включено по умолчанию)

format

Настройка вывода:

terser({
  format: {
    comments: false
  }
})

Позволяет:

  • удалять комментарии
  • управлять форматированием результата

sourceMap

Хотя Rollup сам управляет sourcemap, terser может учитывать его:

terser({
  sourceMap: true
})

Использование с несколькими бандлами

Rollup может генерировать несколько выходных файлов:

export default {
  input: {
    main: 'src/main.js',
    admin: 'src/admin.js'
  },
  output: [
    {
      dir: 'dist',
      format: 'esm'
    }
  ],
  plugins: [
    terser()
  ]
};

В этом случае минификация применяется ко всем chunks.


Влияние на производительность сборки

Terser работает через разбор AST, что делает его одним из самых тяжёлых этапов сборки.

Факторы, влияющие на скорость:

  • размер бандла
  • уровень compress/mangle
  • количество входных chunks
  • использование многопоточности (worker_threads внутри terser в некоторых конфигурациях)

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

  • увеличение времени сборки в 2–10 раз
  • заметная нагрузка на CPU

Оптимизация скорости минификации

Отключение агрессивных оптимизаций

terser({
  compress: {
    passes: 1
  }
})

Разделение сборок

Использование отдельных конфигураций:

  • dev build без terser
  • prod build с terser

Кэширование Rollup

Rollup поддерживает cache API:

export default {
  cache: true
};

Хотя напрямую terser не кешируется, повторный анализ графа ускоряет общий процесс.


Совместимость с современным JavaScript

Terser поддерживает:

  • ES6–ES2023 синтаксис
  • стрелочные функции
  • классы
  • optional chaining
  • nullish coalescing

Однако некоторые трансформации могут конфликтовать с нестандартными плагинами трансформации AST.


Типичные проблемы

Потеря имён функций

При включённом mangle stack traces могут становиться менее читаемыми:

terser({
  mangle: {
    keep_fnames: true
  }
})

Ломание кода при side effects

Если код зависит от побочных эффектов импортов, aggressive compression может удалить нужные части:

terser({
  compress: {
    side_effects: true
  }
})

Несовместимость с eval

Код с eval и динамическими конструкциями может быть частично оптимизирован некорректно. В таких случаях используют:

terser({
  compress: {
    evaluate: false
  }
})

Tree-shaking vs минификация

Важно различать два этапа:

  • Tree-shaking выполняется Rollup на этапе сборки графа модулей
  • Terser работает уже с итоговым JS-кодом

Tree-shaking удаляет неиспользуемый код на уровне модулей, тогда как terser оптимизирует синтаксис внутри уже собранного кода.


Использование в библиотечных сборках

При публикации библиотек минификация часто отключается:

  • упрощает дебаг
  • сохраняет читаемость
  • позволяет пользователю самостоятельно минифицировать код

Но в CDN-сборках terser применяется всегда.


Режимы работы terser

Основные режимы:

  • parse — разбор кода в AST
  • compress — оптимизация дерева
  • mangle — переименование идентификаторов
  • output format — генерация финального кода

@rollup/plugin-terser управляет всей цепочкой автоматически, предоставляя единый интерфейс в Rollup-плагине.


Пример продвинутой конфигурации

import terser from '@rollup/plugin-terser';

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/app.min.js',
    format: 'iife',
    sourcemap: true
  },
  plugins: [
    terser({
      compress: {
        passes: 2,
        drop_console: true
      },
      mangle: {
        toplevel: true,
        keep_fnames: false
      },
      format: {
        comments: false
      }
    })
  ]
};

Интеграция с CI/CD

В пайплайнах сборки плагин обычно используется в отдельной стадии:

  • установка зависимостей
  • сборка Rollup
  • минификация terser
  • публикация артефактов

Часто применяется параллельная сборка разных target-окружений (ESM/CJS/IIFE).


Взаимодействие с другими плагинами Rollup

Порядок плагинов критичен:

  • трансформационные плагины (Babel, TypeScript)
  • резолвинг модулей
  • commonjs-конверсия
  • terser (в конце цепочки)

Любая попытка поставить terser раньше других плагинов приводит к некорректной работе сборки, так как он ожидает финальный JS-код.