@rollup/plugin-multi-entry

Плагин @rollup/plugin-multi-entry используется в Rollup для объединения нескольких входных файлов в единый граф модулей без необходимости вручную описывать каждый entry point. Его основная задача — позволить задавать несколько точек входа через один виртуальный входной модуль, который затем импортирует все указанные файлы. Это особенно полезно в сценариях, где структура проекта содержит набор независимых модулей, которые требуется собрать как единый пакет или библиотеку.

Плагин относится к категории entry-handling инструментов и решает проблему ограничения Rollup, связанного с тем, что стандартная конфигурация input ожидает либо один файл, либо явный список входов. При масштабировании проекта поддержка таких списков становится неудобной, особенно если они генерируются динамически.


Принцип работы multi-entry

Внутри Rollup каждый входной файл рассматривается как корень графа зависимостей. @rollup/plugin-multi-entry добавляет дополнительный слой абстракции: он создает виртуальный модуль, который агрегирует список файлов через последовательность export или import.

Фактически плагин выполняет следующие действия:

  1. Принимает массив входных файлов или glob-паттерн.
  2. Генерирует виртуальный модуль.
  3. В этом модуле создаются импорты всех указанных файлов.
  4. Rollup воспринимает этот модуль как единую точку входа.

Такой подход позволяет использовать стандартный механизм tree-shaking, поскольку все зависимости остаются частью единого графа.


Установка

Плагин подключается как зависимость проекта:

npm install @rollup/plugin-multi-entry --save-dev

или

yarn add @rollup/plugin-multi-entry -D

После установки он становится доступен для использования в конфигурации Rollup.


Базовая конфигурация

Минимальная настройка включает подключение плагина в список plugins и передачу входных файлов через input.

import multiEntry from '@rollup/plugin-multi-entry';

export default {
  input: 'src/index.js',
  plugins: [
    multiEntry()
  ],
  output: {
    file: 'dist/bundle.js',
    format: 'esm'
  }
};

В этом примере src/index.js может быть виртуальной точкой входа, которая агрегирует другие модули через конфигурацию плагина.


Использование нескольких входных файлов

Основная функциональность проявляется при работе с массивом файлов:

import multiEntry from '@rollup/plugin-multi-entry';

export default {
  input: 'src/entries.js',
  plugins: [
    multiEntry({
      exports: false
    })
  ],
  output: {
    file: 'dist/bundle.js',
    format: 'cjs'
  }
};

Где entries.js может содержать:

import './moduleA.js';
import './moduleB.js';
import './moduleC.js';

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


Вариант с глоббингом файлов

Часто используется совместно с glob-паттернами для автоматического подключения файлов:

import multiEntry from '@rollup/plugin-multi-entry';

export default {
  input: 'src/entries.js',
  plugins: [
    multiEntry({
      exports: true
    })
  ]
};

И внутри entries.js:

export * from './modules/*.js';

Плагин интерпретирует это как набор отдельных модулей, добавляя их в граф сборки.


Параметры конфигурации

exports

exports определяет способ экспорта модулей.

  • false — файлы подключаются через import, но не агрегируются как экспортируемые сущности.
  • true — создаются реэкспорты всех модулей.

Пример:

multiEntry({
  exports: true
})

В этом режиме Rollup формирует единый интерфейс экспорта из множества файлов.


include / exclude (через сопутствующую фильтрацию)

Хотя сам плагин не всегда предоставляет полноценные фильтры, он часто используется совместно с внешними механизмами отбора файлов:

import glob from 'glob';

const files = glob.sync('src/modules/**/*.js');

Затем список передается в виртуальный entry-файл.


Виртуальная точка входа

Ключевая концепция @rollup/plugin-multi-entry — создание виртуального entry-модуля.

Rollup ожидает файл входа, но плагин подменяет его содержимое:

import './a.js';
import './b.js';
import './c.js';

Этот файл может не существовать физически или генерироваться динамически. Плагин перехватывает запрос и подставляет сгенерированный код.


Сценарии применения

1. Сборка набора утилит

Когда проект состоит из набора независимых функций:

src/utils/date.js
src/utils/string.js
src/utils/math.js

Можно собрать их в один пакет без ручного перечисления:

import multiEntry from '@rollup/plugin-multi-entry';

export default {
  input: 'src/utils/index.js',
  plugins: [multiEntry()]
};

2. Библиотеки с модульной архитектурой

При разработке библиотеки важно сохранять возможность частичного импорта:

export { a } from './a.js';
export { b } from './b.js';

multi-entry позволяет автоматически формировать такие агрегаты.


3. Генерация сборки из динамического списка файлов

Если структура модулей формируется автоматически (например, из CMS или API), плагин позволяет подключать их без статической конфигурации.


Ограничения и особенности

1. Отсутствие независимых entry points

Все входные файлы фактически становятся частью одного графа. Это означает отсутствие изолированных чанков, как при использовании массива input.


2. Возможное усложнение tree-shaking

Если используется режим exports: true, Rollup может включать больше кода, чем при явных точках входа, особенно если модули имеют побочные эффекты.


3. Поведение с side effects

Rollup учитывает sideEffects в package.json, но при multi-entry важно явно контролировать:

{
  "sideEffects": false
}

Иначе некоторые модули могут быть включены полностью.


4. Конфликты с другими entry-плагинами

Использование одновременно с @rollup/plugin-alias или динамическими входами требует аккуратной настройки порядка плагинов.


Внутреннее поведение в графе модулей

После обработки multi-entry Rollup строит граф следующим образом:

  1. Виртуальный entry добавляется как root node.
  2. Каждый импортируемый файл становится дочерним узлом.
  3. Далее стандартный механизм анализа зависимостей выполняет обход графа.
  4. На этапе генерации кода Rollup объединяет модули в чанки.

Это означает, что multi-entry не изменяет саму модель Rollup, а лишь влияет на начальную точку графа.


Отличие от стандартного массива input

Rollup позволяет напрямую задавать массив входов:

export default {
  input: ['src/a.js', 'src/b.js']
};

Однако @rollup/plugin-multi-entry отличается:

  • создается единый entry вместо нескольких независимых;
  • формируется общий граф, а не отдельные чанки;
  • проще управлять динамическими наборами файлов;
  • выше гибкость при генерации входов программно.

Использование с TypeScript и ESM

Плагин корректно работает с современными модулями:

import multiEntry from '@rollup/plugin-multi-entry';

export default {
  input: 'src/index.ts',
  plugins: [
    multiEntry()
  ],
  output: {
    format: 'esm'
  }
};

При этом TypeScript-компиляция выполняется до этапа Rollup или через отдельный плагин, например @rollup/plugin-typescript.


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

В реальных проектах multi-entry часто используется как промежуточный слой:

src/modules → entries generator → virtual entry → Rollup → bundle

Генератор может быть Node-скриптом:

import fs from 'fs';

const files = fs.readdirSync('./src/modules');

fs.writeFileSync(
  './src/entries.js',
  files.map(f => `import './modules/${f}'`).join('\n')
);

Далее Rollup использует multi-entry для интерпретации результата.


Производительность

При большом количестве файлов важно учитывать:

  • увеличение времени построения графа;
  • рост числа модулей в памяти;
  • возможные задержки при incremental rebuild.

Однако сам плагин не выполняет тяжелых вычислений, его стоимость в основном линейна относительно числа входных файлов.


Поведение в watch-режиме

При использовании rollup -w изменения в любом из входных файлов приводят к пересборке всего графа, поскольку виртуальный entry зависит от всех модулей сразу.

Это делает watch-режим менее гранулярным по сравнению с отдельными input-чанками.


Совместимость с другими инструментами Rollup

Плагин обычно используется совместно с:

  • @rollup/plugin-node-resolve
  • @rollup/plugin-commonjs
  • @rollup/plugin-typescript
  • rollup-plugin-terser

Порядок подключения влияет на итоговую структуру графа, особенно при работе с CommonJS-модулями.


Архитектурное значение

@rollup/plugin-multi-entry закрывает разрыв между статической моделью входов Rollup и динамическими сценариями сборки, где список модулей формируется во время разработки или даже во время выполнения Node-скриптов.

Он фактически превращает Rollup в систему с управляемой динамической агрегацией входных файлов, сохраняя при этом его основной принцип — построение единого графа зависимостей без лишней магии на уровне рантайма.