В Rollup конфигурация может быть представлена не только одним объектом, но и массивом объектов. Такой подход используется для одновременной сборки нескольких независимых или частично пересекающихся бандлов в рамках одного процесса. Каждый элемент массива рассматривается как отдельная конфигурация со своим набором входных точек, выходных файлов, плагинов и параметров трансформации.
Механизм множественных конфигураций основан на возможности экспортировать из конфигурационного файла не один объект, а массив:
export default [
{
input: 'src/index.js',
output: {
file: 'dist/bundle.esm.js',
format: 'esm'
}
},
{
input: 'src/index.js',
output: {
file: 'dist/bundle.cjs.js',
format: 'cjs'
}
}
];
Каждый объект в массиве полностью независим и обрабатывается Rollup как отдельный билд. Это означает, что граф зависимостей строится заново для каждой конфигурации, а плагины выполняются отдельно в рамках каждого прохода.
При использовании массива конфигураций важно понимать, что:
Такая изоляция обеспечивает предсказуемость сборки, но может увеличивать время выполнения при большом количестве конфигураций.
Несмотря на изолированность конфигураций, часто возникает необходимость избежать дублирования настроек. Для этого используется вынесение общей части в отдельные структуры:
const baseConfig = {
input: 'src/index.js',
plugins: []
};
export default [
{
...baseConfig,
output: {
file: 'dist/bundle.esm.js',
format: 'esm'
}
},
{
...baseConfig,
output: {
file: 'dist/bundle.cjs.js',
format: 'cjs'
}
}
];
Такой подход позволяет централизовать общие параметры, сохраняя при этом гибкость для каждой сборки.
Массив конфигураций часто формируется программно, что особенно полезно при необходимости собрать несколько пакетов с одинаковой структурой, но разными входными данными:
const formats = ['esm', 'cjs', 'umd'];
export default formats.map((format) => ({
input: 'src/index.js',
output: {
file: `dist/bundle.${format}.js`,
format
}
}));
Динамическая генерация снижает вероятность ошибок при ручном дублировании и упрощает масштабирование сборки.
Rollup поддерживает возможность экспорта функции, возвращающей массив конфигураций. Это позволяет использовать асинхронные операции:
export default async () => {
const env = await loadEnv();
return [
{
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
replace({
__ENV__: JSON.stringify(env)
})
]
}
];
};
Асинхронная конфигурация полезна при интеграции с внешними источниками данных, такими как переменные окружения, API или файловая система.
Множественные конфигурации часто используются для разделения сборок по средам выполнения:
const dev = {
input: 'src/index.js',
output: {
file: 'dist/bundle.dev.js',
format: 'esm',
sourcemap: true
}
};
const prod = {
input: 'src/index.js',
output: {
file: 'dist/bundle.prod.js',
format: 'esm',
sourcemap: false
}
};
export default [dev, prod];
Такое разделение позволяет формировать разные артефакты без усложнения внутренней логики сборки.
При множественных конфигурациях важно учитывать, что экземпляры плагинов не разделяются между сборками. Это особенно критично для плагинов с внутренним состоянием:
import resolve from '@rollup/plugin-node-resolve';
const createPlugins = () => [
resolve()
];
export default [
{
input: 'src/a.js',
output: { file: 'dist/a.js', format: 'esm' },
plugins: createPlugins()
},
{
input: 'src/b.js',
output: { file: 'dist/b.js', format: 'esm' },
plugins: createPlugins()
}
];
Фабрика плагинов предотвращает утечку состояния между сборками и обеспечивает изоляцию.
Внутри массива конфигураций можно использовать условия для включения или исключения отдельных сборок:
const isProd = process.env.NODE_ENV === 'production';
export default [
{
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
}
},
isProd && {
input: 'src/index.js',
output: {
file: 'dist/bundle.min.js',
format: 'esm'
}
}
].filter(Boolean);
Такой подход позволяет управлять набором сборок без изменения структуры конфигурации.
При использовании watch каждая конфигурация
отслеживается отдельно. Изменение исходного файла может триггерить
пересборку всех конфигураций, если они зависят от одного и того же
входного набора модулей.
export default [
{
input: 'src/index.js',
output: {
file: 'dist/a.js',
format: 'esm'
},
watch: {
include: 'src/**'
}
},
{
input: 'src/index.js',
output: {
file: 'dist/b.js',
format: 'cjs'
},
watch: {
include: 'src/**'
}
}
];
Каждая конфигурация реагирует на изменения независимо, что позволяет гибко настраивать поведение сборки в режиме разработки.
Порядок конфигураций в массиве имеет значение в контексте:
Хотя конфигурации изолированы, некоторые плагины могут писать в общие ресурсы, что делает порядок косвенно значимым.
Множественные конфигурации становятся особенно полезны при наличии:
В таких случаях конфигурационный файл становится декларативным описанием всех артефактов сборки, а не только одного результата.