131 lines
4.1 KiB
JavaScript
131 lines
4.1 KiB
JavaScript
import { FlatCompat } from "@eslint/eslintrc";
|
|
import eslintPluginImport from "eslint-plugin-import";
|
|
import eslintPluginReact from "eslint-plugin-react";
|
|
import eslintPluginReactHooks from "eslint-plugin-react-hooks";
|
|
import eslintPluginSort from "eslint-plugin-simple-import-sort";
|
|
import eslintPluginUnused from "eslint-plugin-unused-imports";
|
|
import { dirname } from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
const compat = new FlatCompat({
|
|
baseDirectory: __dirname,
|
|
});
|
|
|
|
const eslintConfig = [
|
|
...compat.extends("next/core-web-vitals", "next/typescript"),
|
|
{
|
|
plugins: {
|
|
import: eslintPluginImport,
|
|
"unused-imports": eslintPluginUnused,
|
|
"simple-import-sort": eslintPluginSort,
|
|
react: eslintPluginReact,
|
|
"react-hooks": eslintPluginReactHooks,
|
|
},
|
|
|
|
rules: {
|
|
/* неиспользуемые переменные и импорты */
|
|
"@typescript-eslint/no-unused-vars": [
|
|
"warn",
|
|
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
|
|
],
|
|
"unused-imports/no-unused-imports": "error",
|
|
"unused-imports/no-unused-vars": [
|
|
"warn",
|
|
{
|
|
vars: "all",
|
|
varsIgnorePattern: "^_",
|
|
args: "after-used",
|
|
argsIgnorePattern: "^_",
|
|
},
|
|
],
|
|
|
|
/* порядок импортов: стили .module.(s)css внизу */
|
|
"simple-import-sort/imports": [
|
|
"error",
|
|
{
|
|
groups: [
|
|
["^\\u0000"], // side-effects
|
|
["^react", "^next", "^@?\\w"], // пакеты
|
|
["^@/"], // алиасы проекта
|
|
["^\\.\\.?(?:/|$)"], // относительные импорты (включая "..")
|
|
["^.+\\.module\\.(css|scss)$"], // модули стилей
|
|
],
|
|
},
|
|
],
|
|
"simple-import-sort/exports": "error",
|
|
|
|
/* React правила */
|
|
"react/jsx-uses-react": "off", // не нужно в React 17+
|
|
"react/react-in-jsx-scope": "off", // не нужно в React 17+
|
|
"react/prop-types": "off", // используем TypeScript
|
|
"react/display-name": "warn",
|
|
"react/jsx-key": "error",
|
|
"react/jsx-no-duplicate-props": "error",
|
|
"react/jsx-no-undef": "error",
|
|
// "react/no-array-index-key": "warn",
|
|
"react/no-danger": "warn",
|
|
"react/no-deprecated": "error",
|
|
"react/no-direct-mutation-state": "error",
|
|
"react/no-find-dom-node": "error",
|
|
"react/no-is-mounted": "error",
|
|
"react/no-render-return-value": "error",
|
|
"react/no-string-refs": "error",
|
|
"react/no-unescaped-entities": "warn",
|
|
"react/no-unknown-property": "error",
|
|
"react/no-unsafe": "warn",
|
|
"react/self-closing-comp": "error",
|
|
|
|
/* React Hooks правила */
|
|
"react-hooks/rules-of-hooks": "error",
|
|
"react-hooks/exhaustive-deps": "warn",
|
|
|
|
/* TypeScript правила */
|
|
"@typescript-eslint/no-explicit-any": "warn",
|
|
"@typescript-eslint/no-non-null-assertion": "warn",
|
|
"@typescript-eslint/no-var-requires": "error",
|
|
"@typescript-eslint/explicit-function-return-type": "off",
|
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
"@typescript-eslint/no-empty-function": "warn",
|
|
"@typescript-eslint/no-inferrable-types": "error",
|
|
|
|
/* Общие правила */
|
|
"no-console": "warn",
|
|
"no-debugger": "error",
|
|
"no-alert": "warn",
|
|
"no-var": "error",
|
|
"prefer-const": "error",
|
|
"no-unused-expressions": "error",
|
|
"no-duplicate-imports": "error",
|
|
"no-multiple-empty-lines": ["error", { max: 2 }],
|
|
"eol-last": "error",
|
|
"no-trailing-spaces": "error",
|
|
|
|
/* Запрет SVG импортов как компонентов */
|
|
"no-restricted-imports": [
|
|
"error",
|
|
{
|
|
patterns: [
|
|
{
|
|
group: ["*.svg"],
|
|
message: "❌ SVG imports as components break in production. Use inline SVG or next/image.",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
}, {
|
|
ignores: [
|
|
"node_modules/**",
|
|
".next/**",
|
|
"out/**",
|
|
"build/**",
|
|
"next-env.d.ts",
|
|
"public/metrics-scripts/**"
|
|
]
|
|
}];
|
|
|
|
export default eslintConfig;
|