Комбинация ESLint и Prettier не только значительно сокращает время форматирования, но и снижает нагрузку на процессор компьютера. Кроме того, если вы работаете в команде, тандем этих инструментов позволяет избежать стресса при проверке кода.
Обычно можно настроить ESLint и Prettier на основе пресетов, таких как Airbnb, Google и Standard. Но если эти пресеты не подходят для вашего проекта, не расстраивайтесь: у вас все еще есть возможности для оптимизации.
Вот 7 рекомендуемых конфигураций ESLint, которые значительно улучшат ваш проект TypeScript/React.
1. arrow-body-style
Очень простое правило arrow-body-style способно устранить множество проблем при написании кода. Рекомендуемая его настройка — "arrow-body-style": ["error", "as-needed"]
— приводит к удалению ненужного возврата, как показано ниже.
// "arrow-body-style": ["error", "as-needed"], // Неверно let foo = () => { return 0; }; // Верно let foo = () => 0
2. react/self-closing-comp
Правило react/self-closing-comp схоже с arrow-body-style. Несмотря на свою простоту, оно существенно экономит время, выполняя автоматическое закрытие тегов в JSX.
Рекомендуемая настройка — react/self-closing-comp: ["error", { "component": true, "html": true }]
.
// "react/self-closing-comp": [ // "error", { // "component": true, // "html": true // } // ] // Неверно <Hello name="John"></Hello>; <div className="content"></div>; // Верно <Hello name="John" /> <div className="content" />
"component": true
приводит к написанию пользовательского компонента с автоматически закрывающимся тегом. Кроме того, "html": true
изменяет обычный html-тег на самозакрывающийся.
3. autofix/no-unused-vars
Это производное из ESLint-правила no-unused-vars. Поскольку оригинальная настройка no-unused-vars не производит форматирование автоматически, стоит использовать eslint-plugin-autofix.
$ yarn add -D eslint-plugin-autofix
После этого добавьте его как плагин ESLint.
{
"plugins": ["react", "@typescript-eslint", "autofix"],
"rules": {
...
}
}
Теперь можно использовать установленное правило no-unused-vars, как показано ниже!
// "autofix/no-unused-vars": [ // "error", // { // "argsIgnorePattern": "^_", // "ignoreRestSiblings": true, // "destructuredArrayIgnorePattern": "^_" // } // ] // Неверно function foo(x, y) { return x + 1; } foo(); var { foo, ...coords } = data; const [a, b] = ["a", "b"]; console.log(b); // Верно function foo(x, _y) { return x + 1; } foo(); var { foo, ...coords } = data; const [_a, b] = ["a", "b"]; console.log(b);
Если просто добавить autofix/no-used-vars: "error"
, то все неиспользуемые переменные покажут ошибку, выданную контролем качества кода. Однако иногда нужно определить неиспользуемые переменные для демонстрации определенных намерений. Поэтому рекомендую использовать argsIgnorePattern: "^_"
. С префиксом _
это разрешено.
ignoreRestSiblings
-опция destructuredArrayIgnorePattern
— это правила, специфичные для каждого конкретного случая.
Иногда ключ удаляется из объекта с применением свойства REST, как показано ниже. В этой ситуации можно больше не использовать удаленный ключ. Игнорировать его позволит ignoreRestSiblings
.
const obj = { first: "John", last: "Lennon", age: 30 }; const { age, ...name } = obj; // remove age from obj // => ошибка ESLint в отношении age не возникает.
Аналогичная ошибка ESLint возникает при деструктурировании массива. В этом случае можно не использовать первый деструктурированный элемент. Предотвратить ошибку ESLint позволит destructuredArrayIgnorePattern: "^_"
.
const [_A, B, C] = Promise.all([fetchA, fetchB, fetchC]); console.log(B, C); // => ошибка ESLint в отношении A не возникает.
4. @typescript-eslint/consistent-type-imports
При импортировании типов TypeScript рекомендуется использовать функцию импорт только для типов для повышения производительности. Но меня волнует правильное использование обычного импорта и только для типов.
import { useEffect } from "react;
import type { FC } from "react;
Поэтому пришло время использовать @typescript-eslint/consistent-type-imports. Это правило автоматически определяет, является ли импортируемый модуль типом или нет, и при необходимости форматирует его.
// "@typescript-eslint/consistent-type-imports": [ // "error", // { // "prefer": "type-imports", // } // ], // Неверно import { useEffect, FC } from "react"; // Верно import { useEffect } from "react"; import type { FC } from "react";
5. import/order
На самом деле правило import/order мне нравится больше всего. Поскольку импортов очень много, организация порядка импорта вручную занимает в общей сложности много времени. Поэтому пришло время использовать автоформат!
// "import/order": [
// "error",
// {
// "groups": [
// "builtin",
// "external",
// "parent",
// "sibling",
// "index",
// "object",
// "type"
// ],
// "pathGroups": [
// {
// "pattern": "@/**/**",
// "group": "parent",
// "position": "before"
// }
// ],
// "alphabetize": { "order": "asc" }
// }
// ],
Само правило довольно сложное. Ключ groups
определяет фактический порядок между типами модулей. Приведенная выше конфигурация располагает узел, встроенный в модули (например, path
), перед внешними пакетами (например, react
). Если хотите узнать подробности о каждой группе, ознакомьтесь с официальной документацией.
pathGroups
создает пользовательскую группу. Я часто определяю ее для импорта псевдонимов.
// импорт псевдонимов
import foo from "../../src/path/to/foo"; // not readable
import foo from "@/src/path/to/foo"; // using import alias
С настройкой pathGroups
модули, использующие импорт псевдонимов, упорядочиваются перед parent
.
alphabetize
означает порядок в одном модуле. react
упорядочивается перед vue
(конечно, так не бывает).
6. no-restricted-imports
Как уже было сказано выше, импорт псевдонимов очень полезен. После введения импорта псевдонимов вам, возможно, понадобится запретить использование относительного импорта. Поэтому пришло время установить no-restricted-imports.
// "no-restricted-imports": [
// "error",
// {
// "patterns": ["../"]
// }
// ],
Это правило ограничивает импорт родительского модуля по относительному пути. С другой стороны, оно позволяет импортировать дочерний модуль по относительному пути. Это своего рода предпочтение. Чтобы запретить любой относительный путь, нужно просто добавить ./
к patterns
.
На самом деле это не форматируется автоматически, потому что ESLint не знает пользовательский импорт псевдонимов. Поэтому выполнение осуществляется вручную.
7. react-hooks/exhaustive-deps
React-хук требует определения зависимостей, чтобы установить, когда должна быть запущена внутренняя логика. Но если у вас сложная логика в React-хуке, трудно точно прописать все зависимости. Поэтому для обнаружения недостающих зависимостей стоит использовать react-hooks/exhaustive-deps.
Для применения правила ESLint react-hooks нужно установить пакет react-hooks в качестве плагина.
// .eslintrcjson
{
"plugins": [
"react",
"@typescript-eslint",
"autofix",
"react-hooks"
],
}
Само правило очень простое. Просто добавьте одну строку, как показано ниже.
// "react-hooks/exhaustive-deps": "error"
Читайте также:
- Создание хука Git pre-commit для автопроверки и исправления кода JavaScript и TypeScript
- React: основные ошибки мидл-разработчиков
- 7 инструментов для создания дизайн-систем
Читайте нас в Telegram, VK и Дзен
Перевод статьи Toru Eguchi: 7 Recommended ESLint Rules for React TypeScript Project