Хук transform является центральным элементом системы
плагинов Rollup, отвечающим за модификацию исходного кода модулей в
процессе сборки. Именно на этом этапе происходит основная работа по
анализу, переписыванию и преобразованию кода до того, как он попадёт в
граф модулей и далее в финальный бандл.
Пайплайн Rollup строится вокруг последовательной обработки модулей.
После этапа разрешения импортов и чтения файлов каждый модуль проходит
через цепочку плагинов. На этом этапе transform становится
точкой, где код ещё представлен в исходной или почти исходной форме, но
уже доступен для модификации.
Основная задача transform заключается в следующем:
Каждый плагин может внести свой вклад в трансформацию, и результат формируется как последовательное применение всех обработчиков.
Хук transform вызывается для каждого модуля с двумя
основными аргументами:
code — текст исходного модуля;id — абсолютный путь или идентификатор модуля.Типичная форма возврата:
{ code, map };null или undefined, если изменений
нет.При этом Rollup ожидает, что результат трансформации будет либо новым кодом, либо расширенной структурой с source map.
Каждый модуль проходит через цепочку плагинов последовательно. Важно учитывать следующие особенности:
transform становится входом для
следующего;null код передаётся дальше без
изменений;Promise.Таким образом, итоговый код модуля является результатом композиции всех трансформеров.
Основной сценарий использования transform —
переписывание исходного кода. Это может включать:
Простейший вариант — текстовые замены:
Подобные операции часто реализуются через регулярные выражения или AST-обработку.
Более корректный подход предполагает разбор кода в AST (Abstract
Syntax Tree). В этом случае transform используется как
точка интеграции парсеров:
После модификации AST код снова сериализуется в строку.
Хук позволяет внедрять дополнительную логику:
В таких случаях важно контролировать порядок вставок, чтобы не нарушить семантику исходного модуля.
Одной из ключевых задач transform является поддержка
source map. Rollup объединяет карты источников от всех плагинов, поэтому
каждый трансформер должен корректно возвращать map.
Варианты возврата:
null — отсутствие карты;map в формате Source Map v3;magic-string.При неправильной работе с source map нарушается отладка, что особенно критично в production-сборках.
Функция transform вызывается с контекстом плагина. Через
this доступны вспомогательные методы Rollup:
this.getModuleInfo(id) — получение информации о
модуле;this.emitFile() — создание ассетов;this.resolve() — ручное разрешение зависимостей;this.addWatchFile() — добавление файлов в
наблюдение;this.warn() и this.error() — генерация
сообщений.Контекст позволяет не только изменять код, но и влиять на граф модулей.
transform может возвращать Promise, что делает
возможным:
Асинхронность увеличивает гибкость, но усложняет предсказуемость пайплайна. Rollup ожидает завершения всех трансформаций перед переходом к следующему этапу.
Если плагин не изменяет код, он может вернуть null. Это
важный механизм оптимизации:
Часто используется условная логика:
Для ограничения области действия transform применяются
фильтры:
@rollup/pluginutils createFilter;Фильтрация позволяет избегать обработки:
Хотя transform работает с кодом, он косвенно влияет на
структуру графа:
Особенно важно учитывать, что изменение импортов может повлиять на порядок разрешения модулей.
transform находится между стадиями:
load — получение исходного кода;transform — его модификация;resolveId — разрешение зависимостей.Часто плагины комбинируют несколько хуков:
load предоставляет виртуальный код;transform адаптирует его под сборку.Так как transform вызывается для каждого модуля, его
производительность критична. Основные факторы влияния:
Оптимизации включают:
Несмотря на гибкость, хук имеет ограничения:
Также важно учитывать, что чрезмерная модификация кода может привести к трудноотлаживаемым бандлам.
Rollup применяет особую модель композиции:
transform получает результат предыдущего;null;Это делает transform предсказуемым, но чувствительным к
порядку регистрации плагинов.
transform часто используется совместно с виртуальными
модулями:
В таких случаях id может не соответствовать реальному
файлу, что требует дополнительной логики обработки.