Что такое линтер кода
Линтеры для начинающих
Красивый код с самого начала.
Недавно мы писали про линтеры: как они проверяют код на ошибки и делают его более красивым. Если коротко, то линтеры работают так:
Всё это — чтобы исправлять неаккуратности за программистами.
В этой статье — примеры линтеров, которые можно подключить хоть сейчас и получить чистый код уже к концу прочтения.
👉 Линтеры из обзора мы проверяли в VS Code и Sublime text 3. Для запуска проверки и форматирования открытого кода в VS Code нажмите в пустом месте правой кнопкой мыши и выберите пункт «Форматировать документ с помощью…» или «Format Document With…»:
Beautify — линтер для HTML
HTML-линтер, который следит за внешним видом кода страницы и форматирует его по заданными правилам. Умеет разбивать по строкам несколько команд, если они написаны в одной строке друг за другом.
Было: стили в одну строку, комментарии на той же строке, что и команды, несколько html-тегов на строке подряд Стало: красиво и понятно, каждая команда и комментарий — на своей строке
Если вы пишете не очень большой CSS-код, вам вполне хватит того же Beautify. Но если вы решили заняться стилями всерьёз и установили CSS-препроцессор, чтобы писать код ещё быстрее, посмотрите на Beautify css/sass/scss/less.
Уже по названию видно, что этот плагин работает не только с CSS, но и с форматами всех популярных препроцессоров. Устанавливается и работает точно так же, как и остальные, можно создать свои правила обработки кода или настроить под себя те, что есть.
JavaScript
JSLint — один из самых старых и самых строгих линтеров для JavaScript. Он проверяет вообще всё:
Если ваш код проверил JSLint и не нашёл ни одной ошибки — поздравляем, вы постигли JS-дзен.
В Sublime Text 3 JSLint подсвечивает строки с ошибкой и даёт подробное описание, что именно здесь не так
JSHint работает почти точно так же, как и предыдущий линтер, но проверяет менее строго. Идеальный инструмент для тех, кто только начинает писать код — он покажет критичные ошибки и не будет требовать соблюдения всех канонов языка JavaScript.
JSHint может показать все ошибки прямо в окне редактора кода
PyLint — линтер для Python
Pylint.org — самый популярный линтер для Python, который проверяет почти всё:
Если вам нужно что-то проверить в коде, скорее всего, PyLint сможет вам помочь.
Если нажать на строчку с ошибкой, курсор перейдёт к нужному участку кода
Что такое линтер
Резюме
Популярные статьи
В практических упражнениях на Хекслете код решения проверяют не только тесты, но и линтер. Линтер — программа, которая проверяет код на соответствие стандартам в соответствии с определённым набором правил. Правила описывают отступы, названия создаваемых сущностей, скобки, математические операции, длину строк и множество других аспектов. Каждое отдельное правило кажется не очень важным, но соблюдение их всех — основа хорошего кода.
Главная задача линтера — сделать код единообразным, удобным для восприятия и самим программистом, и другими людьми, которые будут читать код. В разных командах могут использоваться разные линтеры и разные наборы правил для них, но главное — уметь работать с линтером в принципе, а привыкнуть писать по определенным правилам будет несложно.
Линтер в упражнениях
Замечания линтера в упражнениях выводятся в нижней части экрана во вкладке Linter. На скриншоте пример для языка JavaScript и линтера ESLint, но похожая информация есть и в выводе других линтеров.
В выводе линтера вы всегда найдёте имя файла, в котором обнаружены ошибки. Под ним будет список ошибок с указанием номера строчки в файле и номера символа в ней, кратким описанием и названием правила, которое было нарушено.
Чтобы разобраться с непонятной ошибкой, введите её название в поисковике — одной из первых ссылок в выдаче будет сайт линтера. Обычно там есть более подробное описание ошибки, а также примеры хорошего и плохого кода, который её иллюстрирует. Исправьте код так, чтобы линтер был доволен 🙂
Если будет непонятно, как исправить ошибку, выкладывайте код решения на ревью и задавайте вопрос в обсуждениях соответствующего урока. Кто-то из нашей команды вам обязательно поможет.
Линтер — это чистый код для ленивых
Зачем нужен и как работает расчёсывальщик кода.
Ситуация: вы с коллегами параллельно работаете над разными частями одного кода. При очередном объединении исходников вы замечаете, что они пишут код не так, как вы: его сложно читать, у него сложный синтаксис и странно объявлены функции. Коллеги то же самое говорят про ваш код. В результате все правят код друг друга, приводят его к общему виду, а работа идёт долго.
👉 Линтер — это программа, которая автоматизирует всю эту возню и сама «причёсывает» код по определённым правилам. Даёшь ей чумазый и неуклюжий код, она чистит на уровне каких-то простых правил.
В чём может быть проблема, когда программистов много
Когда вы пишете код самостоятельно и для себя, его можно писать как угодно — в одну строчку без пробелов или отделяя функции друг от друга тремя пустыми строками. Главное, что вы понимаете, что здесь написано.
Как только вы начинаете участвовать с кем-то в совместном проекте, нужно установить общие правила написания кода. Сюда может относиться:
Чтобы эти правила применялись и работали, за ними кто-то должен следить. Можно выделить отдельного программиста, можно проверять код друг друга по очереди, а можно поручить это линтеру.
Что делает линтер
Линтер на основании заданных правил перерабатывает код за секунду:
Умные линтеры
Есть линтеры попроще и поумнее. Умные могут не только делать код красивым внешне, но и проверять логику работы программы. Например, линтер может найти все переменные, которые объявлены, занимают память, но ни разу не используются. Или он может заменить одни стандартные функции на другие, если в компании есть такие правила.
Отдельные умники умеют находить потенциальные утечки памяти, циклические зависимости, неполные вызовы и коряво объявленные классы. А ещё — проверять соответствия типов, связность классов, количественные параметры вызова функции и передачи аргументов, цикломатическую сложность и так далее. Но если вам нужны все эти проверки, то вы уже и так знаете про то, как устроены линтеры и для чего они нужны.
Линтер нашёл стилистическую ошибку в CSS — нужно поменять эти команды местами, потому что в компании принято сначала описывать верхние отступы, а потом уже боковые
Один линтер — один язык
Есть много разных линтеров для каждого языка программирования. Они отличаются по глубине настройки и возможностям анализа кода — как глубоко они могут его анализировать. Например, для JavaScript есть JSLint, JSHint и ESlint — это всё линтеры, которые делают плюс-минус одно и то же и различаются в деталях.
Иногда программисты используют несколько линтеров — один смотрит синтаксис, второй следит за памятью и безопасностью, а в третьем мощная система правил автозамены кода.
Что дальше
Сделаем подборку линтеров для веб-разработки — HTML, JavaScript, CSS. Не пропустите, если хотите отдать часть своих задач машине.
О линтерах, качестве кода, качестве вообще и управлении качеством
Бойтесь своих желаний, они могут исполниться.
Народная мудрость.
Ещё одна философская заметка про управление, а данном случае качеством, состоит из трёх частей: очень абстрактной, в меру абстрактной, конкретной и отдельного вывода. Содержит критику существующей практики применения линтеров.
Очень абстрактная часть о качестве
Сначала я хочу поговорить о качестве, а точнее об управлении качеством чего бы то ни было, о продукте в самом широком смысле, продукте как результате человеческой деятельности, будь то создание нового (написание кода или картины, проектирование космического корабля), отсечения лишнего (скульптура, фрезеровка, отбор хороших фруктов), или трансформация (перевозка, заморозка, упаковка, изготовление бензина и пластика из газа).
У хорошего продукта есть некие признаки того что он качественный. У разных продуктов это разные признаки. Например хорошие фрукты вкусно пахнут, хорошо выглядят, имеют хороший вкус.
Сейчас я приведу гиперболизированный пример, и позже перейду непосредственно к коду.
Представьте что у нас есть магазин фруктов и есть проблема, наши фрукты стали хуже продаваться, а у конкурента очереди прям. Мы проводим исследование и узнаём что запах возле наших прилавков не нравится посетителям. А запах у лавок конкурента нравится. О мы нашли проблему, индекс удовлетворённости посетителя запахом! Давайте её решим, есть же аромамаркетинг, просто поставим автоматические установки возле прилавков и получим прекрасный запах яблоневого сада. Сделали. И индекс удовлетворённости покупателя запахом закономерно запахом попёр вверх. Только вот покупателей теперь ещё меньше.
Если взглянуть серьёзно то изначальная проблема могла быть совершенно разной:
На самом деле при появлении такой проблемы нужно комплексно анализировать причины и в каждом конкретном случае принимать специфичное для случая решение.
Ещё более гиперболизировано
У вас есть зелёные помидоры, а вы знаете что продаются только красные. Не надо красить помидоры. Это хорошо, что можно ускорить созревание при помощи этилена. И это будет полноценное созревание, а не покраска. Если бы ускорить было нельзя то нужно было бы выкинуть эти помидоры и добыть новые, уже хорошие.
Иначе говоря, если вы не удовлетворены качеством получающегося продукта, то в цепочке его производства есть неполадки и нужно анализировать и изменять процесс, а не красить на выходе.
Ну вы поняли. Если что-то плохо пахнет, духи не помогут.
В меру абстрактная часть о качестве кода
Среди свойств хорошего кода мы найдём (не сортируя по важности):
Когда какой-либо показатель начинает использоваться как цель, он теряет свою ценность как инструмент.
Вольная трактовка закона Гудхарта.
Теперь проведём аналогию с помидорами. Наш недостаточно созрел. Автоматический линтер скажет нам: «Смотри надо вот тут и тут не нужный цвет». Что сделает программист? Очень часто покрасит. И в этом кроется основная идея моей критики линтеров. Сейчас я приведу конкретный пример, а потом сделаем вывод.
Конкретика
PixiJS 2 февраля 2018 года (год назад).
Прилетает пул реквест. Суть в том, что ранее для рисования кривой использовалось константное количество точек, что очевидно не оптимально. Предложено использовать хитрый алгоритм для оценки длины кривой. Алгоритм не rocket science, но точно не очевидный, опубликован в 2013 году и приведён со ссылкой на статью его автора (наблюдаются проблемы с https). Счастье что он вообще сохранился на личной страничке.
Там приведён код на С (16 строк):
А в пул реквесте прислан следующий код (JS):
Код оформлен в полном соответствии с настройками линтера. Указаны описания всех параметров, ссылка на изначальный алгоритм, куча констов, в соответствии с требованием линтера «no-mixed-operators»: 1 расставлены скобочки. Даже для производительности апи сделано не объектным, а с отдельными параметрами, так действительно обычно лучше в JS.
Есть одна проблема. Этот код делает полную херню. (Попытка калькировать на русском выражение fucked up, которое вполне используется в западных публикациях для выражения степени проблемы и вроде как уместно).
Возвращается огромная длина, и на неё выделяется много точек, хорошо, что там было ограничение сверху, по нему оно и работало. Раньше этот режим был отключен по дефолту, но потом включился для всех (из-за другого бага кстати). Фикс уже вмержили кстати. Я не связывался с автором коммита и не спрашивал его, почему он решил расставить скобки, но чувствую что он запустил линтер, файл конфигурации которого уже есть в PixiJS. Это линтер ему сказал, твой код плох, потому что в нём не хватает скобок, добавь скобки. Опция «no-mixed-operators» говорит что вы не имеете права написать
потому что это может привести к плохой читаемости. Эту опцию кто-то создал, потом кто-то включил в проект, что говорит о том, что многие люди считают её полезной.
Вывод
Я не хочу сказать что линтеры зло, но вот такое применение их я считаю злом. Мы (в смысле человечество) смогли автоматизировать обнаружение только малой части признаков хорошего кода, в основном это косметика типа расставленных скобок. Линтеры хороши как инструменты анализа качества кода, но как только мы возводим соблюдение требований линтера в рамки обязательного требования мы получаем это самое соблюдение требований. Ничего кроме соблюдения требований мы не приобретаем. Это как поставить камеру на конвеер с помидорами и отправлять на покраску все которые недостаточно красные. Пока мы не давали разработчику инструмент оценки качества внешнего вида кода он мог прислать плохой код, и мы могли это увидеть. Теперь плохой код будет лучше замаскирован. Он будет мимикрировать под хороший, потому что все внешние признаки хорошего кода на нём есть. И мы потеряем линтер как инструмент оценки, ведь весь код соответствует. У нас был инструмент оценки, а теперь его нет, зато код со скобочками, правда не там иногда, но это детали. Итого линтеры считаю классным инструментом, но только если соблюдение требований не становится целью.
И да, тут можно сказать что нет тестов, что не нужно копипастить код, что это stackOverflow development, что не вставляйте в проект код который не понимаете. Это всё да. И это и есть признак плохого кода. Но линтер помог сделать его визуально похожим на всё остальное в проекте. Но линтер никогда не проверит, хорошо ли вы поняли то, что написали.
Иначе говоря я считаю что правильное применение линтера это регулярный запуск его на проекте лидом и оценка того как и что идёт. Ну и правила типа больше скобок богу скобок я в принципе считаю вредными. Когда мы видим что кто-то коммитит код плохого качества, то стоит понять почему он это делает и решить эту проблему на более глубоком уровне. Естественно форматировать код руками не нужно, автоформаттеры я всячески приветствую, но до тех пор пока они не трогают смысловую часть кода никак. Если же мы линтером заставим человека привести код к стандартам, то мы по сути покрасим зелёный помидор в красный цвет. И будет ещё сложнее понять что он на самом деле зелёный. Что делать в открытых проектах с кучей разных людей, вопрос сложнее, но и тут можно подумать что делать.
Стоит сказать что моё такое отношение к линтерам сформировалось давно, более трёх лет назад, но я никак не мог найти подходящего примера в практике, когда линтер сыграл злую шутку. И вот я его нашёл. Тот факт, что я искал его столь долго, говорит что проблема не столь масштабна, либо о том, насколько сложно заметить негативный эффект, однако думаю эта заметка будет полезна. Помните, линтер это инструмент, и как любой инструмент его можно применять во вред и во благо, и как с любым инструментом иногда можно порезаться.
Prettier, ESLint, Husky, Lint-Staged и EditorConfig: инструменты для написания аккуратного кода
Вы стремитесь к тому, чтобы писать аккуратный код, но не знаете с чего начать… Вы вчитываетесь в руководства по стилю, вроде этого от Airbnb, стараетесь следовать практическим рекомендациям ведущих специалистов… Вам приходится удалять неиспользуемый код? Приходится искать ненужные переменные? Вы пытаетесь выявлять неудачные паттерны, применённые в ваших программах? Например — хотите понять, читая хитросплетения кода некоей функции, возвратит ли она что-нибудь или нет. Звучит знакомо? Проблема заключается в том, что программисту очень тяжело и многое успевать, и многому учиться.
Может быть вы — тимлид, под началом которого трудится команда разработчиков разного уровня? В вашей команде есть новые люди? Беспокоит ли вас то, что код, который они напишут, не будет соответствовать вашим стандартам? Проходят ли ваши дни в проверках чужого кода, когда эти проверки, в основном, касаются соблюдения стандартов, а не программной логики?
Автор этого материала говорит, что он сталкивался со всем тем, чему посвящены только что заданные вопросы. То, с чем он столкнулся, утомляет и изматывает. Здесь он хочет рассказать об инструментах, правильное применение которых позволяет решить вышеописанные проблемы.
А именно, здесь пойдёт речь о таких средствах как Prettier, ESLint, Husky, Lint-Staged, EditorConfig, об автоматизации форматирования и линтинга кода. Этот материал ориентирован, в основном, на React-разработку, но рассмотренные здесь принципы можно применить в любом веб-проекте. Вот репозиторий, где, кроме прочего, собрано то, о чём тут пойдёт речь.
Prettier
Prettier — это средство для форматирования кода, которое нацелено на использование жёстко заданных правил по оформлению программ. Оно форматирует код автоматически. Вот как это выглядит.
Prettier форматирует код, следуя правилам
▍Сильные стороны Prettier
Вот какие возможности и особенности Prettier позволяют говорить о полезности этого инструмента:
▍Настройка Prettier
Установим пакет prettier в качестве зависимости разработки нашего проекта:
Благодаря этой команде в package.json будет добавлена запись о зависимости разработки, которая выглядит так:
В этот файл внесём следующий код (именно в таком вот неприглядном виде):
Как это исправить? Существует три подхода к работе с плохо отформатированным кодом:
Разберём эти правила:
Вот что произойдёт, если оно установлено в значение false :
Теперь, когда правила настроены, поговорим об этом скрипте:
Запустим скрипт из командной строки:
Вот что стало после этого с показанным выше плохо отформатированным кодом.
Результат форматирования кода с помощью Prettier
На этом будем считать, что с Prettier мы разобрались. Поговорим о линтерах.
ESLint
Линтинг — это вид статического анализа кода, который часто используют для нахождения проблемных паттернов проектирования или кода, который не следует определённым руководствам по стилю.
Существуют линтеры, предназначенные для большинства языков программирования, иногда компиляторы включают линтинг в процесс компиляции кода. Это определение линтинга взято со страницы информации об опенсорсном линтере для JavaScript ESLint, о котором мы и поговорим.
▍Зачем нужен линтер для JavaScript?
Так как JavaScript — это динамический язык программирования со слабой типизацией, код, написанный на нём, подвержен ошибкам, которые допускают разработчики. JavaScript — интерпретируемый язык, поэтому синтаксические и другие ошибки в коде обычно выявляются только после запуска этого кода.
Линтеры, наподобие ESLint, позволяют разработчикам находить проблемы в коде, не запуская его.
▍Почему ESLint — это особенный инструмент?
В заголовок этого раздела вынесен хороший вопрос. Дело тут в том, что ESLint поддерживает плагины. Так, правила проверки кода не должны представлять собой монолитный пакет. Всё, что нужно, можно подключать по мере необходимости. Каждое добавляемое в систему правило линтинга автономно, оно может быть, независимо от других, включено или выключено. Каждому правилу можно назначить уровень оповещения в соответствии с желанием разработчика — это может быть предупреждение (warning) или ошибка (error).
При использовании ESLint вы работаете с полностью настраиваемой системой, способной отразить ваше понимание того, как должен выглядеть правильный код, и зафиксировать то, какого свода правил вы придерживаетесь.
Среди существующих руководств по стилю JavaScript можно отметить следующие, весьма популярные:
Это руководство активно поддерживается — взгляните на его репозиторий на GitHub. Здесь я буду использовать набор правил, основанный именно на нём.
Поэтому обсудим роль представленных здесь пакетов:
Этот файл имеет следующую структуру:
Рассмотрим блоки этого файла, представленные объектами с соответствующими именами:
Здесь заданы три папки:
Запуск скрипта lint
Если выполнить второй скрипт ( yarn lint:write ), то ESLint выполнит такую же проверку, которая была выполнена раньше. Единственное различие заключается в том, что в таком режиме система попытается исправить обнаруженные ошибки, постарается привести код в как можно более пристойный вид.
Расширение ESLint для VS Code
У нас уже есть настроенные Prettier и ESLint, но, чтобы пользоваться возможностями этих инструментов, нам приходится запускать скрипты. Это не очень-то удобно, поэтому попробуем это исправить. А именно, мы хотим добиться того, чтобы форматирование и линтинг кода выполнялись бы по команде сохранения файла в редакторе. Кроме того, выполнять линтинг и форматирование кода мы хотим перед выполнением коммитов.
Рассмотрим его содержимое.
Представьте свои ощущения, если бы к вам попал код проекта размером в 20000 строк, который вам надо было бы проверить и улучшить. А теперь представьте себе, что вам пришлось бы это делать вручную. Такая работа заняла бы, наверное, месяц. А с помощь вышеописанных средств автоматизации всё это делается секунд за тридцать.
Теперь, после настройки всего необходимого, каждый раз, когда вы сохраняете файл с кодом, редактор сам позаботится о проверке и форматировании текста программы. Однако тут мы говорим о редакторе VS Code. Вполне возможно, что кто-то в вашей команде предпочитает какой-нибудь другой редактор. Ничего плохого в этом нет, но, чтобы всем удобно было работать, нам придётся позаниматься ещё кое-что автоматизировать.
Husky
Пакет Husky позволяет задействовать хуки Git. Это означает, что у вас появляется возможность выполнять некие действия перед выполнением коммита или перед отправкой кода репозиторий.
Для того чтобы воспользоваться возможностями Husky, сначала установим этот пакет:
После этого добавим в package.json следующее:
Это приведёт к тому, что перед выполнением команды commit или push будет вызван некий скрипт, который, например, выполняет тестирование кода или его форматирование.
Подробности о Husky можно почитать здесь.
Lint-staged
Пакет Lint-staged позволяет проверять с помощью линтера индексированные файлы, что помогает предотвратить отправку в репозиторий кода с ошибками.
Линтинг имеет смысл проводить до коммита кода. Благодаря этому можно сделать так, чтобы ошибки не проникали в репозиторий, и обеспечить единую стилизацию кода, попадающего туда. Однако выполнение линтинга для проверки всего проекта может оказаться слишком длительной задачей, а результаты такой проверки могут оказаться бессмысленными. В конечном счёте, линтингу может понадобиться подвергнуть файлы, которые планируется закоммитить.
Lint-staged позволяет выполнять набор произвольных задач над индексированными файлами, отфильтрованными по шаблону поиска. Подробности об этом можно почитать здесь.
Установим пакет Lint-staged:
Совместное использование Husky и Lint-staged
Приведём снова, для удобства, содержимое нашего package.json :
Теперь, зная о Husky и Lint-staged, вы можете оценить их влияние на работу с Git. А именно, предположим, что были выполнены следующие команды:
Теперь вы знаете о том, как интегрировать Prettier, ESLint, Husky и Lint-staged в свой проект.
На сайте проекта можно найти список редакторов, которые поддерживают этот файл. В него, в частности, входят WebStorm, AppCode, Atom, Eclipse, Emacs, BBEdit и другие.
Поясним настройки, использованные в этом файле:
Итоги
Полагаем, прочитав этот материал, вы вполне готовы к тому, чтобы создать удобную среду разработки в команде любого масштаба. Инструменты, представленные здесь, помогут вам поддерживать порядок в коде проектов и автоматизировать выполнение рутинных задач.
Уважаемые читатели! Какими инструментами вы пользуетесь для проверки и форматирования кода? Как автоматизируете эти процессы?