Putout: линтер нового поколения

В 2015 году Николас Заказ опубликовал статью с похожим названием, только вместо Putout было ESLint. В те времена это было действительно так, ESLint безусловно стандарт дефакто в мире JavaScript линтеров. Однако совершенству нет предела, и любому успешному инструменту приходит на смену еще более успешный, либо дополняет его устраняя недостатки. Об одном из таких инструментов мы сегодня поговорим, однако начать хотелось бы с истории.

История линтеров

Начнем с истоков, чтобы было понятно откуда ноги растут, после чего перейдем к самым популярным решениям на JavaScript.


  • 1972 — Стивен Джонсон создает первый линтер в Bell Labs, он проверяет наличие ошибок в коде на C. Слово «Lint» означает что-то вроде «комков волокон в хлопковой ткани».


  • 2002 — Дуглас Кроуфорд создает первый JavaScript линтер JSLint с несвободной лицензией The Software shall be used for Good, not Evil. И сообщество с радостью (бы) приняло такой полезный инструмент, но были недостатки: правила (почти) нельзя конфигурировать, в нем минимум настроек.


  • 2011 — Антон Ковалев создает форк JSHint лишенный недостатка предшественника имеет возможность обильной конфигурации, однако монолитен и не расширяем.


  • 2013 — Николас Закас не выдерживает отсутствия плагинов в JSHint и пишет свой линтер о котором знает каждый js-разработчик: ESLint.


  • 2018 — Coderaiser пишет инструмент, который удаляя неиспользуемые переменные, делает то, что ESLint, делать отказывается, а именно: использует правила, которые могут изменить поведение кода.


Что не так с существующими линтерами

В JavaScript Community все более-менее утряслось, и остался один линтер, выживший либо вмердживший в себя конкурентов. ESLint и правда делает очень многие вещи достаточно качественно. Но все не так просто, и есть набор моментов, который, скажем так, можно было бы улучшить:


  1. Нет состояния прогресса. В 2020-ом году, мы каждый день запускаем инструмент, который неизвестно когда завершит работу. Да, на маленьких проектах это не заметно и не существенно. Но фронтенд сейчас очень сильно разросся, и плагинов, и правил существует довольно-таки много, и проверка может вполне выполняться несколько минут. Как минимум, это не удобно.
  2. Переусложненная система плагинов. Да она быстрая, эффективная, но очень уж многословная:
  3. Наличие такой концепции как warning: зачем? Если нашел проблему — возьми и исправь, зачем о ней говорить, помечая желтым цветом. Постоянные напоминания о чем-то, что не сильно важно не имеют смысла.
  4. Отсутствие опции --fix для огромного количества правил. Это сейчас ESLint двигается в сторону autofix, но делает он это крайне плавно, и само наличие правил, которые не исправляются сами, лично меня напрягает.

В чем ключевая идея Putout

Владея основной информацией о том, что не так с существующими решениями, было решено сделать продукт в соответствии со следующими принципами:


  1. Возможность отображения статуса прогресса.
  2. Каждое правило имеет возможность исправления.
  3. Правила могут минимально менять поведение кода, если это делает его лучше.
  4. Правила имеют полные и конкретные названия (convert-equal-to-strict-equal в противовес eqeqeq).
  5. Нет ворнингов, есть только ошибки.
  6. Максимально дополнять ESLint, не дублируя его работу, косметические правки имеет смысл оставить ему.
  7. 100% покрытие тестами (сейчас их более 1400)
  8. Писать и тестировать плагины должно быть просто и легко.
  9. Маленькое ядро, вся система состоит из плагинов.
  10. Интеграция с существующими решениями.

Архитектура

image

Основной механизм работы Putout состоит из работы трех модулей:


  • parser — парсит код в AST, а затем AST обратно в код
  • loader — загружает плагины
  • runner — запускает на выполнение плагины

Плагины

Встроенные плагины поддерживают 4 вида интерфейсов, начиная от самых простых, и заканчивая сложными. Благодаря этому putout содержит в себе больше 50 плагинов, каждый из которых является отдельным npm-пакетом, то есть при обновлении плагина, update придет пользователям более старых версий Putout наравне с пользователями новых версий.

Интеграция с существующими решениями

Putout поддерживает все самые популярные парсеры JavaScript кода, а так же системы написания кодмодов, такие как jscodeshift. Кроме этого может использоваться как плагин для ESLint (благодаря чему попадает во все IDE), плагин для babel, а также имеет возможность запуска ESLint для форматирования файла, после внесения изменений, а так же встроенную поддержку работы со staged файлами в git и улучшенную работу кэша (кэшируются результаты проверки всех правил Putout, и только встроенных правил eslint).

Послесловие

Я не рассказал как установить, использовать и настраивать Putout поскольку уже говорил об этом в одной из предыдущих статей, хочу лишь добавить, что все замечания написанные в комментариях были учтены и исправлены. Всем спасибо за внимание:).

© Habrahabr.ru