ESLint и Prettier

Кратко о библиотеках:

ESLint

Линтер - это помощник по части "здоровья" кода. Вы определяете список правил и в дальнейшем, при настроенном плагине в вашем редакторе, он как Microsoft Word "проферка орфографии" проверяет все, что вы написали.

Например, определили переменную, но нигде не используете? Сработает правило: no-unused-vars (долой неиспользуемые переменные) и переменная будет подчеркнута.

Когда вы видите "подчеркивание", и после наведения видите в скобочках название правила - не нужно бежать гуглить. Нужно идти на сайт eslint.org и там в "поиск" вставлять текст ошибки, будет быстрее.

Prettier

Преттир - это помощник по части оформления кода. Можно писать с пробелами перед именем свойства, кавычками, запятыми в последней строке и тд тп - преттир, настроенный на сохранение или на пре-коммит хук - "перетрясет" ваши файлы и оформит их в соответствии с настройками, которых у него минимум. Это сделано специально, ибо чем меньше настроек, тем меньше конфигураций - когда-нибудь, спор "табы vs пробелы" уйдет в небытие, но кто выиграет?)

Одна из работ "преттира" - форматировать длинные строки.

Было:

Стало:

Я думаю преимущества очевидны, поэтому давайте настроим необходимые ускорители повседневной разработки.

Настройка

Линтер встроен в create-react-app, но для работы в связке с Prettier, а так же для подсветки кода во время написания в VS Code нужна небольшая донастройка.

Для начала установите пакеты:

npm install eslint-config-prettier eslint-plugin-prettier prettier lint-staged husky --save-dev

Все пакеты в целом понятны зачем, кроме lint-staged и husky

  • husky - упрощает работу с git hooks ("пре-коммит" (момент, когда вы собираетесь делать коммит) легко настроить с помощью этой "собаки")

  • lint-staged - пакет, который позволяет вам сделать обработку командой из терминала только тех файлов, которые собираются улететь в коммит.

Husky и lint-staged - сладкая парочка для борьбы с плохим кодом в нашем репозитории. Например, мы можем настроить, что если ESLint вернул ошибку, то коммит будет автоматически отменен. Вернемся к этому позже.

Итак, настройка eslint, создайте следующий файл в корне проекта:

.eslintrc

{
  "extends": [
    "react-app",
    "prettier"
  ],
  "rules": {
    "jsx-quotes": [
      1,
      "prefer-double"
    ]
  },
  "plugins": [
    "prettier"
  ]
}

Достаточно скромный конфиг, который "наследует" стандартные правила (их много) из react-app и prettier (это глобальные конфиги, один встроен в create-react-app, второй мы установили посредством пакета eslint-config-prettier)

Затем я переопределил одно правило: jsx-quotes (для имен классов внутри JSX будут ставиться двойные кавычки. Не могу сказать, насколько это важно на сегодняшний день, но раньше у меня были конфликты с преттиром без этого правила).

Вы можете переопределить в списке любые правила, которые вас интересуют. Список можно найти в документации, но проще просто начать работать и по ходу пьесы смотреть на "подчеркивания". Те, которые вас не устраивают - переопределяйте.

Последняя опция в конфиге - использование плагинов. Мы используем плагин prettier (пакет eslint-plugin-prettier), чтобы не было конфликтов между "помощниками" (напоминаю, у нас их два: prettier и eslint).

После настройки конфига, вам нужно настроить ваш редактор. Я приведу пример только для Visual Studio Code.

Добавьте в файл с настройками, следующие строки:

"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"[javascript]": {
    "editor.formatOnSave": true,
},
"[html]": {
    "editor.formatOnSave": false,
},
"[json]": {
    "editor.formatOnSave": false,
},
"eslint.autoFixOnSave": true,
"eslint.alwaysShowStatus": true,

Напоследок, для корректной работы вам потребуется парочка плагинов из маркет-плейса (eslint и prettier).

Мой список плагинов:

Конфиг может быть настроен различными способами, например, взгляните на эти два видео:

Настроим prettier (нам так же нужен конфигурационный файл):

.prettierrc

{
  "useTabs": false, // использовать табы? нет (я за пробелы)
  "printWidth": 80, // длина строки - 80
  "tabWidth": 2, // длина "таба" - 2 пробела
  "singleQuote": true, // использовать одинарные кавычки - да!
  "trailingComma": "es5", // запятая в последней строке - да
  "jsxBracketSameLine": false, // закрывающийся jsx в этой же строке
  "parser": "flow", // парсер - flow (пока не важно)
  "semi": false // точка с запятой - нет
}

Вот и все настройки. Настройка - parser, вам пока не должна мешать, а что такое trailingComma - пример ниже:

const data = {
  name: 'Max',
  city: 'Moscow, // <-- traling comma ("висячая запятая")
}

Почему так? Мне это нравится, так как если добавится новое свойство, в git difference (изменения в файле) будет только одна строка, вместо двух (в одной добавилась бы запятая, во второй - новое свойство).

На данный момент, если вы будете писать код, у вас уже будет отрабатывать eslint. Так же в момент сохранения, код будет преобразовываться с помощью prettier. Однако, нам еще не хватает настройки пре-коммит хука.

Представьте ситуацию: вы работает с коллегой. Он пишет в блокноте, у него нет никаких "преттиров". Следовательно, чтобы он не закоммитил код, который не отформатирован как вам нужно, мы настраиваем пре-коммит хук. Это значит, в момент коммита, весь js/jsx/json код из директории src, который он "коммитит" будет преобразован преттиром, так же, как если бы он преобразовался при сохранении в вашем редакторе.

package.json

{
  "name": "redux-course-ru-v2",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "precommit": "lint-staged"
  },
  "devDependencies": {
    "eslint-config-prettier": "^2.9.0",
    "eslint-plugin-prettier": "^2.6.2",
    "husky": "^0.14.3",
    "lint-staged": "^7.2.0",
    "prettier": "^1.14.0"
  },
  "lint-staged": {
    "*.{js, jsx}": [
      "prettier --write",
      "git add"
    ]
  }
}

В секции scripts добавилась команда precommit, и добавилось свойство lint-staged с настройками.

Теперь в момент коммита, в терминале будет похожая ситуация:

Резонный вопрос, у коллеги с блокнотом, у него и ESLint отсутствует же? Верно. Нужно усложнить ему жизнь и "обламывать" коммит, если в нем есть ошибки/предупреждения от ESLint.

Удалите <TestComponent /> из отрисовки в <App />, но оставьте создание переменной.

src/App.js

import React, { Component } from 'react'
import './App.css'

const TestComponent = () => <p>просто render</p>

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    )
  }
}

export default App

Выполните команду в терминале (находясь в директории с проектом):

node_modules/.bin/eslint src/

Так как я не люблю глобальные зависимости, я использую локально установленный eslint (его установил для нас create-react-app). Чтобы упростить вызов в терминале, можно добавить в секцию scripts в package.json новую команду:

package.json

...
"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject",
  "precommit": "lint-staged",
  "eslint": "node_modules/.bin/eslint src/"
},
...

Теперь eslint в терминале можно запускать так: npm run eslint. После запуска этой команды, eslint проверит весь src/ на наличие ошибок/предупреждений. Это полезно сделать в начале внедрения "жесткого пре-коммита" и лично исправить все ошибки, чтобы команда научилась на хорошем примере.

Вернемся к настройке. Изменим lint-stage скрипт в package.json на:

"lint-staged": {
  "*.{js, jsx}": [
    "node_modules/.bin/eslint --max-warnings=0",
    "prettier --write",
    "git add"
  ]
}

Теперь в момент пре-коммита будет запускаться lint-staged проверка в которой eslint и prettier обработают все файлы, готовящиеся к коммиту.

Что интересно, я настроил еслинт агрессивно (опция --max-warnings=0), то есть, даже любое предупреждение прервет коммит.

Проверим:

На скрине видно "вредный совет". Да, если добавить --no-verify к команде git commit, то проверок не будет. Но за это сразу бейте по рукам.

Итого: Настроили ESLint, prettier и pre-commit hook. Очень сильно облегчили жизнь себе и коллегам, кто болеет за единый стиль и чистый код.

Исходный код (без ошибок).

Last updated