Дисклеймер Данная статья будет полезна новичкам и, возможно, старичкам. Эта реализация является чисто субъективной и может вам не понравиться (жду вас в комментах). Для понимания материала требуются базовые навыки работы с React.
Введение
Сейчас мы разберём как настроить линтеры для вашего React проекта, как настроить автоформатирование кода, подсветку ошибок и git хуки. ESLint, Prettier, StyleLint, Husky, Lint-staged, VSCode — все эти технологии будут полезны как в командной, так и в соло разработке.
Git хуки — позволяют запускать кастомные скрипты перед вызовом git команд.
Совокупный результат этих технологий даст нам следующие преимущества:
- Читабельность. Код остаётся чистым и понятным — благодаря форматированию Prettier.
- Меньше мусор-кода. Не используете какую-то переменную, метод или что-то ещё? Линтер накажет и покажет.
- Истребление глупых ошибок. Линтеры могут подсвечивать потенциальные ошибки, что позволит избежать проблем в будущем.
- Защита четвёртой стены. Git хуки не допустят внедрение кода с ошибками в ваш репозиторий.
- Быстрое погружение. При правильной настройке IDE у новичков проекта будет возникать меньше проблем при первом заходе. Для VSCode можно заранее подготовить окружение, настройки, и список рекомендованных и нерекомендованных расширений.
Установка
Подготовка рабочего окружения будет происходить в рамках VSCode и CRA в связке с TypeScript.
Сразу установим необходимые расширения:
- ESLint необходим для подсветки ошибок и работы с описанными правилами.
ESLint — Visual Studio Marketplace - Prettier служит для чтения правил и форматирования кода.
Prettier — Code formatter — Visual Studio Marketplace - StyleLint по аналогии с ESLint, только с фокусом на стили. Так как официальный плагин не поддерживает автоматическое исправление ошибок, то мы установим аналог этого расширения.
stylelint-plus — Visual Studio Marketplace
Если данный пример вам не подходит, и вы не хотите углубляться в теорию и практику настройки, то можно перейти к главе React-third-hand.
Создание проекта:
npx create-react-app my-app --template typescript
# or
yarn create react-app my-app --template typescript
VSCode
Неотъемлемой частью является настройка IDE в случае, если вы работаете в команде или ваш проект может перейти в другие руки. Для этого нам нужно создать папку .vscode в корне с проектом и добавить следующие файлы:
settings.json — настройки VSCode для проекта.
У VSCode есть две области видимости настроек: User (глобальные) и Workspace (для проекта).
Приведу следующий пример настроек:
{
// Форматирование кода с помощью prettier
"editor.defaultFormatter": "esbenp.prettier-vscode",
// Форматирование при сохранении файла
"editor.formatOnSave": true,
// Использование локальных правил для StyleLint
"stylelint.useLocal": true,
"stylelint.autoFixOnSave": true,
// Проверка орфографии с помощью Code Spell Checker
"cSpell.language": "en,ru",
// Дополнительный словарь для Code Spell Checker
"cSpell.words": ["antd", "reduxjs"],
// Использование одной темы в проекте)
"workbench.colorTheme": "One Dark Pro",
// Подсветка комментариев с приставкой TODO
"todohighlight.keywords": [
{
"text": "TODO:",
"color": "white",
"border": "1px solid white",
"backgroundColor": "rgba(46,24,83,0.5)",
"isWholeLine": true
}
],
}
extensions.json — позволяет указывать рекомендованные и нежелательные расширения для проекта. Для добавления вам нужно написать ID плагина, которое вы можете взять через панель расширений, нажав шестеренку.
// extension.json
{
// Рекомендованные расширения
"recommendations": [
"mikestead.dotenv",
"streetsidesoftware.code-spell-checker",
"streetsidesoftware.code-spell-checker-russian",
"dsznajder.es7-react-js-snippets",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
// Нежелательные расширения
"unwantedRecommendations": []
}
Prettier
Основная задача Prettier — форматировать код по заданным правилам.
Базовая настройка
Ранее мы установили расширение и уже можем форматировать код. Для этого нам нужно открыть любой файл, нажать комбинацию клавиш alt + shift + F
.
Для автоформатирования при сохранении нам необходимо сделать следующее:
- Нажать
F1
. - Ввести команду:
>preferences: open settings (json)
. - В открывшемся файле settings.json (глобальные настройки) указать следующие параметры:
// settings.json
{
...
// Форматирование кода с помощью prettier
"editor.defaultFormatter": "esbenp.prettier-vscode",
// Форматирование после сохранения файла
"editor.formatOnSave": true
}
Расширение по умолчанию имеет базовые настройки форматирования, если мы перейдём в него, то увидим большое количество опций, но правильней будет описать их самостоятельно в проекте.
Создадим в корне приложения файл .prettierrc. В проектах RentaTeam мы используем следующие настройки:
// .prettierrc
{
"printWidth": 120,
"tabWidth": 2,
"tabs": false,
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "auto"
}
Более подробно можно прочитать в официальной документации Prettier.
При настройке помощников мы часто будем созвать конфиги. Они являются обычными JSON файлами с поддержкой комментариев. (.prettierrc, .eslintrc, stylelintrc)
Игнорирование правил
Если нужно игнорировать форматирование в определенных файлах, то можно создать файл .prettierignore.
Пример с потолка:
// .prettierignore
// Любая директория с файлом App.tsx
**/App.tsx
.prettierrc
package.json
Также есть возможность отключения форматирования для блока. Для этого в коде нужно добавить комментарий:
// SomeCompoents.tsx
const someText = 'with prettier rules'
// prettier-ignore
const anotherSomeText = "without prettier rules"
// prettier-ignore
export const SomeComponent = () => {
const anotherSomeText = "without prettier rules"
return (
<div>
{ anotherSomeText }
{ someText }
<img alt="logo" />
</div>
);
};
ESLint
Статический анализатор кода, который подсвечивает проблемные места в зависимости от заданных правил.
Важные моменты:
- Для проверки работоспособности ESLInt необходимо нажать сочетание клавиш
ctrl (cmd) + shift + U
, после чего откроется output окно, где нужно выбрать eslint. Если возникнут проблемы при подключении, то они будут отображаться в этом окне. - Также есть необходимость в перезагрузке VSCode, бывает, что при добавлении новых правил, ESLint может их не замечать и необходимо перезапустить рабочее окружение с помощью
F1
и команды>Reload Window
. - Можно увидеть проблемные места в коде
ctrl (cmd) + shift + M
. Только учтите, что ошибки будут подсвечиваться в открытых файлах.
Базовая настройка
Разберём пакеты которые нам необходимы для настройки:
eslint — сам линтер.
eslint-plugin-react — обширный список правил для работы с React. По умолчанию в нём включены некоторые проверки, остальные нужно прописывать в rules. Здесь можно ознакомиться с правилами более подробно.
eslint-plugin-react-hooks — правила для работы с React хуками.
eslint-plugin-jsx-a11y — включает в себя правила для правильного написания HTML тэгов.
@typescript-eslint/parser — анализатор ESLint, который использует TypeScript ESTree, чтобы позволить ESLint анализировать исходный код TypeScript.
@typescript-eslint/eslint-plugin — правила для работы с TypeScript. Полный список правил можно найти на сайте пакета.
Все вышеперечисленные зависимости присутствуют в CRA и их правила прописаны внутри пакета. Конфигурация находится в package.json, давайте удалим её и создадим в корне проекта .eslintrc:
// .eslintrc
{
"extends": ["react-app", "react-app/jest"],
}
Поле extends использует заготовленный файл конфигураций, который применяет набор правил.
Добавим скрипты в package.json для анализа и фикса кода. В дальнейшем они нам понадобятся для настройки прекоммит-хука.
// package.json
"scripts": {
...
"lint:es": "eslint --ext .js,.jsx,.ts,.tsx src",
"lint:es:fix": "npm run lint:es -- --fix"
},
Естественно автофикс скрипт не сможет исправить все ошибки и в большинстве случаев потребуется вносить изменения вручную.
Игнорирование правил
Создаём файл .eslintignore в корне проекта, где указываем файлы/директории для ESLint которые не нужно учитывать.
И снова пример с потолка:
// .eslintignore
**/App.tsx
.prettierrc
package.json
Также у нас есть два варианта игнорирования правила внутри кода:
- Строкой выше относительно ошибки написать комментарий:
/* eslint-disable-next-line название-правила */
- Отключает указанное правило для всего файла:
/* eslint-disable название-правила */
ESLint всегда пишет правило по которому совершена ошибка, наведите на проблемный участок и скопируйте его.
Здесь можно прочитать более подробно
Синхронизация ESLint и Prettier
Eslint подсвечивает ошибки, Prettier форматирует! Это важный момент при работе с помощниками: ESLint имеет собственный форматер, но не во всех ситуациях он может делать правильно и красиво. Prettier vs. Linters · Prettier
Мы можем передать правила Prettier в ESLint, чтобы он подсвечивал проблемные места, связанные с форматированием. Установим зависимости для проекта:
npm i -D prettier eslint-config-prettier eslint-plugin-prettier
# or
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier
prettier — сам форматер.
eslint-config-prettier — отключает правила, которые могут конфликтовать с prettier.
eslint-plugin-prettier — даёт возможность отображать ошибки связанные с правилами prettier.
Получаем следующий код в .eslintrc:
// .eslintrc
{
"extends": ["react-app", "react-app/jest"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": 2
}
}
plugins даёт возможность работать с правилами и настроить их с нуля.
В rules мы описываем правила которые предоставляет нам extends и plugins.
Порядок импортов
Предлагаю настроить порядок импортов, чтобы отделять “наших” от “чужих”. Для этого установим зависимость:
npm i -D eslint-import-resolver-typescript
# or
yarn add -D eslint-import-resolver-typescript
eslint-plugin-import — Данный плагин добавит в ваш проект проверки для импортов и будет следить за тем, чтобы все импортируемые зависимости присутствовали в проекте, подключались в удобном для последующей работы порядке и так далее. Он также входит в CRA.
eslint-import-resolver-typescript — необходим для разрешения абсолютных импортов ts/tsx файлов.
Дополняем .eslintrc файл:
// .eslintrc
{
"extends": ["react-app", "react-app/jest"],
"plugins": ["prettier"],
"settings": {
"import/resolver": {
"typescript": {}
}
},
"rules": {
"prettier/prettier": 2,
"import/order": [
2,
{
"groups": ["external", "builtin", "index", "sibling", "parent", "internal", "type"],
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"newlines-between": "always-and-inside-groups"
}
]
}
}
settings позволяет добавлять дополнительные конфигурации. В него можно внести список плагинов, расширений и языковые настройки.
Данное правило требует группировать импорты и расставлять их в алфавитном порядке. Более подробней о конфигурации.
В шаблоне CRA и Next: абсолютные импорты настраиваются в tsconfig.json или jsconfig.json при помощи параметра baseUrl. Данная опция позволяет импортировать файлы относительно заданной директории.
После установки правил, импорты будут записываться в следующем порядке:
// Из node_modules
import { Menu } from 'antd'
import { FC, useState } from 'react'
import { Link } from 'react-router-dom'
// Относительные
import './styles.scss'
import { getItem } from './data'
// Абсолютные
import { useStoreDispatch } from 'hooks/useStoreDispatch'
import { t } from 'languages'
import { logout } from 'store/profile'
// Типы, интерфейсы, енамы
import type { T_Address, I_Comment, E_Statuses } from 'interfaces/app'
StyleLint
Линтер для стилей, позволяет избежать ошибок и писать код в одной парадигме. Поведение очень схоже с ESLint.
Важные моменты:
- Для проверки работоспособности StyleLint необходимо нажать сочетание клавиш
ctrl (cmd) + shift + U
, после чего откроется output окно, где нужно выбрать StyleLint. Если возникнут проблемы при подключении, то они будут отображаться в этом окне. - Также есть необходимость перезагрузка VSCode, бывает, что при добавление новых правил, StyleLint может их не замечать и необходимо перезапустить рабочее окружение с помощью
F1
и написать команду>Reload Window
. - Можно увидеть проблемные места в коде
ctrl (cmd) + shift + M
. Только учтите, что ошибки будут подсвечиваться в открытых файлах.
Базовая настройка
npm i -D stylelint stylelint-config-standard stylelint-config-clean-order
# or
yarn add -D stylelint stylelint-config-standard stylelint-config-clean-order
stylelint — сам линтер.
stylelint-config-standard — содержит согласованные правила написания стилей.
stylelint-order — отвечает за настройку приоритетов и группировки стилей.
stylelint-config-clean-order — правила для написания стилей в правильном порядке. Если есть желание узнать в каком порядке пишутся стили, то можно посмотреть здесь.
В корне с проектом создадим .stylelintrc:
{
"extends": ["stylelint-config-standard", "stylelint-config-clean-order"],
"plugins": ["stylelint-order"],
"rules": {
"no-empty-source": null,
"declaration-empty-line-before": null,
"no-missing-end-of-source-newline": null,
"selector-class-pattern": null,
"keyframes-name-pattern": null
}
}
Ранее мы установили плагин для StyleLint и теперь потребуется дописать пару настроек для VSCode. Советую прописать их как для проекта так и глобально, чтобы новые разработчики не задавали лишние вопросы.
// settings.json
{
// Использование локальных правил Stylelint
"stylelint.useLocal": true,
// Форматирование при сохранении файла
"stylelint.autoFixOnSave": true,
}
После всех этих настроек в файлах css будут подсвечиваться ошибки и при возможности он будет их исправлять.
Не забываем создать скрипты для StyleLint.
"scripts": {
...
"lint:css": "stylelint src",
"lint:css:fix": "npm run lint:css -- --fix"
},
Автофикс скрипт не сможет исправить все проблемные места и в большинстве случаев потребуется вносить изменения вручную.
Игнорирование правил
StyleLint любит лезть куда не надо, так что перейдём к важной настройке игнорирования.
Создадим файл .stylelintignore в корне проекта:
*.tsx
*.jsx
*.ts
*.js
*.md
*.svg
/node_modules
- Строкой выше, относительно ошибки написать комментарий:
/* stylelint-disable-next-line название-правила */
- Отключает указанное правило для всего файла:
/* stylelint-disable название-правила */
Название правила высвечивается при наведении на проблемный участок кода.
Синхронизация StyleLint и Prettier
Чтобы StyleLint и Prettier не конфликтовали, нам нужно установить зависимость:
npm i -D stylelint-config-prettier
# or
yarn add -D stylelint-config-prettier
stylelint-config-prettier — отключает все правила, которые могут конфликтовать с Prettier.
Добавим "stylelint-config-prettier"
правила в поле extends:
// .stylelintrc
{
"extends": [
"stylelint-config-standard",
"stylelint-config-clean-order",
"stylelint-config-prettier"
],
...
}
Теперь эта парочка не будет сориться, исправлять некоторые ошибки и форматировать код.
Синхронизация StyleLint и SCSS/SASS
Для поддержки SCSS/SASS кода установим зависимость:
npm i -D stylelint-config-standard-scss
# or
yarn add -D stylelint-config-standard-scss
stylelint-config-standard-scss — расширяется от пакета stylelint-config-standard и также содержит согласованные правила.
В .stylelintrc заменим в поле extends stylelint-config-standard
на stylelint-config-standard-scss
:
// .stylelintrc
{
"extends": [
"stylelint-config-standard-scss",
"stylelint-config-clean-order",
"stylelint-config-prettier"
],
...
}
Синхронизация StyleLint и Styled Components
У этой связки не всё так сладко — автофикс не работает, только подсветка ошибок Следовательно, удаляем скрипт фикса в package.json и .stylelintignore нам не понадобится.
Устанавливаем зависимости и разберём пакеты:
npm i -D stylelint-config-styled-components stylelint-processor-styled-components
# or
yarn add -D stylelint-config-styled-components stylelint-processor-styled-components
stylelint-config-styled-components — эта общая конфигурация автоматически отключит правила, вызывающие неразрешимые конфликты.
stylelint-processor-styled-components — пакет для настройки парсера StyleLint, который будет автоматически определять стилизованные компоненты.
В результате получаем следующий .stylelintrc:
// .stylelintrc
{
"processors": [
[
"stylelint-processor-styled-components",
{
"moduleName": "styled-components",
"importName": "default",
"strict": false,
"ignoreFiles": [],
"parserPlugins": [
"jsx",
["decorators", { "decoratorsBeforeExport": true }],
"classProperties",
"exportExtensions",
"functionBind",
"functionSent"
]
}
]
],
"extends": [
"stylelint-config-styled-components",
"stylelint-config-standard",
"stylelint-config-clean-order",
"stylelint-config-prettier"
],
"plugins": ["stylelint-order"]
}
Husky и Lint-Staged
Husky — позволяет запускать собственные сценарии при работе с git.
Lint-Staged — поможет предотвратить коммит, если в индексированных файлах были найдены ошибки.
Базовая настройка
Запустим скрипт для настройки:
npx husky-init && npm install
# or
npx husky-init && yarn
Подробнее об установке можно прочитать на официальном сайте Husky.
И добавим скрипт для прекоммит-хука, в корневой папке .husky, pre-commit и заменим npm test
на npx lint-staged
.
Теперь перед коммитом будут выполняться проверки линтера и если кто-то из них вернёт ошибку, то потребуется её исправить и снова проиндексировать изменения.
React-third-hand
Небольшая кульминация в рамках этой статьи — npm пакет, который позволяет настраивать рабочее окружение с помощью вышеописанных технологий для React-приложения. Включает в себя установку необходимых зависимостей, создание файлов и модификацию имеющихся. Его использование будет уместно на любом этапе разработки.
react-third-hand — npm (npmjs.com)
Выбираете тип своего приложения, пакетный менеджер, язык программирования, помощников и вид стилизации.
Пакет является моим самописом и я буду признателен любому вашему пул реквесту для поддержки проекта.
Бонус
Подборка расширений
В моём VSCode арсенале, помимо ESLint, Prettier и StyleLint, есть ещё несколько интересных плагинов и полезных практик.
Дальнейшие настройки вы можете выполнять как глобально, так и для проекта.
Code Spell Checker
Code Spell Checker — проверяет орфографию в коде, выдаёт список правильного написания и позволяет расширять словарь.
Russian — Code Spell Checker — дополнение основного расширения для поддержки русского языка.
// settings.json
{
...
"cSpell.language": "en,ru",
"cSpell.userWords": [
"backface",
"eslintignore",
"fontawesome",
"ical",
"nestjs",
"persistor",
"prettierrc",
"stylelint",
"stylelintignore",
"todohighlight",
"stylelintrc",
"Vite",
"websockets",
]
}
ToDo Highlight
TODO Hightlight — подсвечивает ключевые слова в комментариях.
// settings.json
{
...
"todohighlight.keywords": [
{
"text": "TODO:",
"color": "white",
"border": "1px solid white",
"backgroundColor": "orange"
},
{
"text": "NOTE:",
"color": "white",
"border": "1px solid white",
"backgroundColor": "purple"
},
{
"text": "BUG:",
"color": "white",
"border": "1px solid white",
"backgroundColor": "red"
}
],
}
Получим следующее:
Notes
Notes — удобное расширение для заметок в .md формате.
Thunder Client
Thunder Client — хорошая альтернатива Postman. Служит для отправки запросов с разными параметрами и также есть возможность коллекционирования.
VSCode Icons
VSCode Icons — набор иконок для файлов.
Минутка эстетики:
// settings.json
{
...
"vsicons.associations.folders": [
{ "icon": "redux", "extensions": ["store"] },
{ "icon": "route", "extensions": ["routing"] }
]
}
Для более удобного ориентирования в окружении, я задаю директориям определённые иконки. Полный список поддерживаемых иконок для файлов и для папок.
One Dark Pro
Моя любимая тема и также пара настроек для неё:
// settings.json
{
...
"workbench.colorTheme": "One Dark Pro",
"oneDarkPro.italic": false,
// Выделяет методы
"oneDarkPro.bold": true
}
Настройки VSCode
Fira Code
Fira Code — популярный набор лигатур. Плюс к внешнему виду и читаемости.
Устанавливаем шрифты и настраиваем VSCode:
// settings.json
{
...
"editor.fontFamily": "Fira Code, Consolas, 'Courier New', monospace",
"editor.fontLigatures": true
}
Inlay Hints
Приятное нововведение в VSCode, которое сразу отображает динамические типы у разных конструкций.
Выглядит следующим образом:
Для её активации, необходимо:
- Перейти в настройки VSCode
ctrl (cmd) + ,
. - Ввести в поиске
Inlay Hints
. - Выбрать необходимые опции.
Мои настройки:
// settings.json
{
...
"javascript.inlayHints.enumMemberValues.enabled": true,
"javascript.inlayHints.functionLikeReturnTypes.enabled": true,
"javascript.inlayHints.parameterNames.enabled": "all",
"javascript.inlayHints.parameterTypes.enabled": true,
"javascript.inlayHints.propertyDeclarationTypes.enabled": true,
"javascript.inlayHints.variableTypes.enabled": true,
"typescript.inlayHints.enumMemberValues.enabled": true,
"typescript.inlayHints.parameterTypes.enabled": true,
"typescript.inlayHints.propertyDeclarationTypes.enabled": true,
// Превью предложения
"editor.suggest.preview": true,
}
File Nesting
Группировка файлов в один. Может быть полезно для массивно повторяющейся файловой структуры.
Например, скроем все наши конфиги под package.json.
Для этого пропишем настройки:
// settings.json
{
...
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"package.json": "package-lock.json, yarn.lock, .stylelintrc, .stylelintignore, .eslintrc, .eslintignore, .prettierrc",
"styles.ts": "variants.ts, keyframes.ts",
"index.tsx": "data.ts, utils.ts, data.tsx",
"index.ts": "data.ts, utils.ts, data.tsx, interfaces.ts"
},
}
Заключение
Технологии, которые я привёл в этой статье, должны сопровождать, помогать и бить вас по рукам. Они могут работать независимо друг от друга, но для эффективной работы стоит использовать их в совокупности.
Любой программист, по мере своего развития, должен стремиться к более чистому, более правильному написанию кода, а эти инструменты помогут вам в этом.