-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheslint.config.mjs
More file actions
154 lines (147 loc) · 4.69 KB
/
eslint.config.mjs
File metadata and controls
154 lines (147 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { defineConfig } from "eslint/config";
import eslintPlugin from "@eslint/js";
import tseslintPlugin from "@typescript-eslint/eslint-plugin";
import tseslintParser from "@typescript-eslint/parser";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";
import jsxA11yPlugin from "eslint-plugin-jsx-a11y";
import nextPlugin from "@next/eslint-plugin-next";
import promisePlugin from "eslint-plugin-promise";
// Global ignores configuration
// Must be in its own config object to act as global ignores
const ignoresConfig = defineConfig([
{
name: "project/ignores",
ignores: [
".next/",
"node_modules/",
"public/",
".vscode/",
"next-env.d.ts",
"playwright-report/",
".vercel/",
"**/pnpm-*/dist/",
],
},
]);
// ESLint recommended rules for JavaScript/TypeScript
const eslintConfig = defineConfig([
{
name: "project/javascript-recommended",
files: ["**/*.{js,mjs,ts,tsx}"],
...eslintPlugin.configs.recommended,
},
]);
// TypeScript configuration with type-checked rules
const typescriptConfig = defineConfig([
{
name: "project/typescript-strict",
files: ["**/*.{ts,tsx,mjs}"],
plugins: {
"@typescript-eslint": tseslintPlugin,
},
languageOptions: {
parser: tseslintParser,
parserOptions: {
project: ["./tsconfig.json"],
tsconfigRootDir: import.meta.dirname,
ecmaFeatures: {
jsx: true,
},
warnOnUnsupportedTypeScriptVersion: true,
},
},
extends: [
"@typescript-eslint/strict-type-checked",
"@typescript-eslint/stylistic-type-checked",
],
rules: {
// Disable rules that conflict with TypeScript's own error checking
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/triple-slash-reference": "off",
// disabled next rule due to bug:
// https://github.com/typescript-eslint/typescript-eslint/issues/11732
// https://github.com/eslint/eslint/issues/20272
"@typescript-eslint/unified-signatures": "off",
// Allow ts-expect-error and ts-ignore with descriptions
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-expect-error": "allow-with-description",
"ts-ignore": "allow-with-description",
"ts-nocheck": false,
"ts-check": false,
minimumDescriptionLength: 3,
},
],
},
},
// For plain JS files, you may want to disable type-checked rules
{
name: "project/javascript-disable-type-check",
files: ["**/*.{js,mjs,cjs}"],
plugins: {
"@typescript-eslint": tseslintPlugin,
},
extends: ["@typescript-eslint/disable-type-checked"],
},
]);
// React and Next.js configuration
const reactConfig = defineConfig([
{
name: "project/react-next",
files: ["**/*.{jsx,tsx}"],
plugins: {
react: reactPlugin,
"react-hooks": reactHooksPlugin,
"jsx-a11y": jsxA11yPlugin,
"@next/next": nextPlugin,
promise: promisePlugin,
},
rules: {
// React recommended rules
...reactPlugin.configs.recommended.rules,
...reactPlugin.configs["jsx-runtime"].rules,
// React Hooks rules (use recommended-latest for latest features)
...reactHooksPlugin.configs["recommended-latest"].rules,
// Accessibility rules (strict mode for better a11y)
...jsxA11yPlugin.configs.strict.rules,
// Next.js recommended rules
...nextPlugin.configs.recommended.rules,
// Next.js Core Web Vitals rules
...nextPlugin.configs["core-web-vitals"].rules,
// Customizations for modern React/Next.js
"react/react-in-jsx-scope": "off", // Not needed in Next.js
"react/prop-types": "off", // Use TypeScript instead
"react/no-unknown-property": "off", // Conflicts with custom attributes
"react/jsx-no-target-blank": "off", // Next.js handles this
// Fine-tuned accessibility rules
"jsx-a11y/alt-text": [
"warn",
{
elements: ["img"],
img: ["Image"], // Next.js Image component
},
],
"jsx-a11y/media-has-caption": "warn",
"jsx-a11y/aria-props": "warn",
"jsx-a11y/aria-proptypes": "warn",
"jsx-a11y/aria-unsupported-elements": "warn",
"jsx-a11y/role-has-required-aria-props": "warn",
"jsx-a11y/role-supports-aria-props": "warn",
},
settings: {
react: {
version: "detect", // Automatically detect React version
},
},
},
]);
// Export the complete configuration
// Order matters: ignores first, then general configs, then specific overrides
export default defineConfig([
...ignoresConfig,
...eslintConfig,
...typescriptConfig,
...reactConfig,
]);