Перейти к основному содержимому

Статический анализ и линтеры

Правила, которые компилятор и анализатор проверяют при каждом нажатии клавиши, — так ошибка находится раньше, чем её успевает заметить человек. В Dart это анализатор, набор правил линтера и любые собственные правила, которые нужны проекту.

Почему это важно. Каждое правило, за которым следит инструмент, — это правило, которое никому не нужно помнить, обсуждать и вылавливать на code review. Самый дешёвый механизм контроля качества из существующих — и тот, который в большинстве проектов годами стоит в настройках по умолчанию.

Что понимать

  • Что анализатор знает уже сейчас, а вы это игнорируете
  • Какие правила предотвращают ошибки, а какие — только вопрос вкуса
  • Во что обходится предупреждение, которое вы научились пролистывать
  • Где собственное правило проекта заменило бы повторяющийся комментарий на review
  • Почему появился ignore-комментарий и нужен ли он до сих пор

Основные темы

Анализатор

  • analysis_options.yaml — и то, что настройки по умолчанию лишь отправная точка
  • Уровни error, warning и info — и повышение уровня тех, что важны
  • Строгие режимы: strict-casts, strict-inference, strict-raw-types
  • Как исключить сгенерированный код, не исключив заодно свой

Правила линтера

  • Готовые наборы правил и то, где они заканчиваются
  • Правила, которые ловят настоящие ошибки: futures без await, непокрытые ветки switch, сравнение несовместимых типов
  • Правила про стиль — договориться о них один раз
  • Постепенное включение на существующей кодовой базе, чтобы не утонуть в предупреждениях

За пределами настроек по умолчанию

  • Собственные правила линтера под договорённости проекта
  • Архитектурные правила: какому слою что можно импортировать
  • Проверка зависимостей и лицензий
  • Поиск мёртвого кода и неиспользуемых зависимостей

Как это закрепить

  • Сборка падает на замечаниях анализатора — так предупреждения не копятся
  • Pre-commit-хуки для быстрых проверок
  • Форматирование не обсуждается и применяется автоматически
  • Регулярный пересмотр всех // ignore:

Уровни

УровеньКак это выглядит
JuniorИсправляет предупреждения анализатора, запускает форматтер, следует настроенным правилам.
MiddleНастраивает наборы правил, включает строгие режимы, держит кодовую базу без предупреждений и закрепляет это в CI.
SeniorПереводит договорённости команды и архитектурные границы в правила и внедряет их постепенно, не останавливая проект.

Практика

Для начала

  • Дойти до нуля Уберите все предупреждения анализатора в проекте и настройте сборку так, чтобы она падала, если появится новое.

  • Включить строгий режим Включите strict-casts и разберите последствия.

  • Разобрать ignore-комментарии Соберите список всех // ignore: и решите по каждому, оправдан ли он до сих пор.

Дальше

  • Превратить комментарий с review в правило Найдите то, что ревьюеры повторяют раз за разом, и оформите это правилом линтера.

  • Закрепить границу Добавьте правило, которое роняет сборку, когда слой импортирует то, что ему нельзя.

  • Перейти на более строгий набор Переведите существующую кодовую базу на более строгий пакет правил, не делая коммит на тысячу файлов.

Проверьте себя

  • Сколько предупреждений анализатора в вашем проекте прямо сейчас?
  • Какие правила линтера у вас включены и выбирал ли их кто-нибудь осознанно?
  • Какой комментарий чаще всего повторяют ревьюеры в вашей команде — и мог бы его писать инструмент?
  • Что обычно означает // ignore: в вашей кодовой базе?
  • Падает ли ваш CI на замечаниях анализатора — или только на упавших тестах?
  • Какое архитектурное правило в вашем проекте существует только в головах?

Материалы

  • Customizing static analysis — полный справочник по analysis_options.yaml, включая строгие режимы, которые выключены по умолчанию, а включить их стоит.
  • Dart linter rules — все правила и объяснение, зачем каждое нужно. Стоит один раз прочитать целиком: полезных правил больше, чем включает любой стандартный набор.
  • package:very_good_analysis — более строгий готовый набор правил и разумная цель, к которой можно постепенно вести существующий проект.
  • custom_lint — как писать на Dart правила под конкретный проект. Механизм, который превращает ваши договорённости в ошибки компиляции.
  • Effective Dart — обоснование большинства правил. Помогает решить, стоит ли правило того трения, которое оно создаёт.