Проблема

По мере того, как ваш проект начинает стареть, вы обязательно захотите реорганизовать его части. Возможно, на каком-то этапе вы использовали какие-то ярлыки, у разных разработчиков были разные способы делать вещи. Даже если ни один из них не применим к вам, с быстро развивающимся языком, таким как JavaScript, новые библиотеки, стандарты и устаревшие методы являются частью длительного жизненного цикла проекта.

Для нас он запускал ESLint, конвертируя старую кодовую базу в Angular и обнаруживая ожидаемые тысячи ошибок. Запуск ESLint с флагом исправления решил большинство из них, но остались тысячи.

Было несколько особенно раздражающих проблем, некоторые из которых касались использования стрелочных функций (prefer-arrow/prefer-arrow-functions) и порядка элементов (@typescript-eslint/member-ordering rule).

Абстрактные синтаксические деревья

Алгоритм сортировки методов и свойств должен быть простым, лишь бы мы могли получить их в виде удобных для работы с объектами. Войдите в абстрактное синтаксическое дерево или AST.

Абстрактное синтаксическое дерево — это древовидное представление синтаксической структуры текста, написанного на формальном языке. Это структурное представление вашего кода, которое содержит всю информацию для понимания того, что должна делать программа, и может быть интерпретировано программно.

Вы можете просмотреть AST вашей программы на https://astexplorer.net/. Он не поддерживает TypeScript, поэтому мы просто удалим только части TS при вставке.

jscodeshift

Библиотека jscodeshift позволяет нам работать с JavaScript или TypeScript в форме AST, и ее можно установить следующим образом:

$ npm i jscodeshift -g

Основная форма вашего преобразования выглядит следующим образом:

Если вы используете TypeScript, вы можете получить intellisense, если импортируете API и FileInfo. Установите типы с помощью:

$ npm i @types/jscodeshift --save-dev

Преобразование кода

Прежде чем начать, я использую AST Explorer, чтобы получить четкое представление о том, что я хочу найти, и что я хочу получить на выходе. Начнем со стрелочных функций.

Мы хотим перейти от:

To:

Сравнивая эти два, кажется, что мы хотим изменить только тип выражения с FunctionExpression на ArrowFunctionExpression. Кажется достаточно простым, так что давайте сделаем это.

Давайте посмотрим, как это работает, когда мы отлаживаем его с помощью следующей команды, а затем подключаемся к отладчику с помощью консоли разработчика Chrome:

node --inspect-brk ./node_modules/jscodeshift/bin/jscodeshift -t [transform-path] [target-file-path] --parser=ts --run-in-band

Обратите внимание, что root.find возвращает набор путей, а вызов forEach для набора будет перебирать пути. Чтобы преобразовать FunctionExpression в ArrowFunctionExpression, нам нужно получить параметры и тело функции, которые находятся в свойстве value.

Результат

Выполнение кода преобразует FunctionExpression в ArrowFunctionExpression, как и ожидалось, но ESLint по-прежнему не устраивает. Он не хочет блокировать операторы только с оператором возврата.

Вернемся к проводнику AST.

Обратите внимание, как аргумент возвращаемого выражения в операторе блока в коде before просто перемещается в тело в коде after. Вот что мы будем делать.

Вот результат:

А что насчет остальных?

В этой статье описывается, как я исправил одну из ошибок ESLint с помощью JS Codemods. Моя страница github содержит преобразования для методов и свойств сортировки, а также исправление устаревшей подписи Subscribe в RxJS.