Изучаем TypeScript. Введение в TS Compiler API #1
Привет, на связи Antihype JS. Это вторая статья, посвященная TypeScript Compiler API. Сегодня мы разберемся как написать и подключить ваш первый плагин для компилятора. Если вы случайно нашли эту статью, то рекомендуем прочесть первую часть.
Перед написанием кода самого плагина, давайте рассмотрим основные встроенные в TS методы и объекты, с которыми нам предстоит работать.
visitNode
Посещаем узел AST с помощью переданной функции visitor. У нас есть возможность изменить узел, просто вернув новый объект из visitor. Как правило, трансформация запускается начиная с корневого узла - sourceFile.
visitEachChild
Посещает каждый дочерний узел узла, используя функцию visitor. Под капотом используется все тот же метод visitNode.
context
Каждый трансформер получает на вход контекст. Например, контекст можно использовать для получения информации о текущей конфигурации компилятора (compilerOptions).
visitor
Callback функция, которая используется для посещения каждого узла дерева. В ней будет располагаться вся логика трансформации кода.
context.factory.create*
Методы будут полезны для создания новых узлов AST. Например, этот код:
будет представлен в виде следующего набора вызовов для создания дерева:
Также эти методы можно использовать для различного кодгена, например генерации типов из Swagger или GraphQL схемы.
context.factory.update*
По умолчанию все ноды дерева иммутабельные. Для модификации существующих узлов необходимо использовать набор методов context.factory.update*.
Для замены значения строки “test” в уже знакомом нам коде:
В функции visitor следует использовать метод updateVariableDeclaration:
Наконец-то пишем плагин!
С базовым инструментарием мы закончили, давайте приступим к написанию основы для нашего первого плагина. Писать будем трансформер before типа, то есть работаем напрямую с AST тайпскрипта.
Как обычно, сначала импортнем TypeScript:
И для реализации функции transformer воспользуемся встроенным интерфейсом TransformerFactory:
Для лучшего понимания логики работы плагина, сначала мы решим задачу вывода нашего AST в консоль:
Круто, осталось подключить наш плагин в бойлерплейт из первой статьи:
Запускаем сборку и смотрим вывод консоли, чтобы убедиться в корректности работы плагина:
В левой части мы видим тип узла, а после разделителя выводится текст из исходного кода нашей программы.
Теперь я могу посмотреть AST своего исходного кода. А можно более сложный пример?
Хорошо, тогда решим задачу добавления рандомного числа в конец строки “test”:
С помощью встроенных тайпгардов (ts.isVariableDeclaration в нашем случае) и рекурсивного обхода дерева мы можем точечно выбирать нужные узлы и производить их кастомную обработку. Повторюсь, обязательным условием для корректной модификации является возврат нового узла.
Запускаем сборку и проверяем содержимого выходного файла:
Поздравляю, мы справились с нашей задачей, первый плагин отработал корректно!
На сегодня это все. Остаемся на связи, пишите в комментариях пожелания к следующей части. Пример проекта с исходным кодом можно посмотреть на GitHub.
Также подпишитесь на наш канал, там мы пишем и общаемся про frontend и все что с ним связано.