1-eslint.js
module.exports = {
/*
* Отступы = 4 пробела.
* Код должен быть опрятным и не сливаться в кучу.
* https://eslint.org/docs/rules/indent
*/
indent: ['error', 4, { SwitchCase: 1 }],
/*
* Запрещается использовать 'магические' числа.
* Все числа должны быть указаны в виде констант.
* https://eslint.org/docs/rules/no-magic-numbers
*/
'no-magic-numbers': ['error', { ignore: [0, 1], detectObjects: false, enforceConst: true }],
/*
* Перевод строки после фигурной скобки в объектах.
* Фигурные скобки должны быть согласованы между собой и переноситься синхронизованно.
* https://eslint.org/docs/rules/object-curly-newline
*/
'object-curly-newline': ['error', { consistent: true }],
/*
* Разрешается использование только одинарных кавычек.
* https://eslint.org/docs/rules/quotes
*/
quotes: ['error', 'single'],
/*
* В JSX-элементах разрешается использование только двойных кавычек.
* https://eslint.org/docs/rules/jsx-quotes
*/
'jsx-quotes': ['error', 'prefer-double'],
/*
* Разрешается использовать сущности до их объявления. TODO: Включить после поднятия версии реакта!
* Сейчас существует баг с версией React https://stackoverflow.com/questions/63818415/react-was-used-before-it-was-defined
* Поэтому вместо этого правила, сейчас включено @typescript-eslint/no-use-before-define.
* https://eslint.org/docs/rules/no-use-before-define
*/
'no-use-before-define': 'off',
/*
* Разрешается использовать имена переменных, как и в родительской области видимости.
* https://eslint.org/docs/rules/no-shadow
*/
'no-shadow': 'off',
/*
* Семантика стрелочных функций не регламентируется.
* Возвращать значение сразу или явно указывать return - это непринципиальный кейс.
* https://eslint.org/docs/rules/arrow-body-style
*/
'arrow-body-style': 'off',
/*
* Максимальное количество символов в строке.
* В .editorconfig поставляется аналогичное значение.
* https://eslint.org/docs/rules/max-len
*/
'max-len': ['error', { code: 120 }],
/*
* Максимальное кол-во строк в файле = 1000. TODO: Уменьшить до 500!
* Файлы должны быть максимально компактными и легко читаемыми.
* https://eslint.org/docs/rules/max-lines
*/
'max-lines': ['error', 1000],
/*
* Запрещается использование класса console.
* Единственное исключение = console.error().
* https://eslint.org/docs/rules/no-console
*/
'no-console': ['error', { allow: ['warn', 'error'] }],
/*
* Разрешается оставлять неиспользованные переменные.
* Правило включается посредством '@typescript-eslint/no-unused-vars'.
* Потому что только TS умеет работать с переменными в типизации.
* https://eslint.org/docs/rules/no-unused-vars
*/
'no-unused-vars': 'off',
/*
* Все файлы должны заканчиваться пустой строкой.
* Это просто правило хорошего тона.
* https://eslint.org/docs/rules/eol-last
*/
'eol-last': ['error', 'always'],
/*
* Запрещается использовать стрелки там, где они могут быть спутаны со знаком сравнения.
* https://eslint.org/docs/rules/no-confusing-arrow
*/
'no-confusing-arrow': 'error',
/*
* Аргументы стрелочной функции всегда должны быть в скобках.
* Оставление 'висячих' аргументов выглядит неаккуратно в большой массе кода.
* https://eslint.org/docs/rules/arrow-parens
*/
'arrow-parens': ['error', 'always'],
/*
* Запрещено изменять аргументы функции.
* Это может привести к неявному изменению значения.
* https://eslint.org/docs/rules/no-param-reassign
*/
'no-param-reassign': 'off',
/*
* Разрешается использовать и шаблоны и конкатенацию.
* Конкатенация зачастую выглядит аккуратней.
* https://eslint.org/docs/rules/prefer-template
*/
'prefer-template': 'off',
/*
* Запрещается javascript:void(0) и подобное.
* https://eslint.org/docs/rules/no-script-url
*/
'no-script-url': 'error',
/*
* Разрешается любой тип ошибки в 'catch' промиса.
* https://eslint.org/docs/rules/prefer-promise-reject-errors
*/
'prefer-promise-reject-errors': 'off',
/*
* Правила пустых строк после или до указанных команд.
* Все правила сводятся к аккуратности итогового кода.
* https://eslint.org/docs/rules/padding-line-between-statements
*/
'padding-line-between-statements': [
'error',
// Пустая строка после импортов.
{ blankLine: 'always', prev: 'import', next: '*' },
{ blankLine: 'any', prev: 'import', next: 'import' },
// Пустая строка перед return.
{ blankLine: 'always', prev: '*', next: 'return' },
// Пустая строка после объявления переменных.
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
{
blankLine: 'any',
prev: ['const', 'let', 'var'],
next: ['const', 'let', 'var'],
},
],
/*
* Управление стилем комментариев.
* https://eslint.org/docs/rules/multiline-comment-style
*/
'multiline-comment-style': 'off',
/*
* Разрешается не использовать 'default' конструкцию в 'switch'.
* https://eslint.org/docs/rules/default-case
*/
'default-case': 'off',
/*
* Деструктуризация в массивах и объектах необязательна.
* Мы часто обращаемся к элементу массива по его индексу, а данное правило этому противоречит.
* https://eslint.org/docs/rules/prefer-destructuring
*/
'prefer-destructuring': 'off',
/*
* Запрещается отделять спред-оператор с переменной пробелом.
* https://eslint.org/docs/rules/rest-spread-spacing
*/
'rest-spread-spacing': ['error', 'never'],
/*
* Правила переноса скобок массива.
* Скобки должны быть согласованы между собой и переноситься синхронизовано.
* https://eslint.org/docs/rules/array-bracket-newline
*/
'array-bracket-newline': ['error', 'consistent'],
/*
* Разрешаются неиспользуемые выражения.
* Необходимо для выражений типа 'a && c || b()'.
* https://eslint.org/docs/rules/no-unused-expressions
*/
'no-unused-expressions': 'off',
};
2-import.js
module.exports = {
/*
* Разрешается не указывать расширения файлов для указанных типов.
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md
*/
'import/extensions': [2, 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never' }],
/*
* Разрешается использовать именованные экспорты (кроме асинхронных компонентов).
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md
*/
'import/prefer-default-export': 0,
/*
* Запрещены 'overhead' импорты, например, при обращении к 'index'.
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-useless-path-segments.md
*/
'import/no-useless-path-segments': [2, { noUselessIndex: true }],
/*
* Проверка резолва происходит за счет сборщика, а не линта.
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
*/
'import/no-unresolved': 0,
/*
* Сортировка импортов по группам, а внутри них по алфавиту.
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
*/
'import/order': [2, { alphabetize: { order: 'asc', caseInsensitive: true } }],
/*
* Отключение наблюдение за импортами зависимостей
* https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
*/
'import/no-extraneous-dependencies': 'off',
};
3-react.js
module.exports = {
/*
* Деструктуризация в 'props', 'state', 'context' необязательна.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/destructuring-assignment.md
*/
'react/destructuring-assignment': 0,
/*
* Поле 'displayName' у компонента необязателен.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md
*/
'react/display-name': 0,
/*
* Запрещается обращаться к 'this.state' внутри 'setState'.
* Это может привести к ошибкам, связанным с потерей актуального состояния стейта, когда в очереди несколько
* вызовов 'setState'. Для получения текущего стейта используйте колбэк.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-access-state-in-setstate.md
*/
'react/no-access-state-in-setstate': 2,
/*
* Между компонентами, написанными в строку должны быть пробелы.
* Компоненты не выглядят слипнувшимися и это добавляет аккуратности.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-adjacent-inline-elements.md
*/
'react/no-adjacent-inline-elements': 2,
/*
* Запрещается использовать индексы массивов для 'key' в React-компонентах.
* TODO: Включить! Потому что это правило добавляет safety в проект.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md
*/
'react/no-array-index-key': 1,
/*
* Запрещается использование 'опасных' пропсов.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-danger.md
*/
'react/no-danger': 2,
/*
* Запрещается мутировать стейт напрямую (кроме конструктора класса).
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-direct-mutation-state.md
*/
'react/no-direct-mutation-state': 2,
/*
* Предпочитать 'SFC', нежели классы.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md
*/
'react/prefer-stateless-function': 1,
/*
* Стейт создается только в теле класса (не в конструкторе).
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/state-in-constructor.md
*/
'react/state-in-constructor': [2, 'never'],
/*
* Статичные поля описываются только в теле ES6 класса.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/static-property-placement.md
*/
'react/static-property-placement': 'off',
/*
* Мы не используем prop-types, у нас typescript
*/
'react/require-default-props': 'off',
'react/prop-types': 'off',
'react/function-component-definition': [1, {
namedComponents: "arrow-function",
unnamedComponents: "arrow-function"
}]
};
4-react-jsx.js
module.exports = {
/*
* Перенос фигурных скобок в JSX-элементах не регламентируется.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-newline.md
*/
'react/jsx-curly-newline': 0,
/*
* JSX доступен только в данных файлах.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
*/
'react/jsx-filename-extension': [2, { extensions: ['.jsx', '.tsx'] }],
/*
* Если переносится хотябы одна пропса, то первая тоже должна перенести.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-first-prop-new-line.md
*/
'react/jsx-first-prop-new-line': [2, 'multiline'],
/*
* Обязательны корректные префиксы для хендлеров.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-handler-names.md
*/
'react/jsx-handler-names': 2,
/*
* В 'JSX' тэгах отступ ревен 4 пробелам.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md
*/
'react/jsx-indent': [2, 4],
/*
* В пропсах отступ ревен 4 пробелам.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
*/
'react/jsx-indent-props': [2, 4],
/*
* Свойство 'key' обязательно если оно требуется.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-key.md
*/
'react/jsx-key': 2,
/*
* Максимальная вложенность элементов = 10.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-max-depth.md
*/
'react/jsx-max-depth': [2, { max: 10 }],
/*
* Между 'JSX-элементами' необязательна пустая строка. (потому что есть JSX комменты для JSX элементов).
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-newline.md
*/
'react/jsx-newline': 0,
/*
* Запрещены биндинги и стрелочные функции в пропсах.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md
*/
'react/jsx-no-bind': 2,
/*
* Запрещается в контекст провайдера помещать нестабильные пропсы.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-constructed-context-values.md
*/
'react/jsx-no-constructed-context-values': 2,
/*
* Запрещены опасные js-ссылки (<a href="javascript:void(0)"></a>).
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-script-url.md
*/
'react/jsx-no-script-url': 2,
/*
* Безопасное открытие ссылок не регламентируется.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-target-blank.md
*/
'react/jsx-no-target-blank': 0,
/*
* Запрещены избыточные фрагменты.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md
*/
'react/jsx-no-useless-fragment': 2,
/*
* Спред-пропсы разрешены.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-props-no-spreading.md
*/
'react/jsx-props-no-spreading': 0,
/*
* Необходимо поддерживать алфавитный порядок в пропсах.
* https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md
*/
'react/jsx-sort-props': [2, { ignoreCase: true, shorthandLast: true }],
};
5-lodash.js
module.exports = {
/*
* Разрешаются только точечные импорты из библиотеки lodash.
* Потому что только так сокращается размер данной библиотеки.
* https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/import-scope.md
*/
'lodash/import-scope': [2, 'method'],
/*
* Есть функции, для которых это правило не подходит, например shouldComponentUpdate.
* https://github.com/wix/eslint-plugin-lodash/blob/v7.2.0/docs/rules/import-scope.md
*/
'lodash/prefer-constant': 'off',
/*
* Нам далеко не всегда нужно импортировать lodash.
* https://github.com/wix/eslint-plugin-lodash/blob/v7.2.0/docs/rules/prefer-lodash-method.md
*/
'lodash/prefer-lodash-method': 'off',
};
6-typescript.js
module.exports = {
/*
* Отступы = 4 пробела.
* Дублирующее правило 'indent' из eslint, создано для перестраховки.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/indent.md
*/
'@typescript-eslint/indent': [2, 4],
/*
* У функций бывают очень длинные возвращаемые типы, поэтому это не всегда целесообразно для соблюдения чистоты кода.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/explicit-function-return-type.md
*/
'@typescript-eslint/explicit-function-return-type': 0,
/*
* Правила разделителей в интерфейсах (точка с запятой).
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/member-delimiter-style.md
*/
'@typescript-eslint/member-delimiter-style': 2,
/*
* Запрещаются неиспользованные переменные.
* Кроме переменных в типизации и спред-операторов.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars.md
*/
'@typescript-eslint/no-unused-vars': [
2,
{
vars: 'all',
args: 'after-used',
ignoreRestSiblings: true,
},
],
/*
* Типизировать граничные функции необязательно. TODO: Пересмотреть правило!
* Сейчас достаточно использования '@typescript-eslint/explicit-function-return-type'.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/explicit-module-boundary-types.md
*/
'@typescript-eslint/explicit-module-boundary-types': 0,
/*
* Модификаторы доступа необязательны.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/explicit-member-accessibility.md
*/
'@typescript-eslint/explicit-member-accessibility': 0,
/*
* Запрещается использовать сущности до их объявления. TODO: Включить полностью!
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md
*/
'@typescript-eslint/no-use-before-define': 1,
/*
* Разрешаются к использованию всевозможные типы.
* В будущем тут можно явно ограничивать использование типов.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-types.md
*/
'@typescript-eslint/ban-types': 0,
/*
* Разрешается импорт через require.
* https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-var-requires.md
*/
'@typescript-eslint/no-var-requires': 0,
};
7-jsx-a11y.js
module.exports = {
/*
* Данные правила (jsx-a11y) пришли из стайлгайда airbnb.
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y
*/
/*
* Видимые элементы должны иметь заполненный атрибут alt
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md
*/
'jsx-a11y/alt-text': ['error', { elements: ['img', 'object', 'area', 'input[type="image"]'] }],
/*
* Видимые элементы должны иметь заполненный атрибут alt
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/anchor-has-content.md
*/
'jsx-a11y/anchor-has-content': 'warn',
/*
* Для композитных элементов, внутренний фокус должен быть равен нулю или быть положительным
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-activedescendant-has-tabindex.md
*/
'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
/*
* Корректные названия для aria-* атрибутов
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-props.md
*/
'jsx-a11y/aria-props': 'warn',
/*
* Валидные значения для aria элементов
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-proptypes.md
*/
'jsx-a11y/aria-proptypes': 'warn',
/*
* Валидные значения для aria ролей
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md
* Список ролей https://www.w3.org/TR/wai-aria/#role_definitions
*/
'jsx-a11y/aria-role': 'warn',
/*
* Не использовать элементы, не поддерживаемые aria
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-unsupported-elements.md
*/
'jsx-a11y/aria-unsupported-elements': 'warn',
/*
* Дублирование кликов мыши событиями на клавиатуре
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/click-events-have-key-events.md
*/
'jsx-a11y/click-events-have-key-events': 'warn',
/*
* Заголовок дожен иметь контент и он не должен быть спрятан
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/heading-has-content.md
*/
'jsx-a11y/heading-has-content': 'warn',
/*
* Атрибут html должен иметь тег lang
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/html-has-lang.md
*/
'jsx-a11y/html-has-lang': 'warn',
/*
* Элементы <iframe> должны иметь уникальное имя
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/iframe-has-title.md
*/
'jsx-a11y/iframe-has-title': 'warn',
/*
* Избыточное описание для тега img, скринридеры уже объявляют img элементы картинками
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md
*/
'jsx-a11y/img-redundant-alt': ['warn', { elements: ['img'], words: ['Иконка', 'Картинка'] }],
/*
* Все активные элементы должны уметь получать фокус
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/interactive-supports-focus.md
*/
'jsx-a11y/interactive-supports-focus': 'warn',
/*
* Медиа-теги audio, video и др. должны иметь специальный атрибут название для скринридера
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/media-has-caption.md
*/
'jsx-a11y/media-has-caption': 'warn',
/*
* Дублирование событий мыши событиями на клавиатуре для пользователей только клавиатуры
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/mouse-events-have-key-events.md
*/
'jsx-a11y/mouse-events-have-key-events': 'warn',
/*
* Запрет атрибута accessKey, чтобы не создавать путаницу скринридерам
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md
*/
'jsx-a11y/no-access-key': 'warn',
/*
* Запрет на использование тега autoFocus
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-autofocus.md
*/
'jsx-a11y/no-autofocus': ['warn', { ignoreNonDOM: true }],
/*
* Запрет на использование элементов <marquee> и <blink>
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-distracting-elements.md
*/
'jsx-a11y/no-distracting-elements': 'warn',
/*
* Не интерактивные aria роли не должны использоваться с интерактивными элементами, кроме <tr>
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-interactive-element-to-noninteractive-role.md
*/
'jsx-a11y/no-interactive-element-to-noninteractive-role': ['warn', { tr: ['none', 'presentation'] }],
/*
* Не использовать обработчики в неинтерактивных элементах
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-element-interactions.md
*/
'jsx-a11y/no-noninteractive-element-interactions': [
'warn',
{
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
},
],
/*
* Не интерактивные элементы не должны использоваться с интерактивными ролями
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md
*/
'jsx-a11y/no-noninteractive-element-to-interactive-role': [
'warn',
{
ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
table: ['grid'],
td: ['gridcell'],
},
],
/*
* Предупреждать об элементах, которые не взаимодействуют с пользователем и
* на них установлен tabindex
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-noninteractive-tabindex.md
*/
'jsx-a11y/no-noninteractive-tabindex': [
'warn',
{
tags: [],
roles: ['tabpanel'],
},
],
/*
* Избыточное описание ролей, для элементов, которые и так
* семантически понятны, например <img role="img"> (.etc)
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-redundant-roles.md
*/
'jsx-a11y/no-redundant-roles': 'warn',
/*
* Присваивание роли для статических элементов
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-static-element-interactions.md
*/
'jsx-a11y/no-static-element-interactions': [
'warn',
{
handlers: ['onClick', 'onMouseDown', 'onMouseUp', 'onKeyPress', 'onKeyDown', 'onKeyUp'],
},
],
/*
* Соответствие aria атрибутов aria ролям
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-has-required-aria-props.md
*/
'jsx-a11y/role-has-required-aria-props': 'warn',
/*
* Соответствие aria атрибутов aria ролям
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/role-supports-aria-props.md
*/
'jsx-a11y/role-supports-aria-props': 'warn',
/*
* Атрибут scope должен использоваться только на элементе <th>
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/scope.md
*/
'jsx-a11y/scope': 'warn',
/*
* Таб-индекс элементов равен 0 либо меньше 0, чтобы не нарушать скролл табом по странице
* https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/tabindex-no-positive.md
*/
'jsx-a11y/tabindex-no-positive': 'warn',
};
eslint.rc
const eslintRules = require('./tools/eslint/rules/1-eslint');
const importRules = require('./tools/eslint/rules/2-import');
const reactRules = require('./tools/eslint/rules/3-react');
const reactJSXRules = require('./tools/eslint/rules/4-react-jsx');
const lodashRules = require('./tools/eslint/rules/5-lodash');
const typescriptRules = require('./tools/eslint/rules/6-typescript');
const a11yRules = require('./tools/eslint/rules/7-jsx-a11y');
module.exports = {
root: true,
env: { browser: true, es6: true, jest: true },
extends: [
'eslint:recommended',
'plugin:import/recommended',
'plugin:react/recommended',
'plugin:lodash/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'airbnb',
'airbnb/hooks',
'plugin:@sbbol/web-library-guard/recommended',
'plugin:jest-dom/recommended',
'plugin:testing-library/react',
'prettier',
],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
JSX: 'readonly',
page: 'readonly',
reporter: 'readonly',
BUILD_VERSION: 'readonly',
LATEST_COMMIT_HASH: 'readonly',
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: { jsx: true },
ecmaVersion: 2020,
sourceType: 'module',
},
settings: {
'import/resolver': {
node: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
},
},
plugins: ['react', 'lodash', '@typescript-eslint', 'testing-library', 'jest-dom', 'jsx-a11y'],
rules: {
// убираем ругань на CRLF под виндой
'linebreak-style': ['error', process.platform === 'win32' ? 'windows' : 'unix'],
// Убираем проверку типов react/prop-types, эти функции выполняет TS
'react/prop-types': 0,
// Отключаем правила для пустого конструктора
'no-useless-constructor': 'off',
// Правила на пустые функции, они необходимы для задания начального значения в контексте, что бы не использовать null
'lodash/prefer-noop': 'off',
'no-empty-function': 'off',
'@typescript-eslint/no-empty-function': 'off',
// Правила ESLint.
...eslintRules,
// Правила импортов.
...importRules,
// Правила React.
...reactRules,
// Правила React JSX.
...reactJSXRules,
// Правила Lodash.
...lodashRules,
// Правила TypeScript.
...typescriptRules,
// Правила JSX a11y.
...a11yRules,
},
ignorePatterns: ['.eslintrc.js', 'tools/eslint/rules', 'node_modules', 'out'],
};
.gitignore
...
!.eslintrc.js
!.gitignore
!.npmrc
!.prettierignore
!.prettierrc.js
!.stylelintrc.js
...
prettierrc.js
module.exports = {
tabWidth: 4,
printWidth: 120,
useTabs: false,
semi: true,
singleQuote: true,
quoteProps: 'as-needed',
jsxSingleQuote: false,
trailingComma: 'all',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'always',
endOfLine: 'auto',
};
prettierrc.ignore
# Add files here to ignore them from prettier formatting
/out
/node_modules
package-lock.json
/src/assets
lint-staged.config.js
module.exports = {
/** Синтакс функции позволяет запустить tsc с tsconfig.json. */
'*.{ts,tsx}': [() => 'tsc --noEmit'],
'*.{ts,tsx,less}': ['npm run prettier:pre-commit'],
'src/**/*.less': ['npm run stylelint:pre-commit'],
'{src,__mocks__,__tests__}/**/*.{ts,tsx}': ['npm run eslint:pre-commit'],
};
Package.json
...
devDependencies
"electron-to-chromium": "1.4.118",
"eslint-config-airbnb": "19.0.4",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jest-dom": "4.0.1",
"eslint-plugin-jsx-a11y": "6.6.1",
"eslint-plugin-lodash": "7.4.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react": "7.29.4",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-testing-library": "5.6.0",
...
scripts
"eslint": "eslint",
"eslint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
"eslint:pre-commit": "eslint \"src/**/*.{ts,tsx}\" --fix --color --max-warnings=0",
"eslint:src": "eslint \"src/**/*.{ts,tsx}\"",
"stylelint": "stylelint \"**/*.less\"",
"stylelint:fix": "stylelint \"**/*.less\" --fix",
"stylelint:pre-commit": "stylelint \"**/*.less\" --fix --color --max-warnings=0",
"prettier:pre-commit": "prettier --write \"src/**/*.{js,ts,tsx,less}\"",
123
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}