Skip to content

Commit 6af9efd

Browse files
authored
Merge pull request #94 from sectsect/feature/migrate-eslint-flat-config
chore: migrate ESLint config to flat config
2 parents 5a21bf8 + 8f925cb commit 6af9efd

File tree

7 files changed

+645
-375
lines changed

7 files changed

+645
-375
lines changed

.eslintignore

-3
This file was deleted.

.eslintrc.json

-185
This file was deleted.

eslint.config.mjs

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/* eslint-disable import/no-extraneous-dependencies */
2+
/* eslint-disable no-underscore-dangle */
3+
/* eslint-disable import/no-anonymous-default-export */
4+
5+
// Node.js path and URL utilities
6+
import path from 'node:path';
7+
import { fileURLToPath } from 'node:url';
8+
9+
// ESLint core and compatibility utilities
10+
import js from '@eslint/js';
11+
import { FlatCompat } from '@eslint/eslintrc';
12+
import { fixupPluginRules } from '@eslint/compat';
13+
import globals from 'globals';
14+
15+
// ESLint plugins for various technologies and best practices
16+
import react from 'eslint-plugin-react';
17+
import reactHooks from 'eslint-plugin-react-hooks';
18+
import jsxA11Y from 'eslint-plugin-jsx-a11y';
19+
import typescriptEslint from '@typescript-eslint/eslint-plugin';
20+
// import tseslint from 'typescript-eslint';
21+
import unusedImports from 'eslint-plugin-unused-imports';
22+
import tailwindcss from 'eslint-plugin-tailwindcss';
23+
import tsdoc from 'eslint-plugin-tsdoc';
24+
import _import from 'eslint-plugin-import';
25+
import prettier from 'eslint-plugin-prettier';
26+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
27+
import testingLibrary from 'eslint-plugin-testing-library';
28+
import vitest from 'eslint-plugin-vitest';
29+
import deprecationPlugin from 'eslint-plugin-deprecation';
30+
// import nextPlugin from '@next/eslint-plugin-next';
31+
import pluginQuery from '@tanstack/eslint-plugin-query';
32+
33+
// Resolve current file and directory paths
34+
const __filename = fileURLToPath(import.meta.url);
35+
const __dirname = path.dirname(__filename);
36+
const compat = new FlatCompat({
37+
baseDirectory: __dirname,
38+
recommendedConfig: js.configs.recommended,
39+
allConfig: js.configs.all,
40+
});
41+
42+
export default [
43+
// Ignore specific files and directories
44+
{
45+
ignores: [
46+
'**/dist/**',
47+
'**/out/**',
48+
'**/build/**',
49+
'**/node_modules/**',
50+
'**/playwright-report/**',
51+
'**/coverage/**',
52+
'**/.next/**',
53+
'**/.storybook/**',
54+
'**/*.config.{js,cjs,mjs}',
55+
'**/vendor/**',
56+
],
57+
},
58+
59+
// Base configuration extensions
60+
...compat.extends('airbnb', 'airbnb-typescript'),
61+
62+
// Detailed settings for TypeScript and React files
63+
{
64+
files: ['**/*.{ts,tsx}', '**/*.{test,spec}.{ts,tsx}'],
65+
66+
plugins: {
67+
react,
68+
'react-hooks': reactHooks,
69+
'jsx-a11y': jsxA11Y,
70+
'@typescript-eslint': typescriptEslint,
71+
// '@typescript-eslint': tseslint.plugin, // Commented out. This is because the @typescript-eslint plugin is already loaded by ...compat.extends('airbnb-typescript').
72+
// '@next/next': nextPlugin,
73+
'unused-imports': unusedImports,
74+
'@tanstack/query': pluginQuery,
75+
deprecation: fixupPluginRules(deprecationPlugin),
76+
tailwindcss,
77+
tsdoc,
78+
import: _import,
79+
prettier,
80+
'testing-library': testingLibrary,
81+
vitest,
82+
},
83+
84+
languageOptions: {
85+
ecmaVersion: 'latest',
86+
sourceType: 'module',
87+
// parser: tseslint.parser,
88+
parserOptions: {
89+
project: './tsconfig.json',
90+
},
91+
globals: {
92+
...globals.browser,
93+
...globals.node,
94+
...globals.jquery,
95+
window: true,
96+
lazySizes: true,
97+
},
98+
},
99+
100+
settings: {
101+
react: {
102+
version: '19.0.0',
103+
},
104+
},
105+
106+
rules: {
107+
// Prettier rules
108+
'prettier/prettier': 'error',
109+
110+
// React rules
111+
'react/require-default-props': 'off',
112+
'react/jsx-props-no-spreading': 'off',
113+
'react/no-danger': 'off',
114+
'react/function-component-definition': [
115+
2,
116+
{
117+
namedComponents: 'arrow-function',
118+
unnamedComponents: 'arrow-function',
119+
},
120+
],
121+
122+
// Accessibility rules
123+
'jsx-a11y/anchor-is-valid': 'off',
124+
'jsx-a11y/label-has-associated-control': [
125+
2,
126+
{
127+
assert: 'either',
128+
},
129+
],
130+
'jsx-a11y/control-has-associated-label': 'off',
131+
132+
// Next.js rules
133+
// '@next/next/no-img-element': 'off',
134+
135+
// Import rules
136+
'import/order': [
137+
'error',
138+
{
139+
groups: ['builtin', 'external', 'internal'],
140+
pathGroups: [
141+
{
142+
pattern: 'react',
143+
group: 'external',
144+
position: 'before',
145+
},
146+
],
147+
pathGroupsExcludedImportTypes: ['react'],
148+
'newlines-between': 'always',
149+
alphabetize: {
150+
order: 'asc',
151+
caseInsensitive: true,
152+
},
153+
},
154+
],
155+
'import/prefer-default-export': 'off',
156+
157+
// TypeScript rules
158+
'@typescript-eslint/comma-dangle': 'off',
159+
'@typescript-eslint/consistent-type-imports': 'error',
160+
'@typescript-eslint/no-unnecessary-condition': 'error',
161+
'@typescript-eslint/no-unused-vars': 'off',
162+
163+
// Unused imports/variables rules
164+
'unused-imports/no-unused-imports': 'error',
165+
'unused-imports/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
166+
167+
// Other miscellaneous rules
168+
'no-underscore-dangle': 'off',
169+
'tailwindcss/no-custom-classname': 'off',
170+
'tsdoc/syntax': 'warn',
171+
},
172+
},
173+
174+
// Additional rules for test files
175+
{
176+
files: ['**/*.{test,spec}.{ts,tsx}'],
177+
rules: {
178+
'vitest/consistent-test-it': ['error', { fn: 'test' }],
179+
'vitest/require-top-level-describe': [
180+
'error',
181+
{ maxNumberOfTopLevelDescribes: 2 },
182+
],
183+
},
184+
},
185+
186+
// Keep Prettier configuration last to avoid conflicts
187+
eslintPluginPrettierRecommended,
188+
];

0 commit comments

Comments
 (0)