-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy patheslint.config.cjs
245 lines (212 loc) Β· 10.5 KB
/
eslint.config.cjs
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// π¬ 2024-10-16 rvion:
// | for some reason, vscode eslint plugin runs eslint on this file despite it not beeing
// | part of our imports; so lets' disable its errors since they all come from a single rule.
/* eslint-disable @typescript-eslint/no-require-imports */
const typescriptEslint = require('@typescript-eslint/eslint-plugin')
const reactRefresh = require('eslint-plugin-react-refresh')
const globals = require('globals')
const tsParser = require('@typescript-eslint/parser')
const js = require('@eslint/js')
const tailwindcss = require('eslint-plugin-tailwindcss')
const { FlatCompat } = require('@eslint/eslintrc')
// π¬ 2024-10-16 rvion:
// | this localRules stuff seems pretty cool; probably something to investigate soon
// |> const localRules = require('eslint-plugin-local-rules')
const USE_SLOW_TYPECHECKING_RULES = false
const ERROR_LEVEL = 'error' // : 'warn' | 'error'
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
})
// π¬ 2024-10-16 rvion:
// | modern configs seems to use some kind of layered apporach like this
// | https://github.com/prisma/prisma/blob/6819678dd575677ccd5c6a72ea51f8421f6a82ce/eslint.config.cjs#L4
module.exports = [
// 1. add core includes
{
files: ['src/**/*.{ts,tsx}'],
},
// 2. add core excludes
// why in a separate object? because eslint is doing BATSHIT CRAZY impossible to know stuff
// | when config have a single keys... who thought it was a good idea to add such special cases!?)
// | e.g. https://eslint.org/docs/latest/use/configure/ignore
{
ignores: [
// top-level folders to ignore
'ios/',
'android/',
'dist/',
'lib/',
'coverage/',
// ignore formats
'**/*.d.ts',
'**/*.js',
'**/*.cjs',
'**/*.mjs',
// temporary
'src/tools/autotype.ts',
],
},
// 3. addd
...compat.extends(
//
'eslint:recommended',
// π¬ 2024-10-16 rvion:
// | unlike the rule below, those do not require a full typescript typechecking
// | and are great to include by defaul;t next config layer will anyway remove some of them.
'plugin:@typescript-eslint/recommended',
// π¬ 2024-10-16 rvion:
// |π this is handy, but super slow. 100ms => 23 seconds => 230 times slower !!!!!!
// |> 'plugin:@typescript-eslint/recommended-requiring-type-checking',
// π¬ 2024-10-16 rvion:
// | we're not at the point where cosmetic shit matters. prettier already does it's job
// | at making sure we have files somewhat coherent. let's leave it as that.
// |> 'plugin:prettier/recommended',
),
// 4. our actual main config.
{
// cache: true,
languageOptions: {
globals: { ...globals.node },
parser: tsParser,
ecmaVersion: 2020,
sourceType: 'module',
// π¬ 2024-10-16 rvion:
// | THIS MOTHERFUCKING LINE makes everything 100 times slower.
// | parserOptions: { project: path.resolve(__dirname, 'tsconfig.json') },
},
plugins: {
'react-refresh': reactRefresh,
'@typescript-eslint': typescriptEslint,
tailwindcss: tailwindcss,
},
rules: {
// π this one is sadly quite slow;
// but will be quite pleasant to cleanup our crappy tw code
// also, we need to suport className='...' and tw='...'
'tailwindcss/classnames-order': ['warn', { classRegex: '^(className|tw)$' }],
'tailwindcss/enforces-negative-arbitrary-values': 'warn',
'tailwindcss/enforces-shorthand': 'warn',
'tailwindcss/migration-from-tailwind-2': 'warn',
'tailwindcss/no-contradicting-classname': 'error',
'tailwindcss/no-unnecessary-arbitrary-value': 'warn',
// those two rules takes a shit amount of time
'tailwindcss/no-arbitrary-value': 'off',
'tailwindcss/no-custom-classname': 'off',
'no-restricted-properties': [
'error',
{
object: 'window',
property: 'addEventListener',
message: "Please use 'window_addEventListener' instead of 'window.addEventListener'.",
},
],
// "no-restricted-imports": [
// "error",
// {
// "paths": [
// {
// "name": "mobx",
// "importNames": ["makeAutoObservable"],
// "message": "Please use 'makeAutoObservableV2' instead of 'makeAutoObservable' from 'mobx'."
// }
// ]
// }
// ],
// π¬ 2024-10-16 rvion:
// | this one is useless since we use typescript
// | not sure why it suddenly started to appear after bumping eslint various packages.
'no-unused-vars': 'off',
// π¦π¦π this helps (a lot) with hot-reloading!!
// see: https://github.com/ArnaudBarre/eslint-plugin-react-refresh
// see: https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports
'react-refresh/only-export-components': [ERROR_LEVEL, { allowConstantExport: true }],
'@typescript-eslint/explicit-function-return-type': ERROR_LEVEL,
// // AVOID WRITING AND MAINTAINING WEIRD CONDITIONALS ==========================================
'@typescript-eslint/strict-boolean-expressions': USE_SLOW_TYPECHECKING_RULES
? [
ERROR_LEVEL,
{
allowNullableString: true,
allowNullableBoolean: true,
allowAny: true,
},
]
: 'off',
// π¬ 2024-10-17 rvion:
// πΆ if the string-boolean-expressions lint rule above is disabled, then we need to
// at least manually remove the following rules that will otherwise make our code
// actively worse
'no-extra-boolean-cast': 'off',
//# PROMISES
// https://typescript-eslint.io/rules/no-misused-promises
// Disallows Promises in places not designed to handle them.
'@typescript-eslint/no-misused-promises': USE_SLOW_TYPECHECKING_RULES
? [ERROR_LEVEL, { checksVoidReturn: false }]
: 'off',
// https://typescript-eslint.io/rules/require-await
'@typescript-eslint/require-await': USE_SLOW_TYPECHECKING_RULES //
? ERROR_LEVEL
: 'off',
// https://typescript-eslint.io/rules/no-floating-promises
'@typescript-eslint/no-floating-promises': USE_SLOW_TYPECHECKING_RULES //
? ERROR_LEVEL
: 'off',
// https://typescript-eslint.io/rules/await-thenable
'@typescript-eslint/await-thenable': USE_SLOW_TYPECHECKING_RULES //
? ERROR_LEVEL
: 'off',
// avoid errors due to empty strings and 0 values
'@typescript-eslint/return-await': USE_SLOW_TYPECHECKING_RULES //
? [ERROR_LEVEL, 'in-try-catch']
: 'off', // nice but 400+ errors to fix
'no-return-await': ERROR_LEVEL, // nice but 400+ errors to fix
'consistent-this': [2, 'self', 'that'], // as a palliative solution to above permissive rule
// π¬ 2024-10-16 rvion:
// | π΄ this one seems to not work properly.
// | we need to investigate the exact conditions that make it triggers.
// Removing false-positive circular dependencies by forcing type imports
'@typescript-eslint/consistent-type-imports': [
ERROR_LEVEL,
{
prefer: 'type-imports',
fixStyle: 'separate-type-imports',
},
],
// π¬ 2024-10-18 rvion:
// this rule should not be activate unless we run with the full linter
// otherwise, `--fix` will possibly remove correct disable comments
'eslint-comments/no-unused-disable': USE_SLOW_TYPECHECKING_RULES //
? ERROR_LEVEL
: 'off',
'@typescript-eslint/no-non-null-assertion': 'off', // πΆ prevent ! to check if null
//# DISABLED -------------------------------------------------------------------------------------------
'@typescript-eslint/no-inferrable-types': 'off', // explicit types are sometimes useful.
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off', // nice but not tolerant of our exhaust patterns
'@typescript-eslint/no-use-before-define': 'off', // ???
'@typescript-eslint/no-unnecessary-type-constraint': 'off', // ???
'@typescript-eslint/prefer-as-const': 'off', // ???
'@typescript-eslint/no-this-alias': 'off', // sometimes, we need to preserve this.
'@typescript-eslint/no-empty-function': 'off', // OVER-ZEALOUS
'@typescript-eslint/no-var-requires': 'off', // OVER-ZEALOUS
'@typescript-eslint/no-unused-vars': 'off', // OVER-ZEALOUS
'@typescript-eslint/no-empty-object-type': 'off', // OVER-ZEALOUS
// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-empty-interface.md
// this one is buggy: because we use empty interface with extends clause for interface merging with types in various B_... files
// this could also be used for
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-explicit-any': 'off', // DANGEROUS BUT ACCEPTABLE FOR NOW
'@typescript-eslint/ban-ts-ignore': 'off', // DANGEROUS BUT ACCEPTABLE FOR NOW
'@typescript-eslint/no-unsafe-declaration-merging': 'off', // DANGEROUS BUT ACCEPTABLE FOR NOW
'@typescript-eslint/interface-name-prefix': 'off', // USELESS STYLE / NAMING STUFF
'@typescript-eslint/class-name-casing': 'off', // USELESS STYLE / NAMING STUFF
'@typescript-eslint/member-delimiter-style': 'off', // USELESS STYLE / NAMING STUFF
'@typescript-eslint/camelcase': 'off', // USELESS STYLE / NAMING STUFF
semi: 'off', // USELESS STYLE / NAMING STUFF
'no-extra-semi': 'off', // CONFLICT WITH PRETTIER
},
},
]