Rollup как библиотека предоставляет не только CLI-инструмент, но и полноценный программный API, позволяющий интегрировать процесс сборки непосредственно в пользовательские скрипты. Такой подход используется в сложных сборочных системах, monorepo-конфигурациях, кастомных пайплайнах и CI-процессах, где требуется тонкий контроль над этапами трансформации модулей, генерацией бандлов и обработкой выходных артефактов.
Ключевым элементом программной интеграции выступает функция
rollup, возвращающая объект сборки, через который
выполняются генерация и запись бандлов.
Минимальный сценарий использования Rollup в Node.js-скрипте строится вокруг двух этапов: создание бандла и его генерация или запись на диск.
import { rollup } from 'rollup';
const inputOptions = {
input: 'src/index.js'
};
const outputOptions = {
file: 'dist/bundle.js',
format: 'esm'
};
async function build() {
const bundle = await rollup(inputOptions);
await bundle.write(outputOptions);
await bundle.close();
}
build();
В этой модели:
inputOptions описывает входную точку и плагиныoutputOptions определяет формат и место выводаbundle.write() выполняет полную генерацию и записьbundle.close() освобождает ресурсы (watcher, файловые
дескрипторы)Такой подход является базой для любого расширенного сценария сборки.
Rollup предоставляет два ключевых метода для вывода:
bundle.generate() — возвращает результат в памятиbundle.write() — записывает результат на дискИспользование generate() позволяет внедрять
дополнительные шаги обработки, например анализ кода или передачу
результата в другой инструмент.
const bundle = await rollup(inputOptions);
const result = await bundle.generate(outputOptions);
for (const chunk of result.output) {
console.log(chunk.code);
}
Такой подход полезен при построении кастомных пайплайнов, где Rollup выступает лишь одним из этапов трансформации.
inputOptions определяет поведение компиляции и является
центральным объектом управления сборкой.
Основные поля:
input — точка входа или массив точек входаplugins — цепочка плагинов трансформацииexternal — зависимости, исключаемые из бандлаonwarn — обработчик предупрежденийПример расширенной конфигурации:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
const inputOptions = {
input: ['src/main.js'],
external: ['fs', 'path'],
plugins: [
resolve(),
commonjs()
],
onwarn(warning, warn) {
if (warning.code === 'CIRCULAR_DEPENDENCY') return;
warn(warning);
}
};
Встраивание логики onwarn в скрипты сборки позволяет
централизованно управлять качеством бандла и фильтровать шумные
предупреждения.
outputOptions описывает форматирование результата. При
программной сборке часто используется динамическое формирование
параметров.
Основные поля:
file или dir — путь выводаformat — формат модуля (esm,
cjs, iife, umd)sourcemap — генерация source mapname — глобальное имя для IIFE/UMDglobals — маппинг внешних зависимостейПример динамического формирования:
const outputOptions = {
file: process.env.BUILD_TARGET === 'prod'
? 'dist/app.min.js'
: 'dist/app.js',
format: 'esm',
sourcemap: true
};
Такой подход позволяет связывать Rollup с переменными окружения и системами CI/CD без изменения самой конфигурации.
Встраивание Rollup в скрипты сборки позволяет объединять несколько этапов:
Пример последовательного пайплайна:
import { rollup } from 'rollup';
async function buildAll() {
const bundle = await rollup(inputOptions);
await bundle.write({
file: 'dist/app.esm.js',
format: 'esm'
});
await bundle.write({
file: 'dist/app.cjs.js',
format: 'cjs'
});
await bundle.write({
file: 'dist/app.iife.js',
format: 'iife',
name: 'MyApp'
});
await bundle.close();
}
buildAll();
Один и тот же объект bundle позволяет генерировать
несколько представлений без повторного анализа графа зависимостей, что
существенно снижает время сборки.
Программный API включает watch, позволяющий отслеживать
изменения файлов и автоматически пересобирать проект.
import { watch } from 'rollup';
const watcher = watch({
...inputOptions,
output: [outputOptions]
});
watcher.on('event', event => {
if (event.code === 'START') {
console.log('Сборка запущена');
}
if (event.code === 'BUNDLE_END') {
console.log('Сборка завершена:', event.duration);
}
if (event.code === 'ERROR') {
console.error(event.error);
}
});
Watch-режим особенно важен в разработческих скриптах, где требуется мгновенная пересборка без перезапуска процесса Node.js.
Встроенный API позволяет использовать Rollup как модуль внутри более крупных систем:
Пример кастомного runner-а:
export async function buildProject(config) {
const bundle = await rollup({
input: config.entry,
plugins: config.plugins
});
const outputs = Array.isArray(config.output)
? config.output
: [config.output];
for (const output of outputs) {
await bundle.write(output);
}
await bundle.close();
}
Такой слой абстракции позволяет стандартизировать сборку между разными проектами без привязки к CLI.
При программной интеграции важна явная обработка исключений, поскольку Rollup работает асинхронно и может возвращать ошибки на разных этапах графа модулей.
try {
const bundle = await rollup(inputOptions);
await bundle.write(outputOptions);
await bundle.close();
} catch (error) {
console.error('Ошибка сборки:', error);
process.exit(1);
}
В сложных системах часто добавляется дополнительная классификация ошибок:
Это позволяет отделять критические сбои от предупреждений и реализовывать разные стратегии реакции.
Встроенный API позволяет переиспользовать конфигурации и минимизировать перерасчёт графа зависимостей. В watch-режиме Rollup самостоятельно кэширует модули, но в кастомных сценариях можно управлять этим вручную через архитектуру скрипта.
Часто используется стратегия:
let bundle;
export async function rebuild() {
if (!bundle) {
bundle = await rollup(inputOptions);
}
await bundle.write(outputOptions);
}
Встраивание Rollup в скрипты позволяет строить окружения с различными параметрами сборки без изменения исходного кода проекта.
const isProd = process.env.NODE_ENV === 'production';
const inputOptions = {
input: 'src/index.js',
plugins: []
};
const outputOptions = {
file: isProd ? 'dist/app.min.js' : 'dist/app.js',
format: 'esm',
sourcemap: !isProd
};
В продакшене обычно добавляются плагины минификации, удаления комментариев и оптимизации дерева зависимостей, тогда как в разработке приоритетом остаётся скорость.
Встраивание Rollup в скрипты сборки позволяет легко интегрировать его в CI системы. Обычно создаётся отдельный Node.js-скрипт, который вызывается в пайплайне.
// build.js
import { rollup } from 'rollup';
import config from './rollup.config.js';
const bundle = await rollup(config.input);
await bundle.write(config.output);
await bundle.close();
Такой скрипт становится универсальной точкой входа для всех автоматизированных сборок, независимо от среды исполнения.
Плагины Rollup в скриптах подключаются динамически, что позволяет формировать разные цепочки трансформации в зависимости от условий выполнения.
import babel from '@rollup/plugin-babel';
const plugins = [
resolve(),
commonjs()
];
if (process.env.USE_BABEL) {
plugins.push(babel({ babelHelpers: 'bundled' }));
}
const inputOptions = {
input: 'src/index.js',
plugins
};
Такая динамическая композиция особенно важна в монорепозиториях, где разные пакеты могут требовать разного набора трансформаций.
Каждый вызов rollup() создаёт объект, который должен
быть корректно завершён через close(). Это особенно важно
при длительных процессах, watch-режимах и CI-сборках.
Незакрытые bundle-объекты могут удерживать файловые дескрипторы и приводить к утечкам памяти в долгоживущих процессах.
const bundle = await rollup(inputOptions);
try {
await bundle.write(outputOptions);
} finally {
await bundle.close();
}
Такой шаблон используется в устойчивых сборочных системах, где важна предсказуемость завершения процессов.
Rollup в скриптах сборки часто выступает как часть композиции, где разные этапы разделяются на функции:
async function build() {
const bundle = await rollup(inputOptions);
const { output } = await bundle.generate(outputOptions);
await postProcess(output);
await bundle.write(outputOptions);
await bundle.close();
}
Такой подход позволяет разделить чистую сборку и побочные операции, сохраняя контроль над каждым этапом пайплайна.