За последние несколько месяцев много было написано о том, что автоматизированные инструменты могут сделать для инженеров-программистов. Сегодня я не прыгаю на эту подножку: я хочу поговорить о чем-то, что существует намного дольше, чем ChatGPT. Но это то, что произвело революцию в моем опыте разработки и продолжает улучшать его месяц за месяцем. Я хочу поговорить об ESLint.

Прежде чем идти дальше, давайте быстро определим линтинг в целом и ESLint в частности. Линтер — это инструмент статического анализа кода, который анализирует код и проверяет его на соответствие списку правил, предназначенных для того, чтобы сделать его более читабельным, более производительным и менее подверженным ошибкам. Когда дело доходит до JavaScript, ESLint является отраслевым стандартом. Его высокая степень настраиваемости, включая возможность написания пользовательских правил, продвинула его вперед, и сегодня вы можете найти сотни плагинов с открытым исходным кодом, предоставляющих свои собственные полезные правила. Подробнее о том, как ESLint стал популярным линтером как для JavaScript, так и для TypeScript, см. в краткой истории Джоша Голдберга.

Когда я вспоминаю свои ранние годы работы инженером-программистом, я вспоминаю обзоры кода, изобилующие комментариями о стиле кода, использовании const и let и бесконечные дискуссии о том, как лучше написать цикл for. Теперь, когда я работаю с ESLint, мне больше не нужно об этом беспокоиться.

Более того, линтер выявляет проблемы, которые в противном случае могли бы остаться незамеченными. Однажды мы обнаружили, что объединили сфокусированный тест Cypress, а это означает, что почти ни один из наших тестов не выполнялся в наших пайплайнах CI. Только когда возникла производственная проблема — та, которая должна была быть обнаружена существующим тестом, — мы поняли, что произошло.

У нас есть правило для этого сейчас.

При правильных правилах ESLint может действовать как дополнительный член вашей команды. Этот товарищ по команде доступен 24 часа в сутки, 7 дней в неделю, чтобы обеспечить тщательную проверку кода. Как и его человеческие аналоги, он не будет иметь всего контекста и иногда будет делать ненужные предложения. Но он всегда будет там, чтобы замечать вещи, которые люди могут пропустить.

Получите максимум от ESLint

Надеюсь, продемонстрировав преимущества ESLint, я хотел бы поделиться некоторыми советами, как извлечь из него максимальную пользу.

Быть самоуверенным

Некоторые правила соблюдаются повсеместно. Мы все согласны не использовать var в 2023 году. Некоторые правила легко выбрать, потому что они позволяют повысить производительность или избежать ошибок. Но некоторые решения являются чисто произвольными. Мы могли бы часами обсуждать, следует ли запретить или потребовать запятые в конце, но будет ли это хорошим использованием нашего времени? В таких ситуациях лучше просто принять решение и выполнить его. Это большая часть привлекательности Prettier. Но это также относится к вещам, которые форматировщики кода не могут уловить, например, к соглашениям об именах и к тому, как сортировать импорт.

Прекратите использовать предупреждение

Конфигурация ESLint позволяет включать или выключать правила (error). Это также позволяет промежуточное состояние, называемое warn. Это выводит на экран какой-то желтый текст при запуске линтера. Но он не блокирует никаких конвейеров и, по моему опыту, полностью игнорируется. Если правило важно, оно должно быть блокирующим. Если это не так, его вообще не следует активировать. warn занимает странную золотую середину, которая никому не помогает.

Новые правила могут быть сложными при работе с устаревшим кодом. Полное исправление всех ошибок в существующих файлах может занять много времени и привести к сложным конфликтам слияния, когда другие люди одновременно работают над одними и теми же файлами. Поэтому некоторые команды вместо этого просто устанавливают новое правило на warn, чтобы их пайплайны продолжали работать. Проблема здесь в том, что разработчики будут продолжать нарушать правило, потому что никто никогда не обращает внимания на предупреждения. Реальное решение состоит в том, чтобы изолировать устаревший код, используя целевые комментарии eslint-disable, чтобы исключить определенные разделы из определенных правил.

Некоторые правила могут быть оставлены с параметром warn, потому что, хотя они поощряют передовой опыт, есть законные случаи, когда вы можете нарушить это правило. Опять же, настоящим решением является целенаправленное использование eslint-disable. Это гарантирует, что каждый раз, когда правило нарушается, это осознанный и обоснованный выбор.

Будьте осторожны с eslint-disable

При всем при этом два наиболее важных и полезных правила ESLint взяты из плагина eslint-comments: no-unlimited-disable и require-description. Целевые комментарии для отключения определенных правил в исключительных обстоятельствах бесценны, особенно если у вас столько же правил, сколько у нас в моей команде! Но может возникнуть соблазн использовать их, чтобы закрыть ESLint, не позволяя ему выполнять свою полезную работу.

Комментарии «Отключить» должны точно указывать, какое правило или правила отключаются, и всегда должны применяться только к тем строкам, где их применение строго необходимо. no-unlimited-disable не позволяет вам написать «eslint-disable» без указания какого-либо правила, что в конечном итоге приведет к полному отключению ESLint для рассматриваемого кода. require-description настаивает, чтобы вы добавили комментарий, объясняющий, почему вы отключаете конкретное правило. Если это нельзя обосновать кратким пояснением, правило вообще не следует отключать.

Развивайте образ мышления ESLint

Продолжайте задавать себе вопрос: «Может ли ESLint помочь мне здесь?» Несколько примеров:

  • Вы просматриваете код товарища по команде и замечаете что-то странное. Мог ли ESLint уловить это раньше вас? Может быть, правило уже существует — или, может быть, вы могли бы написать новое.
  • Кто-то, просматривая ваш код, только что заметил что-то, о чем вы не подумали. Мог ли ESLint предотвратить это?
  • Вы только что потратили часы на исправление сложной ошибки только для того, чтобы понять, что все это было благодаря одному отсутствующему объявлению. Возможно, стоит потратить время на то, чтобы найти или написать правило ESLint, чтобы это не повторилось.

Поделитесь предпочтительными правилами!

Может быть очень полезно поддерживать единообразие кода в организации, так как инженерам будет легче переключаться между проектами. С этой целью многие компании используют общую конфигурацию или плагин ESLint. Некоторые, например Airbnb или Github, выложили свой исходный код в открытый доступ. В Criteo мы сделали то же самое, объединив полезные правила из ряда других плагинов и добавив несколько собственных. Хотя некоторые правила весьма специфичны для наших технологий и вариантов использования, мы знаем, что многие из проблем, с которыми мы сталкиваемся, также возникают у других инженеров, поэтому мы решили сделать их общедоступными.

Я рекомендую вам взглянуть на наш репозиторий Github. Но чтобы подогреть ваш аппетит, вот несколько собственных правил, которые мы разработали сами:

  • no-todo-without-ticket требует, чтобы каждый комментарий TODO или FIXME содержал ссылку на тикет JIRA. Мы все видели задачи 5-летней давности, которые так и не были обработаны; гарантируя, что хотя бы эта работа находится в очереди, мы помогаем бороться с этим явлением.
  • filename и filename-match-export обеспечивают согласованность имен файлов. Гораздо проще ориентироваться в кодовой базе с файлами с разумными именами. У нас давно были правила на этот счет, но они применялись только посредством проверки кода людьми, что тратило время всех и означало, что нарушения иногда не учитывались.

Выводы

Если вы что-то уберете из этой статьи, пусть это будет так: ESLint — это гораздо больше, чем просто пробелы и табуляции. Это действительно трансформирует производительность разработчиков. Развивая образ мышления ESLint — постоянно задавая вопрос «Может ли это быть правилом ESLint?» — можно сделать еще больше.