Rollup предоставляет возможность собирать один и тот же исходный код сразу в несколько форматов вывода. Это ключевая особенность, позволяющая одной сборкой обслуживать разные среды выполнения: браузер, Node.js, bundler-экосистемы и legacy-системы модульности. Поддержка параллельного формирования bundle делает Rollup удобным инструментом для библиотек, которые должны распространяться в универсальном виде.
Архитектура Rollup разделяет процесс сборки на два логических этапа:
На этапе output конфигурация может содержать как один объект, так и массив объектов. Именно массив и является основным механизмом одновременного вывода в несколько форматов.
Каждый элемент массива описывает независимый bundle с собственными параметрами:
Ключевая возможность заключается в том, что input остаётся единым, а output становится множественным:
export default {
input: 'src/index.js',
output: [
{
file: 'dist/bundle.esm.js',
format: 'es'
},
{
file: 'dist/bundle.cjs.js',
format: 'cjs'
},
{
file: 'dist/bundle.umd.js',
format: 'umd',
name: 'MyLibrary'
}
]
};
В этой конфигурации один граф модулей компилируется трижды в разные форматы без повторного запуска анализа исходников. Это важный момент: Rollup переиспользует построенный dependency graph, что снижает стоимость мульти-вывода.
При использовании массива output Rollup выполняет следующие шаги:
Важно, что этап анализа происходит один раз, а генерация повторяется для каждого output-объекта.
Это даёт несколько преимуществ:
Каждый формат предъявляет собственные требования к конфигурации.
{
file: 'dist/index.esm.js',
format: 'es'
}
Особенности:
{
file: 'dist/index.cjs.js',
format: 'cjs'
}
Особенности:
{
file: 'dist/index.umd.js',
format: 'umd',
name: 'MyLibrary'
}
Особенности:
Одновременный вывод часто используется для разделения целевых сред:
export default {
input: 'src/index.js',
output: [
{
file: 'dist/browser.esm.js',
format: 'es'
},
{
file: 'dist/node.cjs.js',
format: 'cjs',
external: ['fs', 'path']
}
]
};
В таком подходе один и тот же код адаптируется под разные runtime-ограничения.
Rollup позволяет задавать отдельные plugin pipelines для каждого output-конфига. Это критически важно для случаев, когда:
Пример:
import terser from '@rollup/plugin-terser';
export default {
input: 'src/index.js',
output: [
{
file: 'dist/lib.esm.js',
format: 'es'
},
{
file: 'dist/lib.umd.min.js',
format: 'umd',
name: 'Lib',
plugins: [terser()]
}
]
};
Здесь ES-модуль остаётся читаемым, а UMD версия дополнительно минифицируется.
Sourcemap может быть настроен отдельно для каждого формата:
output: [
{
file: 'dist/a.esm.js',
format: 'es',
sourcemap: true
},
{
file: 'dist/a.cjs.js',
format: 'cjs',
sourcemap: false
}
]
Такой подход часто применяется для:
При выводе в UMD или IIFE формат обязательно используется параметр name:
{
file: 'dist/lib.umd.js',
format: 'umd',
name: 'LibCore'
}
При мульти-выводе важно соблюдать консистентность имен, иначе возникают коллизии в глобальном пространстве:
При сложных сборках используется dir, позволяющий формировать несколько файлов (chunks) для каждого формата:
output: [
{
dir: 'dist/esm',
format: 'es'
},
{
dir: 'dist/cjs',
format: 'cjs'
}
]
Это особенно важно при code splitting, когда Rollup создаёт несколько файлов вместо одного bundle.
Если используется динамический import или manualChunks, структура output усложняется:
Пример:
output: [
{
dir: 'dist/es',
format: 'es',
manualChunks: {
vendor: ['lodash']
}
},
{
dir: 'dist/cjs',
format: 'cjs'
}
]
Rollup повторяет разбиение графа для каждого output, но использует уже построенную модель зависимостей.
Несмотря на гибкость, существуют важные ограничения:
Особенно критичен момент с external:
external: ['react']
Если external задан в input-level конфигурации, он применяется ко всем output.
На практике мульти-вывод применяется в нескольких устойчивых схемах.
Хотя Rollup переиспользует граф модулей, время сборки увеличивается линейно от количества output-конфигураций.
Факторы влияния:
Оптимизация обычно достигается через:
При росте проекта конфигурация часто переходит от простого массива к структурированному подходу:
Это позволяет контролировать сложные мульти-таргетные сборки без дублирования логики конфигурации.
Плагины могут вести себя по-разному в зависимости от стадии:
Это создаёт важный принцип: генерация артефактов является output-специфичной, а анализ — глобальным.
Некоторые плагины используют это для:
Механизм одновременного вывода в несколько форматов в Rollup основан на разделении ответственности между общим графом модулей и независимыми этапами генерации. Это позволяет строить универсальные библиотеки, адаптированные к разным runtime-средам, без дублирования исходного кода и без повторного анализа зависимостей.