From 19a1759f202b1dc6f22a1d77a7c5b490ab37e43b Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Wed, 19 Nov 2025 10:13:59 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20ESLint=209=20=D1=81=20flat=20config=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=BE?= =?UTF-8?q?=D0=B9=20React=2019?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Создан eslint.config.mjs с полными правилами - Добавлены комментарии на русском языке - Настроены плагины: React, TypeScript, Hooks, A11y, Import, Jest, Prettier - Игнорирование конфигурационных файлов --- eslint.config.mjs | 253 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..7eddc74 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,253 @@ +/** + * Конфигурация ESLint 9 (Flat Config) + * + * ESLint - это инструмент для статического анализа JavaScript/TypeScript кода, + * который помогает находить и исправлять проблемы в коде. + * + * Используется новый формат конфигурации (Flat Config) для ESLint 9+ + * + * Подключенные плагины: + * - @eslint/js: базовые правила JavaScript + * - typescript-eslint: правила для TypeScript + * - eslint-plugin-react: правила для React + * - eslint-plugin-react-hooks: правила для React Hooks + * - eslint-plugin-jsx-a11y: правила доступности для JSX + * - eslint-plugin-import: правила для импортов + * - eslint-plugin-jest: правила для тестов Jest + * - eslint-plugin-prettier: интеграция с Prettier + * + * Глобальные переменные: + * - __IS_DEV__: флаг режима разработки + * - __API__: URL API + * - __PROJECT__: тип проекта + * + * @example + * // Запуск проверки: + * pnpm lint + * + * // Автоматическое исправление: + * pnpm lint --fix + */ + +import js from '@eslint/js' +import prettierConfig from 'eslint-config-prettier' +import importPlugin from 'eslint-plugin-import' +import jestPlugin from 'eslint-plugin-jest' +import jsxA11yPlugin from 'eslint-plugin-jsx-a11y' +import prettierPlugin from 'eslint-plugin-prettier' +import reactPlugin from 'eslint-plugin-react' +import reactHooksPlugin from 'eslint-plugin-react-hooks' +import globals from 'globals' +import tseslint from 'typescript-eslint' + +export default [ + /** + * Базовые конфигурации + */ + js.configs.recommended, + ...tseslint.configs.recommended, + prettierConfig, + + /** + * Глобальные исключения (не проверяются линтером) + */ + { + ignores: [ + 'dist/**', + 'node_modules/**', + '.fttemplates/**', + '*.config.js', + '*.config.mjs', + '*.config.ts', + ], + }, + + /** + * Основная конфигурация для всех файлов + */ + { + files: ['**/*.{js,mjs,cjs,ts,tsx}'], + plugins: { + react: reactPlugin, + 'react-hooks': reactHooksPlugin, + 'jsx-a11y': jsxA11yPlugin, + import: importPlugin, + jest: jestPlugin, + prettier: prettierPlugin, + }, + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + parser: tseslint.parser, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + ...globals.es2021, + ...globals.jest, + __IS_DEV__: 'readonly', + __API__: 'readonly', + __PROJECT__: 'readonly', + }, + }, + settings: { + react: { + version: 'detect', + }, + 'import/resolver': { + typescript: true, + node: true, + }, + }, + rules: { + /** + * Правила для импортов + */ + + /** Упорядочивание импортов по группам с алфавитной сортировкой */ + 'import/order': [ + 'error', + { + groups: [ + ['external', 'builtin'], + 'internal', + ['sibling', 'parent'], + 'index', + ], + pathGroups: [ + { + pattern: '@react', + group: 'external', + position: 'before', + }, + { + pattern: '@src/**', + group: 'internal', + }, + ], + pathGroupsExcludedImportTypes: ['internal', 'react'], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + 'import/no-unresolved': 'off', + 'import/no-extraneous-dependencies': 'off', + 'import/extensions': 'off', + 'import/prefer-default-export': 'off', + 'import/no-import-module-exports': 'off', + + /** + * Правила для React + */ + + /** Определение компонентов через стрелочные функции или function declaration */ + 'react/function-component-definition': [ + 2, + { + namedComponents: ['arrow-function', 'function-declaration'], + unnamedComponents: ['arrow-function', 'function-expression'], + }, + ], + 'react/jsx-filename-extension': [ + 2, + { extensions: ['.tsx', '.jsx', '.js'] }, + ], + 'react/require-default-props': 'off', + 'react/jsx-props-no-spreading': 'warn', + 'react/display-name': 'off', + 'react/jsx-no-useless-fragment': [2, { allowExpressions: true }], + /** Не нужен с новым JSX transform */ + 'react/react-in-jsx-scope': 'off', + + /** + * Правила для React Hooks + */ + + /** Проверка правил хуков */ + 'react-hooks/rules-of-hooks': 'error', + /** Проверка зависимостей эффектов */ + 'react-hooks/exhaustive-deps': 'error', + + /** + * Правила доступности (A11y) + */ + + 'jsx-a11y/click-events-have-key-events': 'warn', + 'jsx-a11y/no-static-element-interactions': 'warn', + + /** + * Правила для TypeScript + */ + + '@typescript-eslint/no-shadow': 'warn', + '@typescript-eslint/no-unused-vars': 'warn', + '@typescript-eslint/no-var-requires': 'warn', + '@typescript-eslint/no-use-before-define': ['error', { enums: false }], + '@typescript-eslint/naming-convention': 'warn', + '@typescript-eslint/ban-ts-comment': 'warn', + + /** + * Общие правила JavaScript/TypeScript + */ + + /** Точки с запятой контролируются Prettier */ + semi: 'off', + 'jsx-quotes': ['error', 'prefer-single'], + 'no-shadow': 'off', + 'no-unused-vars': 'off', + 'no-underscore-dangle': 'off', + 'no-use-before-define': 'off', + 'no-param-reassign': ['warn', { props: false }], + 'max-len': [ + 2, + { + ignoreComments: true, + ignoreUrls: true, + code: 140, + ignorePattern: '^(import\\s.+\\sfrom\\s.+|\\} from)', + }, + ], + + /** + * Правила форматирования (Prettier) + */ + + 'prettier/prettier': [ + 'error', + { + semi: false, + singleQuote: true, + jsxSingleQuote: true, + trailingComma: 'es5', + }, + ], + }, + }, + + /** + * Переопределение правил для JavaScript файлов + */ + { + files: ['**/*.js'], + rules: { + 'consistent-return': 'off', + '@typescript-eslint/no-var-requires': 'off', + }, + }, + + /** + * Переопределение правил для тестов и сторибуков + */ + { + files: ['**/src/**/*.{test,stories}.{ts,tsx}'], + rules: { + 'max-len': 'off', + }, + }, +]