Что такое Rollup и зачем он нужен

С ростом масштабов JavaScript-приложений возникла проблема организации зависимостей, оптимизации кода и подготовки проекта к публикации. Современные приложения состоят из десятков, сотен и даже тысяч модулей. Браузер не способен эффективно загружать такое количество файлов по отдельности, особенно если код написан с использованием модульной системы ES Modules, CommonJS или сторонних библиотек.

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


Что представляет собой Rollup

Rollup — это модульный JavaScript-бандлер, ориентированный прежде всего на сборку библиотек и оптимизацию ES-модулей.

Основная задача Rollup заключается в следующем:

  • анализировать зависимости проекта;
  • объединять модули в единый пакет;
  • удалять лишний код;
  • преобразовывать формат модулей;
  • минимизировать итоговый размер сборки.

Rollup появился как инструмент, максимально эффективно работающий с ES Modules. В отличие от ранних бандлеров, которые рассматривали модули как обычные файлы, Rollup понимает структуру импортов и экспортов на уровне синтаксического дерева.

Пример модульного кода:

// math.js
export function sum(a, b) {
    return a + b;
}

export function multiply(a, b) {
    return a * b;
}
// app.js
import { sum } from './math.js';

console.log(sum(2, 3));

Rollup способен определить, что функция multiply() нигде не используется, и исключить её из финальной сборки.


Почему появились бандлеры

До появления модульных сборщиков JavaScript-проекты подключались через множество <script>-тегов:

<script src="utils.js"></script>
<script src="api.js"></script>
<script src="ui.js"></script>
<script src="main.js"></script>

Такой подход вызывал множество проблем:

  • зависимость от порядка подключения;
  • загрязнение глобальной области видимости;
  • конфликты имён;
  • увеличение количества HTTP-запросов;
  • сложность поддержки крупных проектов.

Появление CommonJS и ES Modules частично решило проблему организации кода, однако браузеры долгое время не поддерживали модули полноценно. Возникла необходимость в инструментах, которые могли бы:

  • объединять модули;
  • преобразовывать их в совместимый формат;
  • оптимизировать код;
  • ускорять загрузку приложения.

Так появились Webpack, Parcel, Browserify и Rollup.


Основная идея Rollup

Главная особенность Rollup — работа с графом зависимостей.

Когда Rollup запускает сборку, он:

  1. Находит входной файл.
  2. Анализирует все import.
  3. Строит дерево зависимостей.
  4. Определяет используемые экспорты.
  5. Исключает лишний код.
  6. Генерирует итоговый bundle.

Пример:

// utils.js
export const a = 1;
export const b = 2;
export const c = 3;
// app.js
import { a } from './utils.js';

console.log(a);

В итоговый bundle попадёт только:

const a = 1;

console.log(a);

Переменные b и c будут удалены.


Tree Shaking

Одной из ключевых причин популярности Rollup стал механизм Tree Shaking.

Что такое Tree Shaking

Tree Shaking — это удаление неиспользуемого кода из итоговой сборки.

Название связано с аналогией встряхивания дерева, при котором опадают ненужные листья.

Rollup анализирует:

  • какие функции импортируются;
  • какие переменные используются;
  • какие экспорты реально нужны приложению.

После этого весь неиспользуемый код исключается.


Пример Tree Shaking

Исходный файл:

export function usedFunction() {
    console.log('used');
}

export function unusedFunction() {
    console.log('unused');
}

Импорт:

import { usedFunction } from './functions.js';

usedFunction();

Результат сборки:

function usedFunction() {
    console.log('used');
}

usedFunction();

Функция unusedFunction() полностью исчезнет.


Почему Rollup особенно эффективен для библиотек

Rollup создавался с ориентацией на библиотеки, а не на крупные SPA-приложения.

Его преимущества в библиотечной разработке:

  • компактный output;
  • минимальное количество служебного кода;
  • качественный Tree Shaking;
  • поддержка разных форматов модулей;
  • чистый итоговый bundle.

Поэтому Rollup широко используется для создания:

  • npm-пакетов;
  • UI-библиотек;
  • утилит;
  • SDK;
  • framework-плагинов.

Многие известные библиотеки собираются именно через Rollup.


Форматы модулей

Rollup умеет генерировать сборки в различных форматах.

ES Modules (esm)

Современный стандарт JavaScript-модулей.

export function hello() {}

Используется в:

  • современных браузерах;
  • Vite;
  • современных Node.js-проектах.

CommonJS (cjs)

Формат Node.js.

module.exports = {};

Применяется в:

  • старых Node.js-проектах;
  • npm-экосистеме;
  • legacy-средах.

UMD

Universal Module Definition — универсальный формат.

Подходит для:

  • браузеров;
  • AMD;
  • CommonJS.

Часто используется для CDN-сборок.


IIFE

Immediately Invoked Function Expression.

Создаёт глобальную переменную:

(function () {
    // code
})();

Полезен для подключения через обычный <script>.


Архитектура Rollup

Rollup состоит из нескольких основных частей.

Core

Ядро системы, отвечающее за:

  • анализ модулей;
  • построение dependency graph;
  • генерацию bundle.

Plugins

Плагины расширяют возможности Rollup.

Без плагинов Rollup работает только с ES Modules и JavaScript.

Плагины позволяют:

  • обрабатывать TypeScript;
  • компилировать Babel;
  • подключать JSON;
  • импортировать CSS;
  • минимизировать код;
  • работать с CommonJS.

Конфигурация

Поведение сборщика описывается в файле:

rollup.config.js

Именно там указываются:

  • входные файлы;
  • output;
  • плагины;
  • режимы сборки;
  • external dependencies.

Минимальная конфигурация

Пример базовой конфигурации:

export default {
    input: 'src/main.js',

    output: {
        file: 'dist/bundle.js',
        format: 'esm'
    }
};

Как работает процесс сборки

Процесс можно условно разделить на этапы.

1. Поиск entry point

Rollup начинает анализ с файла:

input: 'src/main.js'

2. Построение графа зависимостей

Rollup рекурсивно анализирует все импорты:

import x from './module.js';

3. Анализ экспортов

Определяются:

  • используемые функции;
  • неиспользуемые переменные;
  • side effects.

4. Tree Shaking

Удаляется лишний код.


5. Генерация bundle

Создаётся итоговый файл.


Side Effects

Tree Shaking работает не всегда идеально.

Например:

console.log('hello');

Такой код нельзя удалить автоматически, потому что он имеет побочный эффект.

К side effects относятся:

  • console.log;
  • изменение глобальных объектов;
  • DOM-операции;
  • сетевые запросы;
  • таймеры;
  • мутации состояния.

Rollup старается сохранять код, который потенциально влияет на поведение программы.


Отличие Rollup от Webpack

Хотя оба инструмента являются бандлерами, их философия различается.

Rollup

Сильные стороны:

  • библиотечная разработка;
  • чистый output;
  • эффективный Tree Shaking;
  • простота конфигурации;
  • компактные bundle.

Webpack

Сильные стороны:

  • сложные SPA;
  • обработка большого количества ресурсов;
  • мощная экосистема;
  • гибкость;
  • code splitting.

Rollup и Vite

Современный инструмент Vite использует Rollup внутри production-сборки.

Во время разработки Vite работает через native ES Modules и dev server, а при создании production build передаёт проект Rollup.

Поэтому понимание Rollup помогает лучше понимать внутреннюю архитектуру Vite.


Почему Rollup генерирует компактные bundle

Rollup использует стратегию scope hoisting.

Scope Hoisting

Вместо создания большого количества обёрток вокруг модулей Rollup объединяет код в единое пространство видимости.

Другие бандлеры часто генерируют:

(function(module) {
    // module code
})();

Rollup старается избегать лишних функций-обёрток.

Результат:

  • меньше размер bundle;
  • быстрее выполнение;
  • более читаемый output.

Поддержка динамических импортов

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

import('./module.js');

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

  • разделять код;
  • загружать части приложения по требованию;
  • уменьшать initial bundle size.

Code Splitting

При использовании динамических импортов Rollup может создавать несколько файлов:

dist/
├── main.js
├── vendor.js
└── chunk-XYZ.js

Такой подход:

  • ускоряет первую загрузку;
  • уменьшает объём initial JS;
  • позволяет кэшировать зависимости.

External Dependencies

Rollup позволяет исключать библиотеки из bundle.

Пример:

export default {
    external: ['react']
};

В этом случае React не попадёт в итоговую сборку.

Это особенно важно для библиотек, чтобы:

  • не дублировать зависимости;
  • уменьшать размер пакета;
  • избегать конфликтов версий.

Работа с CommonJS

Изначально Rollup ориентирован на ES Modules.

Однако большая часть npm-экосистемы долгое время использовала CommonJS:

const lib = require('lib');

Для поддержки CommonJS используется специальный плагин.

Он преобразует:

module.exports
require()

в ES Modules.


Работа с TypeScript

Rollup поддерживает TypeScript через плагины.

Типичный процесс:

  1. TypeScript компилируется;
  2. Rollup собирает итоговый bundle;
  3. генерируются .d.ts файлы;
  4. выполняется оптимизация.

Поэтому Rollup часто применяется в TypeScript-библиотеках.


Работа с Babel

Rollup может использовать Babel для:

  • транспиляции;
  • поддержки старых браузеров;
  • полифиллов;
  • преобразования современного синтаксиса.

Rollup в экосистеме npm

Rollup особенно популярен среди авторов npm-библиотек.

Типичная схема:

src/
dist/
package.json
rollup.config.js

Сборка генерирует:

dist/
├── index.esm.js
├── index.cjs.js
└── index.umd.js

Это позволяет одной библиотеке поддерживать сразу несколько сред выполнения.


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

Высокое качество Tree Shaking

Rollup считается одним из лучших инструментов по удалению неиспользуемого кода.


Чистый output

Bundle получается компактным и читаемым.


Отличная работа с библиотеками

Rollup фактически стал стандартом для публикации JavaScript-библиотек.


Простая архитектура

Конфигурация Rollup обычно проще, чем у Webpack.


Поддержка современных стандартов

Rollup изначально проектировался вокруг ES Modules.


Недостатки Rollup

Менее удобен для сложных приложений

Webpack традиционно лучше подходит для крупных SPA с большим количеством нестандартных ресурсов.


Сильная зависимость от плагинов

Для полноценной работы почти всегда нужны плагины.


Ограниченная встроенная функциональность

Rollup intentionally минималистичен.


Типичные сценарии использования

Сборка npm-библиотек

Наиболее распространённый сценарий.


Сборка UI-компонентов

Например:

  • React component libraries;
  • Vue libraries;
  • Web Components.

Сборка SDK

Rollup хорошо подходит для генерации лёгких SDK.


Компактные frontend-пакеты

Особенно там, где важен минимальный размер итогового JavaScript.


Когда Rollup подходит лучше всего

Rollup особенно эффективен, если требуется:

  • минимальный размер bundle;
  • публикация библиотеки;
  • качественный Tree Shaking;
  • поддержка ESM;
  • генерация нескольких форматов сборки;
  • чистый production output.

Когда выбирают другие инструменты

Вместо Rollup часто используют:

  • Webpack — для сложных enterprise-приложений;
  • Parcel — для быстрого старта без конфигурации;
  • esbuild — для сверхбыстрой сборки;
  • Rspack — для ускорения Webpack-экосистемы;
  • Vite — для современной frontend-разработки с быстрым dev server.