Эта статья была рецензирована Тимом Севериеном . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!
Вам знакомо слово «линтинг»? Это процесс использования инструмента для автоматической проверки вашего кода на наличие потенциальных проблем. Есть несколько ключевых преимуществ, которые вы можете получить от использования такого инструмента.
- Сохранение вашего стиля кода согласованным. Линтеры позволяют вам проверять стиль кода на наличие проблем, таких как интервалы, отступы и размещение фигурных скобок. Как только ваша команда согласится со стилем кодирования, это может быть задокументировано в файле конфигурации и проверено автоматически.
- Обнаружение потенциальных ошибок и плохих моделей. Линтеры также могут быть использованы для выполнения более сложных проверок, чтобы обнаружить возможные ошибки, такие как повторяющиеся переменные, недоступный код или недопустимые регулярные выражения. Предупреждение от линтера позволит вам исправить ошибки еще до того, как они достигнут времени выполнения.
- Обеспечение качества. Когда вы следуете определенному руководству по стилю в своем проекте, важно применять его с помощью инструментов, в противном случае всегда найдутся люди, соблазненные срезать углы. Если в процесс сборки встроен инструмент для рисования, вы можете просто запретить запуск или фиксацию проекта в вашем хранилище, если есть нефиксированные ошибки.
- Экономия времени Основное преимущество предыдущих трех заключается в том, что линтеры экономят ваши усилия во время разработки. Вам больше не нужно тратить драгоценное время на споры с коллегами о неуместной скобке, и вы можете обнаружить одну или две ошибки на ранних стадиях.
Уже была статья о доступных линтерах для JavaScript, но сегодня мы сосредоточимся на одном из инструментов, упомянутых автором — ESLint.
ESLint
ESLint — это инструмент для рисования, созданный еще в 2013 году Николасом К. Закасом, и в настоящее время он является самым мощным и расширяемым линтером, доступным для JavaScript. Он предоставляет богатый набор функций, которые делают его идеальным выбором для вашего следующего инструмента для подкладки. Эти функции включают в себя:
- Множество правил, которые можно дополнительно настроить на свой вкус.
- API для создания ваших собственных правил.
- Многочисленные плагины с правилами для конкретных библиотек, фреймворков и практик.
- Встроенная поддержка ES6, ES7 и JSX.
- Рекомендуемый набор правил, а также сторонние конфигурации, доступные для быстрого начала работы.
- Может быть интегрирован с несколькими редакторами и IDE, такими как Sublime, Vim, продукты JetBrains и Visual Studio Code.
Настройка проекта
Перед тем, как внедрить ESLint в свои собственные существующие проекты, было бы разумно попробовать его на чем-то простом. Давайте создадим тестовый проект, который мы будем использовать как площадку для дальнейших исследований. В нем будет только один файл JavaScript, необходимые модули npm и пара команд npm для запуска linter.
Прежде всего, мы создадим проект npm (если вы не уверены в установке или использовании npm, см. Это руководство ). Создайте новую папку, откройте ее в терминале и запустите npm init
. Вам будет предложено ввести некоторую информацию о вашем проекте, и как только вы ответите на все вопросы, npm создаст новый файл package.json
в той же папке.
Как только мы покончили с npm, нам также понадобится файл JavaScript для линтинга. Давайте создадим scripts.js
именем scripts.js
и сохраним там немного кода:
function doGood() { var message = "doing good!"; var message = 'or am i?'; console.log("doing something");; var toDoList = ["List",,'things',"to do"]; }
Вам не нужен линтер, чтобы уже определить некоторые проблемы в коде. Но мы не хотим слышать это от вас или от меня, а от самой ESLint.
Установка и настройка
Для установки ESLint все, что вам нужно сделать, это запустить npm i eslint --save-dev
изнутри папки вашего проекта. Мы могли бы установить ESLint глобально, но я твердо убежден, что каждый проект должен связывать свои собственные зависимости, чтобы каждый разработчик, работающий над проектом, использовал одни и те же инструменты.
После установки ESLint нам необходимо настроить его перед первым запуском. Это удобно сделать, запустив ESLint с флагом --init
. Поскольку ESLint не установлен глобально, команда будет выглядеть следующим образом:
./node_modules/.bin/eslint --init
Эта команда запустит мастер настройки. Мастер предложит вам три способа создания конфигурации:
- Выбор ответа на вопросы о вашем стиле потребует от вас ответа на некоторые вопросы о настройке вашего проекта, например, на какую среду вы нацеливаетесь, версию ECMAScript, модули, использование CommonJS или JSX и некоторые предпочтения стиля. Это быстрый способ настроить проект с минимальным набором рекомендуемых правил.
- Выбор « Использовать руководство по популярным стилям» позволит вам основывать свою конфигурацию на одном из популярных руководств по стилям от Google, Airbnb и других. Этот вариант хорошо работает, если вы уже используете его или планируете использовать один из этих стилей
- Проверьте, что ваш файл (ы) JavaScript попытается вывести правила линтинга из существующей кодовой базы. Хорошо работает, когда у вас уже есть существующая кодовая база, которую вы не захотите менять.
Поскольку мы только начинаем с новым проектом, давайте выберем первый вариант и подпишемся на новейшие функции ECMAScript:
Последний вопрос позволит вам выбрать формат файла конфигурации. Возможные варианты: JSON, YAML и JavaScript, но мы пойдем с JSON, так как он, вероятно, наиболее знаком всем.
После того, как вы ответите на все вопросы, ESLint создаст файл .eslint.json
со следующим содержимым:
{ "env": { "browser": true, "es6": true }, "extends": "eslint:recommended", "parserOptions": { "sourceType": "module" }, "rules": { "indent": [ "error", 4 ], "linebreak-style": [ "error", "unix" ], "quotes": [ "error", "single" ], "semi": [ "error", "always" ] } }
Как видите, он содержит некоторую конфигурацию среды, а также правила, о которых он вас спрашивал. Для свойства extends
установлено значение eslint:recommended
что означает, что ESLint будет использовать собственный набор рекомендуемых правил в качестве основы, которую вы можете позже переопределить. Мы оставим все как есть для демонстрационных целей, но позже вы можете либо удалить его, либо заменить его другим набором правил сторонних производителей.
Запуск ESLint
Теперь, когда у нас есть базовая конфигурация, давайте попробуем запустить ее и посмотреть, работает ли она.
Для запуска ESLint мы можем использовать следующую команду, которая соберет все файлы .js
в корневой папке проекта:
./node_modules/.bin/eslint *.js
Чтобы не вводить это повторно в терминал, мы можем сохранить его как скрипт npm. Откройте package.json
и добавьте еще один скрипт рядом с test
.
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "lint": "eslint *.js" },
Обратите внимание, что нам не нужно ./node_modules/.bin
полный путь к ./node_modules/.bin
поскольку при запуске скриптов npm эта папка автоматически добавляется в PATH.
Мы можем запустить его сейчас, используя
npm run lint
Иди и попробуй. Вы должны увидеть сообщение об ошибках, предупреждающее нас обо всех видах проблем в scripts.js
:
Не беспокойтесь, когда сам скрипт узла сообщает об ошибке, это должно произойти, поскольку ESLint вернул ненулевой код завершения. При необходимости это можно подавить, добавив exit 0
в скрипт (как обсуждено здесь ).
Только некоторые из правил включены в рекомендуемом наборе. Там их гораздо больше.
Обзор правил
ESLint имеет более ста правил в своем арсенале. Мы не будем проходить через все из них, так как список действительно значительный. Мы просто проведем вас через некоторые из наиболее распространенных, чтобы дать вам представление о том, на что способен ESLint.
Вы можете включить любое из этих правил, перечислив его в свойстве rules
в файле конфигурации. Каждому правилу может быть присвоено определенное значение: 0
(или off
), чтобы отключить правило, 1
или ( warn
), чтобы выдать предупреждение, и 2
(или error
), чтобы вызвать ошибку. Некоторые правила, такие как правила в нашем файле конфигурации, могут принимать массив с серьезностью в качестве первого элемента, за которым следуют дополнительные параметры. Обратитесь к документации, если вы не уверены, какие значения поддерживает конкретное правило.
Стилистические правила
Некоторые из правил довольно тривиальны и служат только для обеспечения определенного стиля кода:
- block-spacing — обеспечивает пробелы внутри блоков кода
{ ... }
; - запятая — требует или запрещает висячие запятые в массивах или объектах;
- eol-last — вводит новую строку в конце каждого файла.
Как правило, не имеет значения, как вы настраиваете эти правила, если с ними согласна вся команда.
Лучшие практики
Существует ряд правил, которые охватывают руководящие принципы, которые, как считается, улучшают исходный код и приветствуются в сообществе разработчиков. Некоторые из интересных упоминаний:
- сложность — максимально допустимый порог цикломатической сложности в ваших источниках;
- default-case — всегда требовать блока по
default
в ваших операторахswitch
; - eqeqeq — требует использования операторов строгого сравнения:
===
и!==
; - no-implicit-coercion — запрещает неявные методы преобразования типов, такие как
!!false
или+'2'
; - no-magic-numbers — запрещает использование «магических чисел»: чисел, которые появляются в коде, но не имеют связанных идентификаторов;
- йода — требует или запрещает выписывать условия «йода»;
- no-shadow — запрещает « теневые » переменные: объявляет переменные с тем же именем, что и существующая переменная в родительской области.
Хотя некоторые из этих правил могут иметь исключения в определенных случаях, они обычно считаются полезными и рекомендуются к рассмотрению.
Потенциальные ошибки
Другой набор правил помогает избежать написания слишком сложного кода, который может привести к ошибкам. Конечно, это не может гарантировать, что в вашем приложении нет ошибок или логических недостатков, но это, по крайней мере, поможет вам избежать распространенных ошибок. Вот некоторые примеры:
- no-cond-assign — запрещает присваивания в условных выражениях;
- no-dupe-args — запрещает дублирование аргументов в объявлениях функций;
- no-inner-декларации — запрещает объявление переменных функции ar во вложенных блоках;
- no-invalid-regexp — проверяет правильность ваших регулярных выражений;
- no-unreachable — проверяет, есть ли какой-либо недоступный код после операторов
return
,throw
,continue
илиbreak
.
ECMAScript 6
Существует еще один набор правил, состоящий из проверок, специфичных для стандарта ECMAScript 6. Если вы предпочитаете использовать новейшие функции, вы можете найти их интересными. Вот несколько примеров:
- constructor-super — требует вызовов
super()
в конструкторах; - no-dupe-class-members — проверяет наличие дублированных членов класса;
- no-var — требует
let
илиconst
вместоvar
.
Есть много других правил для изучения, поэтому мы рекомендуем вам ознакомиться с полным списком самостоятельно после того, как вы закончите с этой статьей.
Работает в разных средах
Когда мы изначально настраивали ESLint, мы ожидали, что наш код будет выполняться в браузере. Но предположим, что мы хотим использовать его и в среде Node.js. Например, мы хотели бы использовать функцию Node’s module.exports
, добавив следующий фрагмент кода в наш пример:
if (module && module.exports) { module.exports = doGood; }
Повторный запуск линтера вызовет появление новых ошибок:
10:5 error 'module' is not defined no-undef 10:15 error 'module' is not defined no-undef 11:5 error 'module' is not defined no-undef
Это происходит потому, что линтер не ожидает появления в коде специфичных для узла переменных. Чтобы это исправить, мы можем проинструктировать его, чтобы он знал о среде Node:
"env": { "browser": true, "es6": true, "node": true },
Если вы снова запустите линтер, он будет работать как шарм. Есть также небольшой набор правил, специфичных для среды Node .
Комментарии к конфигурации
Иногда необходимо переопределить конфигурацию изнутри исходного кода. Это может случиться в разных случаях. Например, если ваш код содержит копию сторонней библиотеки, которая не соответствует вашим стандартам кодирования. Или у вас есть определенный фрагмент кода, который должен быть исключением из общих правил. Вы можете добиться этого, используя специальные комментарии в исходном коде.
Представьте, что мы хотим отключить правило no-sparse-arrays
в нашей функции. Мы можем сделать это, добавив следующий комментарий к этой строке:
var toDoList = ["List",,"things","to do"]; // eslint-disable-line no-sparse-arrays
Если мы хотим подавить все ошибки для нашей функции, мы можем eslint-disable/eslint-enable
ее в блок eslint-disable/eslint-enable
.
/* eslint-disable */ function doGood() { var message = "doing good!"; var message = "or am i?"; console.log("doing something"); var toDoList = ["List",,"things","to do"]; // eslint-disable-line no-sparse-arrays } /* eslint-enable */
Или, чтобы отключить linting для всего файла, мы можем просто добавить один /* eslint-disable */
комментарий в начале файла.
Хотя для такого переопределения есть веские случаи, не позволяйте исключениям стать нормой. Вы все еще должны стремиться исправить ошибки, а не подавлять их.
Автоматическое исправление ошибок
ESLint обладает интересной способностью автоматически исправлять некоторые обнаруженные ошибки. Правила, которые могут автоматически исправить код, отмечены значком гаечного ключа в общем списке правил . На данный момент большинство этих правил носит чисто стилистический характер. Давайте попробуем запустить наш первоначальный пример через автокоррекцию. Для этого добавьте флаг --fix
к команде, которую мы использовали для запуска ESLint:
./node_modules/.bin/eslint *.js --fix
Вот как будет выглядеть наш пример после исправления некоторых ошибок:
function doGood() { var message = 'doing good!'; var message = 'or am i?'; console.log('doing something'); var toDoList = ['List',,'things','to do']; }
Как видите, он успешно изменил все кавычки на одинарные и удалил лишнюю точку с запятой. Это полезная функция, однако будьте осторожны с ней. В некоторых случаях было известно, что это нарушает форматирование кода. Всегда проверяйте внесенные изменения перед их фиксацией.
Создание пользовательских правил
Если вы чувствуете, что доступные встроенные и сторонние правила не покрывают все ваши потребности, вы можете написать свои собственные. ESLint предоставляет API, который позволяет создавать собственные правила. Этот предмет более технический, требует более глубокого знания JavaScript, Node, базового понимания синтаксических анализаторов и поэтому заслуживает отдельной статьи. Общая идея состоит в том, что каждое правило содержит две вещи: метаинформацию, такую как имя и описание, и фактическую реализацию. Правило реализовано в виде объекта, содержащего набор обратных вызовов, которые вызываются, пока ESLint перебирает абстрактное синтаксическое дерево вашего кода JavaScript, предоставляя доступ к текущему узлу. По сути, это реализация шаблона «посетитель». Руководство разработчика ESLint содержит более подробную информацию, а также примеры того, как реализовать свои собственные правила.
В заключение
Надеюсь, что эта статья дала вам представление о том, как просто настроить ESLint в вашем проекте и насколько он может улучшить ваш рабочий процесс. Если вы понимаете необходимость этого в своем проекте, я предлагаю вам попробовать как можно скорее. Чем раньше вы примете этот инструмент, тем большую выгоду вы получите. Начните медленно с рекомендуемого набора правил и развивайтесь, настраивая правила для вашего конкретного рабочего процесса. Через некоторое время ESLint должен стать вашим надежным партнером и неотъемлемой частью любого проекта.
Вы используете ESLint? Если нет, вы бы хотели попробовать? Позвольте мне знать в комментариях ниже.