Кеширование в Rollup реализовано через передачу ранее собранного
состояния бандла в последующие сборки. Это состояние передаётся через
поле cache в объекте входных опций и позволяет существенно
ускорить повторные сборки за счёт переиспользования уже построенного
графа модулей и результатов их анализа.
Основная задача кеширования в Rollup — минимизация повторной работы при инкрементальных сборках. В процессе первой сборки Rollup:
Без кеша каждая новая сборка повторяет эти операции полностью, даже
если изменения затрагивают лишь небольшую часть проекта. Поле
cache позволяет сохранить результаты этих вычислений и
переиспользовать их.
При первом вызове rollup.rollup() кеш отсутствует, и
создаётся полный внутренний state сборщика. После завершения сборки
Rollup формирует объект бандла, внутри которого присутствует поле
cache.
Этот объект содержит:
При следующем вызове rollup.rollup({ cache }) этот
объект передаётся обратно в сборщик, что позволяет:
Ключевой момент заключается в том, что Rollup не просто хранит текстовый кеш, а сохраняет структурированное представление всего графа сборки.
Объект cache не является стабильным публичным API в
смысле строгой структуры, но концептуально он включает:
modules — список модулей с их состоянием;moduleIds — идентификаторы модулей в графе;pluginCache — кеш, используемый плагинами через их
cacheKey;watchFiles — список файлов, участвующих в сборке;Каждый модуль в кеше содержит:
Важно учитывать, что структура cache может меняться между версиями Rollup, поэтому прямое манипулирование им считается небезопасным.
При повторной сборке с переданным cache Rollup выполняет
дифференциальный анализ:
Таким образом, при небольших изменениях перерасчёт ограничивается локальной областью зависимостей.
Особенно эффективно кеширование работает в проектах с большим количеством модулей, где изменение одного файла не требует пересборки всего дерева.
В режиме наблюдения (watch) кеш играет центральную роль.
Каждый цикл пересборки:
Это создаёт непрерывную цепочку инкрементальных состояний.
В watch-режиме кеш:
Однако при некорректной работе плагинов кеш может приводить к «залипанию» состояния, когда изменения не отражаются из-за неправильной инвалидации.
Ключевой аспект кеширования — корректная инвалидация. Rollup автоматически инвалидирует модули при:
Плагины могут влиять на кеш через:
transform — изменение содержимого модуля;resolveId — изменение структуры графа;load — подмена содержимого модуля.Если плагин возвращает разные результаты для одного и того же входа, но не сообщает Rollup о необходимости пересборки, кеш может стать источником неконсистентного состояния.
Плагины могут использовать внутренний кеш Rollup, но чаще применяют
собственные механизмы через this.cache. Rollup
предоставляет плагинам доступ к стабильному объекту кеширования:
Типичный сценарий — сохранение результатов дорогих вычислений, например:
Важно, что плагинный кеш и общий cache Rollup — разные
уровни абстракции: первый локальный, второй глобальный для всей
сборки.
Использование cache влияет на производительность в
нескольких направлениях:
В крупных проектах прирост скорости повторной сборки может быть кратным, особенно если:
Кеш в Rollup имеет ряд ограничений, которые необходимо учитывать:
cache
между версиями;Также важно учитывать, что кеш не предназначен для долгосрочного хранения между процессами без повторной проверки актуальности файловой системы.
При программной сборке типичный паттерн выглядит как последовательная передача кеша:
bundle.cache.Это особенно характерно для кастомных build-систем, где Rollup используется как движок:
Передача кеша выглядит как часть входных опций:
const bundle = await rollup.rollup({
input: 'src/index.js',
cache: previousCache
});
После завершения:
previousCache = bundle.cache;
Неправильное использование кеша часто приводит к нестабильным результатам:
Особенно критичной является ситуация, когда кеш переносится между разными версиями Rollup или между сборками с разными наборами плагинов — это приводит к рассинхронизации внутреннего графа и непредсказуемым результатам выполнения.