.eslintrc.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Rules which have been enforced in configuration upgrades and flag issues in existing code.
  2. // We need to consider whether to disable those rules permanently, or fix the issues.
  3. const legacyCode = {
  4. 'class-methods-use-this': 'off',
  5. 'constructor-super': 'off',
  6. 'default-param-last': 'off',
  7. 'max-classes-per-file': 'off',
  8. 'no-continue': 'off',
  9. 'no-else-return': 'off',
  10. 'no-plusplus': 'off',
  11. 'no-prototype-builtins': 'off',
  12. 'no-restricted-syntax': 'off',
  13. 'no-this-before-super': 'off',
  14. };
  15. module.exports = {
  16. extends: [
  17. '@wagtail/eslint-config-wagtail',
  18. 'plugin:@typescript-eslint/recommended',
  19. ],
  20. parser: '@typescript-eslint/parser',
  21. plugins: ['@typescript-eslint'],
  22. env: {
  23. jest: true,
  24. browser: true,
  25. },
  26. rules: {
  27. '@typescript-eslint/explicit-function-return-type': 'off',
  28. '@typescript-eslint/explicit-member-accessibility': 'off',
  29. '@typescript-eslint/explicit-module-boundary-types': 'off',
  30. '@typescript-eslint/no-explicit-any': 'off',
  31. '@typescript-eslint/no-use-before-define': ['error'],
  32. 'import/extensions': [
  33. 'error',
  34. 'always',
  35. {
  36. ignorePackages: true,
  37. pattern: {
  38. js: 'never',
  39. jsx: 'never',
  40. ts: 'never',
  41. tsx: 'never',
  42. },
  43. },
  44. ],
  45. // does not align with the majority of legacy and newer code, some use named others use default exports
  46. 'import/prefer-default-export': 'off',
  47. // allow no lines between single line members (e.g. static declarations)
  48. 'lines-between-class-members': [
  49. 'error',
  50. 'always',
  51. { exceptAfterSingleLine: true },
  52. ],
  53. // note you must disable the base rule as it can report incorrect errors
  54. 'no-use-before-define': 'off',
  55. 'react/jsx-filename-extension': ['error', { extensions: ['.js', '.tsx'] }],
  56. 'no-underscore-dangle': [
  57. 'error',
  58. { allow: ['__REDUX_DEVTOOLS_EXTENSION__'] },
  59. ],
  60. // this rule can be confusing as it forces some non-intuitive code for variable assignment
  61. 'prefer-destructuring': 'off',
  62. },
  63. settings: {
  64. 'import/core-modules': ['jquery'],
  65. 'import/resolver': { node: { extensions: ['.js', '.ts', '.tsx'] } },
  66. },
  67. overrides: [
  68. // Legacy Code - remove from `files` when adopting desired rules in new code progressively
  69. {
  70. files: [
  71. 'client/src/entrypoints/admin/comments.js',
  72. 'client/src/entrypoints/admin/core.js',
  73. 'client/src/entrypoints/admin/expanding-formset.js',
  74. 'client/src/entrypoints/admin/filtered-select.js',
  75. 'client/src/entrypoints/admin/page-chooser.js',
  76. 'client/src/entrypoints/admin/page-editor.js',
  77. 'client/src/entrypoints/admin/telepath/widgets.js',
  78. 'client/src/entrypoints/contrib/table_block/table.js',
  79. 'client/src/entrypoints/contrib/typed_table_block/typed_table_block.js',
  80. 'client/src/entrypoints/images/image-chooser-modal.js',
  81. 'client/src/utils/actions.ts',
  82. 'client/src/utils/version.js',
  83. ],
  84. rules: legacyCode,
  85. },
  86. // Rules that we are ignoring currently due to legacy code in React components only
  87. {
  88. files: ['client/src/components/**'],
  89. rules: {
  90. ...legacyCode,
  91. 'jsx-a11y/click-events-have-key-events': 'off',
  92. 'jsx-a11y/interactive-supports-focus': 'off',
  93. 'jsx-a11y/no-noninteractive-element-interactions': 'off',
  94. 'jsx-a11y/role-supports-aria-props': 'off',
  95. 'react-hooks/exhaustive-deps': 'off',
  96. 'react-hooks/rules-of-hooks': 'off',
  97. 'react/button-has-type': 'off',
  98. 'react/destructuring-assignment': 'off',
  99. 'react/forbid-prop-types': 'off',
  100. 'react/function-component-definition': 'off',
  101. 'react/jsx-props-no-spreading': 'off',
  102. 'react/no-danger': 'off',
  103. 'react/no-deprecated': 'off',
  104. 'react/require-default-props': 'off',
  105. },
  106. },
  107. // Rules we don’t want to enforce for test and tooling code.
  108. {
  109. files: [
  110. 'client/extract-translatable-strings.js',
  111. 'client/tests/**',
  112. 'webpack.config.js',
  113. 'tailwind.config.js',
  114. 'storybook/**/*',
  115. '*.test.ts',
  116. '*.test.tsx',
  117. '*.test.js',
  118. '*.stories.js',
  119. '*.stories.tsx',
  120. ],
  121. rules: {
  122. '@typescript-eslint/no-empty-function': 'off',
  123. '@typescript-eslint/no-unused-vars': 'off',
  124. '@typescript-eslint/no-var-requires': 'off',
  125. 'global-require': 'off',
  126. 'import/first': 'off',
  127. 'import/no-extraneous-dependencies': 'off',
  128. 'no-unused-expressions': 'off',
  129. 'react/function-component-definition': 'off',
  130. 'react/jsx-props-no-spreading': 'off',
  131. },
  132. },
  133. // Files that use jquery via a global
  134. {
  135. files: [
  136. 'docs/_static/**',
  137. 'wagtail/contrib/modeladmin/static_src/wagtailmodeladmin/js/prepopulate.js',
  138. 'wagtail/contrib/settings/static_src/wagtailsettings/js/site-switcher.js',
  139. 'wagtail/documents/static_src/wagtaildocs/js/add-multiple.js',
  140. 'wagtail/embeds/static_src/wagtailembeds/js/embed-chooser-modal.js',
  141. 'wagtail/images/static_src/wagtailimages/js/add-multiple.js',
  142. 'wagtail/images/static_src/wagtailimages/js/focal-point-chooser.js',
  143. 'wagtail/images/static_src/wagtailimages/js/image-url-generator.js',
  144. 'wagtail/search/static_src/wagtailsearch/js/query-chooser-modal.js',
  145. 'wagtail/search/templates/wagtailsearch/queries/chooser_field.js',
  146. 'wagtail/snippets/static_src/wagtailsnippets/js/snippet-multiple-select.js',
  147. 'wagtail/users/static_src/wagtailusers/js/group-form.js',
  148. ],
  149. globals: { $: 'readonly', jQuery: 'readonly' },
  150. },
  151. // Files that use other globals or legacy/vendor code that is unable to be easily linted
  152. {
  153. files: ['wagtail/**/**'],
  154. globals: {
  155. addMessage: 'readonly',
  156. buildExpandingFormset: 'readonly',
  157. cancelSpinner: 'readonly',
  158. escapeHtml: 'readonly',
  159. jsonData: 'readonly',
  160. ModalWorkflow: 'readonly',
  161. DOCUMENT_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
  162. EMBED_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
  163. IMAGE_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
  164. QUERY_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
  165. SNIPPET_CHOOSER_MODAL_ONLOAD_HANDLERS: 'writable',
  166. },
  167. rules: {
  168. '@typescript-eslint/no-unused-vars': 'off',
  169. '@typescript-eslint/no-use-before-define': 'off',
  170. 'camelcase': [
  171. 'error',
  172. {
  173. allow: [
  174. '__unused_webpack_module',
  175. '__webpack_modules__',
  176. '__webpack_require__',
  177. ],
  178. properties: 'never',
  179. },
  180. ],
  181. 'consistent-return': 'off',
  182. 'func-names': 'off',
  183. 'id-length': 'off',
  184. 'indent': 'off',
  185. 'key-spacing': 'off',
  186. 'new-cap': 'off',
  187. 'newline-per-chained-call': 'off',
  188. 'no-param-reassign': 'off',
  189. 'no-underscore-dangle': 'off',
  190. 'object-shorthand': 'off',
  191. 'prefer-arrow-callback': 'off',
  192. 'quote-props': 'off',
  193. 'space-before-function-paren': 'off',
  194. 'vars-on-top': 'off',
  195. },
  196. },
  197. ],
  198. };