С ростом масштабов JavaScript-приложений возникла проблема организации зависимостей, оптимизации кода и подготовки проекта к публикации. Современные приложения состоят из десятков, сотен и даже тысяч модулей. Браузер не способен эффективно загружать такое количество файлов по отдельности, особенно если код написан с использованием модульной системы ES Modules, CommonJS или сторонних библиотек.
Rollup решает эту проблему за счёт сборки проекта в оптимизированные пакеты. Он анализирует структуру импортов, объединяет зависимости, удаляет неиспользуемый код и генерирует итоговые файлы, пригодные для использования в браузере, Node.js или публикации библиотек.
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>
Такой подход вызывал множество проблем:
Появление CommonJS и ES Modules частично решило проблему организации кода, однако браузеры долгое время не поддерживали модули полноценно. Возникла необходимость в инструментах, которые могли бы:
Так появились Webpack, Parcel, Browserify и Rollup.
Главная особенность Rollup — работа с графом зависимостей.
Когда Rollup запускает сборку, он:
import.Пример:
// 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 будут удалены.
Одной из ключевых причин популярности Rollup стал механизм Tree Shaking.
Tree Shaking — это удаление неиспользуемого кода из итоговой сборки.
Название связано с аналогией встряхивания дерева, при котором опадают ненужные листья.
Rollup анализирует:
После этого весь неиспользуемый код исключается.
Исходный файл:
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 создавался с ориентацией на библиотеки, а не на крупные SPA-приложения.
Его преимущества в библиотечной разработке:
Поэтому Rollup широко используется для создания:
Многие известные библиотеки собираются именно через Rollup.
Rollup умеет генерировать сборки в различных форматах.
Современный стандарт JavaScript-модулей.
export function hello() {}
Используется в:
Формат Node.js.
module.exports = {};
Применяется в:
Universal Module Definition — универсальный формат.
Подходит для:
Часто используется для CDN-сборок.
Immediately Invoked Function Expression.
Создаёт глобальную переменную:
(function () {
// code
})();
Полезен для подключения через обычный
<script>.
Rollup состоит из нескольких основных частей.
Ядро системы, отвечающее за:
Плагины расширяют возможности Rollup.
Без плагинов Rollup работает только с ES Modules и JavaScript.
Плагины позволяют:
Поведение сборщика описывается в файле:
rollup.config.js
Именно там указываются:
Пример базовой конфигурации:
export default {
input: 'src/main.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
}
};
Процесс можно условно разделить на этапы.
Rollup начинает анализ с файла:
input: 'src/main.js'
Rollup рекурсивно анализирует все импорты:
import x from './module.js';
Определяются:
Удаляется лишний код.
Создаётся итоговый файл.
Tree Shaking работает не всегда идеально.
Например:
console.log('hello');
Такой код нельзя удалить автоматически, потому что он имеет побочный эффект.
К side effects относятся:
Rollup старается сохранять код, который потенциально влияет на поведение программы.
Хотя оба инструмента являются бандлерами, их философия различается.
Сильные стороны:
Сильные стороны:
Современный инструмент Vite использует Rollup внутри production-сборки.
Во время разработки Vite работает через native ES Modules и dev server, а при создании production build передаёт проект Rollup.
Поэтому понимание Rollup помогает лучше понимать внутреннюю архитектуру Vite.
Rollup использует стратегию scope hoisting.
Вместо создания большого количества обёрток вокруг модулей Rollup объединяет код в единое пространство видимости.
Другие бандлеры часто генерируют:
(function(module) {
// module code
})();
Rollup старается избегать лишних функций-обёрток.
Результат:
Rollup поддерживает:
import('./module.js');
Это позволяет:
При использовании динамических импортов Rollup может создавать несколько файлов:
dist/
├── main.js
├── vendor.js
└── chunk-XYZ.js
Такой подход:
Rollup позволяет исключать библиотеки из bundle.
Пример:
export default {
external: ['react']
};
В этом случае React не попадёт в итоговую сборку.
Это особенно важно для библиотек, чтобы:
Изначально Rollup ориентирован на ES Modules.
Однако большая часть npm-экосистемы долгое время использовала CommonJS:
const lib = require('lib');
Для поддержки CommonJS используется специальный плагин.
Он преобразует:
module.exports
require()
в ES Modules.
Rollup поддерживает TypeScript через плагины.
Типичный процесс:
.d.ts файлы;Поэтому Rollup часто применяется в TypeScript-библиотеках.
Rollup может использовать Babel для:
Rollup особенно популярен среди авторов npm-библиотек.
Типичная схема:
src/
dist/
package.json
rollup.config.js
Сборка генерирует:
dist/
├── index.esm.js
├── index.cjs.js
└── index.umd.js
Это позволяет одной библиотеке поддерживать сразу несколько сред выполнения.
Rollup считается одним из лучших инструментов по удалению неиспользуемого кода.
Bundle получается компактным и читаемым.
Rollup фактически стал стандартом для публикации JavaScript-библиотек.
Конфигурация Rollup обычно проще, чем у Webpack.
Rollup изначально проектировался вокруг ES Modules.
Webpack традиционно лучше подходит для крупных SPA с большим количеством нестандартных ресурсов.
Для полноценной работы почти всегда нужны плагины.
Rollup intentionally минималистичен.
Наиболее распространённый сценарий.
Например:
Rollup хорошо подходит для генерации лёгких SDK.
Особенно там, где важен минимальный размер итогового JavaScript.
Rollup особенно эффективен, если требуется:
Вместо Rollup часто используют: