Работа с несколькими точками входа

Работа с несколькими точками входа в Rollup используется в случаях, когда проект необходимо собрать в несколько независимых бандлов, каждый из которых имеет собственный граф зависимостей. Это отличается от классического сценария с одной точкой входа, где весь код приложения собирается в единый файл.

Базовая концепция нескольких entry points

В Rollup точка входа определяет стартовый модуль, от которого строится граф зависимостей. При использовании нескольких точек входа создаётся несколько графов, либо один общий граф с несколькими корнями, в зависимости от конфигурации.

Ключевая идея заключается в том, что каждая entry point становится отдельным корнем дерева зависимостей.

Основные сценарии использования:

  • библиотека с несколькими независимыми модулями
  • разделение кода по функциональным зонам (admin, public, widget)
  • сборка нескольких версий одного пакета
  • micro-frontend архитектура
  • экспорт отдельных утилит как самостоятельных пакетов

Форматы задания нескольких входных точек

Массив entry points

Самый простой способ — передать массив строк в поле input.

export default {
  input: [
    'src/main.js',
    'src/admin.js',
    'src/widget.js'
  ],
  output: {
    dir: 'dist',
    format: 'esm'
  }
};

В этом случае Rollup создаст отдельный бандл для каждого входного файла.

Результат:

  • main.js → основной бандл
  • admin.js → отдельный бандл
  • widget.js → отдельный бандл

Объектная форма входов

Объект позволяет явно задать имена выходных файлов.

export default {
  input: {
    main: 'src/main.js',
    admin: 'src/admin.js',
    widget: 'src/widget.js'
  },
  output: {
    dir: 'dist',
    format: 'esm'
  }
};

Здесь ключи объекта становятся именами чанков.

Результат:

  • dist/main.js
  • dist/admin.js
  • dist/widget.js

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


Поведение графа зависимостей

При множественных entry points Rollup анализирует зависимости следующим образом:

  • если модули не пересекаются, каждый entry собирается независимо
  • если есть пересечение зависимостей, Rollup объединяет общий код в shared chunks
  • одинаковые импорты могут быть вынесены в отдельные чанки при code splitting

Общие зависимости

Если несколько entry points используют один модуль:

// src/utils.js
export const sum = (a, b) => a + b;
// src/main.js
import { sum } from './utils.js';
// src/admin.js
import { sum } from './utils.js';

Rollup может:

  • вынести utils.js в отдельный chunk
  • либо инлайнить его, если конфигурация не позволяет разделение

Управление code splitting при множественных входах

manualChunks

Функция manualChunks позволяет управлять тем, как общие зависимости распределяются между чанками.

export default {
  input: {
    main: 'src/main.js',
    admin: 'src/admin.js'
  },
  output: {
    dir: 'dist',
    format: 'esm',
    manualChunks(id) {
      if (id.includes('node_modules')) {
        return 'vendor';
      }
    }
  }
};

Эффект:

  • все зависимости из node_modules попадают в vendor.js
  • код приложения остаётся разделённым по entry points

Оптимизация общих модулей

Rollup применяет следующие правила:

  1. одинаковые зависимости объединяются
  2. модули с одинаковым содержимым дедуплицируются
  3. динамические импорты создают отдельные chunks независимо от entry points

Порядок выполнения сборки

При множественных входах Rollup:

  1. создаёт список entry modules
  2. строит отдельные графы зависимостей
  3. объединяет пересекающиеся узлы
  4. формирует набор chunks
  5. применяет output-плагины
  6. генерирует финальные файлы

Влияние формата output

ES Modules

output: {
  dir: 'dist',
  format: 'esm'
}
  • лучшая поддержка code splitting
  • сохранение import/export структуры
  • эффективное разделение чанков

CommonJS

output: {
  dir: 'dist',
  format: 'cjs'
}
  • ограниченная поддержка code splitting
  • возможна агрегация нескольких entry в один файл
  • менее гибкая работа с динамическими зависимостями

IIFE и UMD

При использовании IIFE или UMD:

  • каждый entry point обычно превращается в отдельный self-contained bundle
  • разделение на чанки ограничено или отсутствует
  • пересечение зависимостей часто инлайнится

Особенности именования файлов

При использовании dir output Rollup генерирует файлы автоматически.

patterns

output: {
  dir: 'dist',
  entryFileNames: '[name].js',
  chunkFileNames: 'chunks/[name]-[hash].js'
}

[name] соответствует ключу entry point или имени модуля.


Сложные зависимости между entry points

Общий модуль как entry и dependency

Если один и тот же файл указан как entry point и импортируется другими модулями:

input: {
  main: 'src/main.js',
  shared: 'src/shared.js'
}

И при этом:

import './shared.js';

Rollup может:

  • либо создать отдельный chunk для shared
  • либо продублировать код в зависимости от стратегии output

Динамические импорты и множественные entry points

Dynamic import усиливает разделение графа:

import('./admin.js');
import('./widget.js');

Даже при наличии нескольких entry points Rollup создаёт дополнительные async chunks.

Особенность:

  • entry points формируют синхронные графы
  • dynamic imports формируют асинхронные подграфы

Плагины и множественные входы

Некоторые плагины ведут себя по-разному при multi-entry сборке.

Примеры влияния:

  • трансформаторы могут применяться к каждому entry отдельно
  • плагины минификации работают после объединения chunks
  • alias и resolve влияют на общий граф зависимостей

Частые ошибки при использовании нескольких entry points

Дублирование кода

Причина:

  • отсутствие code splitting
  • неправильная настройка manualChunks

Конфликты имен chunks

Причина:

  • одинаковые имена entry points в объектной форме
  • отсутствие настройки entryFileNames

Неожиданная агрегация зависимостей

Причина:

  • пересекающиеся импорты между entry points
  • общие зависимости без явного разделения

Стратегии проектирования multi-entry сборки

Изоляция entry points

Каждый entry должен:

  • иметь собственный контекст выполнения
  • минимально зависеть от других entry

Выделение shared слоя

Часто используется структура:

  • core (общие утилиты)
  • modules (entry points)
  • vendor (внешние зависимости)

Группировка по функциональности

Пример:

  • admin bundle
  • client bundle
  • worker bundle

Каждый работает независимо, но использует общий слой utils.


Производственные сценарии

Библиотека с несколькими API

input: {
  index: 'src/index.js',
  es: 'src/es.js',
  cjs: 'src/cjs.js'
}

Каждый entry соответствует разному формату потребления.


Микрофронтенды

input: {
  header: 'src/header.js',
  footer: 'src/footer.js',
  dashboard: 'src/dashboard.js'
}

Каждый модуль может разворачиваться отдельно.


Плагинная архитектура

Entry points представляют плагины:

  • plugin-auth
  • plugin-payments
  • plugin-analytics

Итоговая модель поведения Rollup при multi-entry

  • каждый entry point становится корнем графа
  • графы могут пересекаться
  • Rollup автоматически оптимизирует общие зависимости
  • итоговая структура зависит от output.format и стратегии chunking