Контекст плагина Rollup формируется через объект this,
доступный внутри большинства хуков. Он представляет собой API сборщика,
через которое плагин получает доступ к графу модулей, метаданным и
внутреннему состоянию бандла. Среди наиболее важных методов этого
контекста выделяются this.getModuleInfo и
this.getModuleIds, позволяющие работать с уже построенной
структурой зависимостей.
Во время выполнения сборки Rollup строит граф модулей, в котором каждый файл превращается в узел с набором метаданных: импортами, динамическими импортами, флагами побочных эффектов, AST (при необходимости), информацией о входных точках и внутренними служебными данными. Эти данные доступны через единый интерфейс, чтобы плагины могли анализировать граф без повторного парсинга и чтения исходного кода.
Метаданные формируются по мере прохождения стадий пайплайна:
resolveId, load, transform,
moduleParsed, и становятся стабильно доступны в фазах, где
граф уже частично или полностью построен.
Метод this.getModuleInfo(id) возвращает объект с
информацией о конкретном модуле по его идентификатору.
const info = this.getModuleInfo(id);
Возвращаемое значение представляет собой объект метаданных модуля,
либо null, если модуль ещё не загружен или не существует в
графе.
Объект информации о модуле обычно содержит следующие поля:
id — уникальный идентификатор модуля (абсолютный путь
или виртуальный ID)importedIds — список статических импортовdynamicImporters — модули, которые импортируют текущий
модуль динамическиimporters — статические импортерыisEntry — является ли модуль точкой входаisExternal — помечен ли модуль как внешнийhasModuleSideEffects — наличие побочных эффектовast — AST дерева (если включено и доступно)meta — пользовательские метаданные, добавляемые
плагинамиsyntheticNamedExports — флаг синтетических
экспортовСтруктура может расширяться в зависимости от версии Rollup и активных
плагинов, поскольку meta является расширяемым
пространством.
this.getModuleInfo не гарантирует наличие полной
информации на всех этапах сборки. Поведение зависит от стадии:
resolveId модуль может отсутствовать в графеload информация может быть частичнойtransform большинство модулей уже присутствуютgenerateBundle граф полностью сформированТаким образом, корректное использование метода предполагает учет фазы жизненного цикла сборки.
Возвращаемый объект является кэшированным представлением. Rollup не
создает новый объект при каждом вызове, а возвращает ссылку на
внутреннюю структуру. Это важно для оптимизации: повторные вызовы
getModuleInfo не приводят к пересборке или повторному
анализу.
export default function myPlugin() {
return {
name: 'dependency-analyzer',
transform(code, id) {
const info = this.getModuleInfo(id);
if (!info) return;
const hasDynamicImports = info.dynamicImporters.length > 0;
if (hasDynamicImports) {
this.warn(`Модуль ${id} используется в dynamic import`);
}
}
};
}
В данном случае анализируется, используется ли модуль в динамических импортерах, что может влиять на стратегию код-сплиттинга.
getModuleInfo часто используется для рекурсивного обхода
зависимостей:
function collectImports(pluginContext, id, result = new Set()) {
const info = pluginContext.getModuleInfo(id);
if (!info) return result;
for (const imported of info.importedIds) {
if (!result.has(imported)) {
result.add(imported);
collectImports(pluginContext, imported, result);
}
}
return result;
}
Такой подход позволяет восстановить дерево зависимостей без прямого доступа к внутренним структурам Rollup.
Несмотря на гибкость, метод имеет ряд ограничений:
null для еще не обработанных
модулейИз-за этого его использование должно быть привязано к пониманию жизненного цикла сборки.
Метод this.getModuleIds() возвращает список всех
модулей, которые были зарегистрированы в текущем графе сборки.
for (const id of this.getModuleIds()) {
// обработка модулей
}
Результатом является итерируемая коллекция идентификаторов модулей.
getModuleIds отражает текущее состояние графа и может
изменяться по мере выполнения сборки. В отличие от
getModuleInfo, который работает с конкретным узлом, этот
метод дает обзор всей системы модулей.
Ключевые характеристики:
Различие между методами принципиальное:
getModuleInfo(id) — доступ к одному узлу графаgetModuleIds() — доступ ко всему набору узловПервый используется для точечного анализа, второй — для обхода или глобальной агрегации.
export default function graphPlugin() {
return {
name: 'graph-plugin',
generateBundle() {
const stats = {
totalModules: 0,
entryModules: 0
};
for (const id of this.getModuleIds()) {
const info = this.getModuleInfo(id);
if (!info) continue;
stats.totalModules++;
if (info.isEntry) {
stats.entryModules++;
}
}
this.info(
`Modules: ${stats.totalModules}, Entries: ${stats.entryModules}`
);
}
};
}
Этот код демонстрирует глобальный анализ графа в момент генерации бандла.
На практике оба метода используются совместно. Типичный паттерн —
сначала получить список всех модулей через getModuleIds,
затем для каждого извлечь детальную информацию через
getModuleInfo.
Такой подход обеспечивает:
Поведение методов тесно связано с пайплайном Rollup:
getModuleIds неполныйgetModuleInfo частично доступенПоле meta внутри ModuleInfo служит для
обмена данными между плагинами. Оно не имеет строгой схемы и позволяет
хранить произвольные структуры.
Пример:
transform(code, id) {
const info = this.getModuleInfo(id);
if (info) {
info.meta.myPlugin = {
analyzed: true,
timestamp: Date.now()
};
}
}
Другие плагины могут затем использовать эти данные, создавая цепочку анализа поверх графа.
Доступ к getModuleInfo является дешевой операцией, так
как данные берутся из кэша. Однако частые обходы через
getModuleIds с последующим вызовом
getModuleInfo могут стать затратными при больших
проектах.
Оптимизационные особенности:
При работе с большими монорепозиториями важным становится ограничение количества полных обходов графа и агрегация данных в одной фазе.
В режиме наблюдения граф модулей может изменяться между итерациями сборки. В этом случае:
getModuleIds отражает текущее состояние после
пересборкиgetModuleInfo обновляется при изменении модуляЭто требует аккуратного подхода к хранению внешнего состояния в плагинах, поскольку ссылки на старые метаданные могут становиться устаревшими.
Обе функции формируют основу для большинства аналитических плагинов Rollup, работающих с графом модулей на уровне метаданных, а не исходного кода.