Источник: Nuances of Programming
Комбинация 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"
Читайте также:
Перевод статьи Toru Eguchi: 7 Recommended ESLint Rules for React TypeScript Project