@@ -81,41 +81,141 @@ export default [
8181 } ,
8282 } ,
8383 rules : {
84- // Nx boundaries
84+ /**
85+ * Nx boundaries
86+ * @see https://nx.dev/docs/features/enforce-module-boundaries
87+ * */
8588 '@nx/enforce-module-boundaries' : [
8689 'error' ,
8790 {
8891 enforceBuildableLibDependency : true ,
8992 allow : [ '^.*/eslint(\\.base)?\\.config\\.[cm]?js$' ] ,
90- depConstraints : [ { sourceTag : '*' , onlyDependOnLibsWithTags : [ '*' ] } ] ,
93+ depConstraints : [
94+ // example: apps can depend on ui + shared libs
95+ {
96+ sourceTag : 'type:app' ,
97+ onlyDependOnLibsWithTags : [ 'scope:ui' , 'scope:shared' , 'type:lib' ] ,
98+ } ,
99+ // // define to which libraries ui can depend on
100+ // { sourceTag: 'scope:ui', onlyDependOnLibsWithTags: ['scope:ui', 'scope:shared'] },
101+ ] ,
91102 } ,
92103 ] ,
93104
94105 // General style
95106 'prettier/prettier' : 'error' ,
96- curly : [ 'error' , 'all' ] ,
97107
98108 // TypeScript
99109 // Removed duplicates already enforced by TypeScript:
100110 'no-unused-vars' : 'off' ,
111+
112+ // ts checks these better than ESLint
101113 'no-redeclare' : 'off' ,
102- 'no-dupe-class-members' : 'off' ,
103- '@typescript-eslint/no-shadow' : 'off' ,
114+
115+ /**
116+ * This rule is redundant with `await` usage
117+ * async function foo() {
118+ * return await bar(); // `return bar()` is sufficient
119+ * }
120+ *
121+ * Also is covered by @no-floating-promises
122+ */
104123 '@typescript-eslint/return-await' : 'off' ,
105124
125+ /**
126+ * This rule is too restrictive in practice
127+ * const isAllow = useSomeHook(({ isAllow }) => isAllow); // will error
128+ */
129+ '@typescript-eslint/no-shadow' : 'off' ,
130+
131+ // allow to type primitive types explicitly like `let x: number = 5;` ✅
132+ '@typescript-eslint/no-inferrable-types' : 'off' ,
133+
134+ /**
135+ * this rule is too restrictive in practice, e.g.,
136+ * expect(someAsyncFunction).toHaveBeenCalledWith(someArg); // will error because someAsyncFunction is async
137+ */
138+ '@typescript-eslint/no-misused-promises' : 'off' ,
139+
140+ // allow the exception pattern with leading for function with multiple args
106141 '@typescript-eslint/no-unused-vars' : [
107142 'error' ,
108143 { argsIgnorePattern : '^_' , varsIgnorePattern : '^_' } ,
109144 ] ,
145+
146+ // functions an classes always are hoisted so this rule does not make sense for them
110147 '@typescript-eslint/no-use-before-define' : [
111148 'error' ,
112149 { functions : false , classes : false , variables : true } ,
113150 ] ,
151+
152+ // warn on develop so is not super annoying but will be rejected by husky pre-commit
114153 '@typescript-eslint/no-explicit-any' : 'warn' ,
115154
155+ // eslint cannot accurately check unbound methods so best to disable it
156+ '@typescript-eslint/unbound-method' : 'off' ,
157+
158+ /**
159+ * Empty functions are useful as placeholders or in tests
160+ */
161+ '@typescript-eslint/no-empty-function' : 'off' ,
162+
163+ // #region [TODO]: rules to review later
164+ /**
165+ * This rules are necessary in our code base but would require significant refactoring to enable them
166+ * By now we disable them since they were muted by configuration or explicit rules... but we want them enabled eventually
167+ */
168+
169+ /**
170+ * Also necessary we should not render unknown values directly in templates
171+ */
172+ '@typescript-eslint/restrict-template-expressions' : 'off' ,
173+
174+ /**
175+ * Related with defensive programming
176+ * We need to remove this rule and assert the non-null values properly: TODO
177+ */
178+ '@typescript-eslint/no-non-null-assertion' : 'off' ,
179+
180+ /**
181+ * This one is also related with defensive programming
182+ * We need to assert every unknown value before using it: TODO
183+ */
184+ '@typescript-eslint/no-unsafe-call' : 'off' ,
185+
186+ /**
187+ * We need this rule to easier identify rejected promises origins
188+ * It will require refactoring to enable it though
189+ */
190+ '@typescript-eslint/prefer-promise-reject-errors' : 'off' ,
191+
192+ /**
193+ * Avoid unsafe assignments
194+ * We need to migrate to defensive programming and assert every unknown value before using it
195+ */
196+ '@typescript-eslint/no-unsafe-assignment' : 'off' ,
197+ '@typescript-eslint/no-unsafe-member-access' : 'off' ,
198+
199+ /**
200+ * Super important to avoid deadened async errors or forgotten promises,
201+ * We already catch error because that could have been prevented by proper this rule usage
202+ * It will require significant refactoring to enable it though
203+ */
204+ '@typescript-eslint/no-floating-promises' : 'off' ,
205+
206+ /**
207+ * Avoid creating class and interface with same name
208+ * We need this but it requires refactoring to enable it
209+ */
210+ '@typescript-eslint/no-unsafe-declaration-merging' : 'off' ,
211+ 'no-dupe-class-members' : 'off' ,
212+
213+ // #endregion
214+
116215 // React
117216 'react/react-in-jsx-scope' : 'off' ,
118217 'react/jsx-uses-react' : 'off' ,
218+
119219 'react-hooks/rules-of-hooks' : 'error' ,
120220 'react-hooks/exhaustive-deps' : 'warn' ,
121221
0 commit comments