Bundling в Rollup представляет собой процесс объединения множества модулей JavaScript в один или несколько итоговых файлов, тогда как unbundling — осознанное сохранение части модулей раздельными для более гибкого распределения ответственности между сборкой и окружением исполнения. Баланс между этими подходами определяет архитектуру итоговой библиотеки, её совместимость, размер и поведение при интеграции в разные среды.
Rollup строит граф зависимостей начиная с входной точки и последовательно объединяет импортируемые модули в единый результат. Основная цель такого подхода — создание компактного и оптимизированного кода за счёт устранения лишних связей и применения tree-shaking.
Ключевые особенности bundling:
Rollup исторически ориентирован на библиотеки, где важна чистота ESM-графа и минимальный runtime-overhead.
При этом bundling не является абсолютной стратегией: Rollup позволяет выборочно исключать модули из сборки, оставляя их внешними зависимостями.
Unbundling в Rollup означает сознательное разделение кода на части, которые не попадают в финальный бандл, а остаются отдельными модулями, подключаемыми через import во время выполнения или через систему модульной загрузки окружения.
Основные сценарии применения:
Механизм реализуется через external, который исключает
модули из графа сборки Rollup:
export default {
input: 'src/index.js',
external: ['react', 'react-dom']
}
В результате Rollup сохраняет import-выражения без инлайнинга кода.
Ключевая задача архитектуры библиотеки — определить, где заканчивается ответственность пакета и начинается ответственность окружения.
Подходит для:
Характерные свойства:
Недостаток — увеличение размера и возможное дублирование зависимостей в конечном приложении.
Наиболее распространённый вариант для библиотек.
Сборка включает:
И исключает:
Такой подход позволяет комбинировать оптимизацию и гибкость интеграции.
Редкий сценарий, при котором библиотека фактически становится набором ESM-модулей без агрегации.
Особенности:
Используется в:
Конфигурация external является центральным механизмом
unbundling в Rollup. Она определяет, какие зависимости:
Типовые стратегии:
external: ['react', 'react/jsx-runtime']
Используется при фиксированном наборе зависимостей.
external: id => id.startsWith('react')
Позволяет масштабировать правила на подмодули и алиасы.
external: [/^react/, /^@babel/]
Применяется в крупных библиотеках с множеством peer-зависимостей.
PeerDependencies усиливают концепцию unbundling, фиксируя принцип: библиотека не должна поставлять собственную версию критических зависимостей.
Причины:
Rollup в этом контексте используется как инструмент соблюдения архитектурного контракта, а не просто упаковщик.
Гранулярность модулей напрямую влияет на эффективность tree-shaking.
При агрессивном bundling:
При unbundling:
Rollup эффективнее всего работает, когда модули мелкие и чистые, без побочных эффектов.
Rollup поддерживает разделение бандла на чанки, что создаёт промежуточную модель между bundling и unbundling.
Пример динамического импорта:
import('./feature.js')
Результат:
Это особенно важно для библиотек с расширяемой функциональностью.
Поведение bundling/unbundling сильно зависит от типа проекта.
Основные цели:
Часто используется:
Основные цели:
Часто используется:
Rollup в приложениях чаще выступает как средство финальной оптимизации, а не как архитектурный инструмент.
Dual package (ESM + CommonJS) усиливает необходимость точного контроля bundling.
Типичная структура:
При этом:
На практике проблемы возникают при нарушении границ:
Особенно критично это в UI-библиотеках, где размер и совместимость напрямую влияют на интеграцию.
Выбор между bundling и unbundling определяется несколькими факторами:
Стабильные утилиты и ядро библиотеки чаще выигрывают от bundling, тогда как интеграционные слои и внешние зависимости требуют unbundling для сохранения гибкости и предотвращения дублирования.
Граница между этими подходами формирует не просто конфигурацию Rollup, а структуру всей библиотеки и способ её включения в экосистему.