Как подготовить окружение для 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" }, }
Заключение
Технологии, которые я привёл в этой статье, должны сопровождать, помогать и бить вас по рукам. Они могут работать независимо друг от друга, но для эффективной работы стоит использовать их в совокупности.
Любой программист, по мере своего развития, должен стремиться к более чистому, более правильному написанию кода, а эти инструменты помогут вам в этом.