.eslintrc.cjs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. module.exports = {
  2. env: {
  3. browser: true,
  4. es2021: true,
  5. },
  6. extends: [
  7. '@antfu/eslint-config-vue',
  8. 'plugin:vue/vue3-recommended',
  9. 'plugin:import/recommended',
  10. 'plugin:import/typescript',
  11. 'plugin:promise/recommended',
  12. 'plugin:sonarjs/recommended',
  13. 'plugin:@typescript-eslint/recommended',
  14. // 'plugin:unicorn/recommended',
  15. ],
  16. parser: 'vue-eslint-parser',
  17. parserOptions: {
  18. ecmaVersion: 13,
  19. parser: '@typescript-eslint/parser',
  20. sourceType: 'module',
  21. },
  22. plugins: [
  23. 'vue',
  24. '@typescript-eslint',
  25. 'regex',
  26. ],
  27. ignorePatterns: ['src/@iconify/*.js', 'node_modules', 'dist', '*.d.ts'],
  28. rules: {
  29. 'vue/no-v-html': 'off',
  30. 'vue/block-tag-newline': 'off',
  31. // eslint-disable-next-line n/prefer-global/process
  32. 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
  33. // eslint-disable-next-line n/prefer-global/process
  34. 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
  35. // indentation (Already present in TypeScript)
  36. 'comma-spacing': ['error', {
  37. before: false,
  38. after: true,
  39. }],
  40. 'key-spacing': ['error', { afterColon: true }],
  41. 'vue/first-attribute-linebreak': ['error', {
  42. singleline: 'beside',
  43. multiline: 'below',
  44. }],
  45. 'antfu/top-level-function': 'off',
  46. // Enforce trailing comma (Already present in TypeScript)
  47. 'comma-dangle': ['error', 'always-multiline'],
  48. // Disable max-len
  49. 'max-len': 'off',
  50. // we don't want it
  51. 'semi': ['error', 'never'],
  52. // add parens ony when required in arrow function
  53. 'arrow-parens': ['error', 'as-needed'],
  54. // add new line above comment
  55. 'newline-before-return': 'error',
  56. // add new line above comment
  57. 'lines-around-comment': [
  58. 'error',
  59. {
  60. beforeBlockComment: true,
  61. beforeLineComment: true,
  62. allowBlockStart: true,
  63. allowClassStart: true,
  64. allowObjectStart: true,
  65. allowArrayStart: true,
  66. },
  67. ],
  68. // Ignore _ as unused variable
  69. '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_+$' }],
  70. 'array-element-newline': ['error', 'consistent'],
  71. 'array-bracket-newline': ['error', 'consistent'],
  72. 'vue/multi-word-component-names': 'off',
  73. 'padding-line-between-statements': [
  74. 'error',
  75. {
  76. blankLine: 'always',
  77. prev: 'expression',
  78. next: 'const',
  79. },
  80. {
  81. blankLine: 'always',
  82. prev: 'const',
  83. next: 'expression',
  84. },
  85. {
  86. blankLine: 'always',
  87. prev: 'multiline-const',
  88. next: '*',
  89. },
  90. {
  91. blankLine: 'always',
  92. prev: '*',
  93. next: 'multiline-const',
  94. },
  95. ],
  96. // Plugin: eslint-plugin-import
  97. 'import/prefer-default-export': 'off',
  98. 'import/newline-after-import': ['error', { count: 1 }],
  99. 'no-restricted-imports': ['error', 'vuetify/components'],
  100. // For omitting extension for ts files
  101. 'import/extensions': [
  102. 'error',
  103. 'ignorePackages',
  104. {
  105. mjs: 'never',
  106. js: 'never',
  107. jsx: 'never',
  108. ts: 'never',
  109. tsx: 'never',
  110. },
  111. ],
  112. // ignore virtual files
  113. 'import/no-unresolved': [2, {
  114. ignore: [
  115. '~pages$',
  116. 'virtual:generated-layouts',
  117. // Ignore vite's ?raw imports
  118. '.*\?raw',
  119. ],
  120. }],
  121. // Thanks: https://stackoverflow.com/a/63961972/10796681
  122. 'no-shadow': 'off',
  123. '@typescript-eslint/no-shadow': ['error'],
  124. '@typescript-eslint/consistent-type-imports': 'error',
  125. // Plugin: eslint-plugin-promise
  126. 'promise/always-return': 'off',
  127. 'promise/catch-or-return': 'off',
  128. // ESLint plugin vue
  129. 'vue/component-api-style': 'error',
  130. 'vue/component-name-in-template-casing': ['error', 'PascalCase', { registeredComponentsOnly: false }],
  131. 'vue/custom-event-name-casing': ['error', 'camelCase', {
  132. ignores: [
  133. '/^(click):[a-z]+((\d)|([A-Z0-9][a-z0-9]+))*([A-Z])?/',
  134. ],
  135. }],
  136. 'vue/define-macros-order': 'error',
  137. 'vue/html-comment-content-newline': 'error',
  138. 'vue/html-comment-content-spacing': 'error',
  139. 'vue/html-comment-indent': 'error',
  140. 'vue/match-component-file-name': 'error',
  141. 'vue/no-child-content': 'error',
  142. 'vue/require-default-prop': 'off',
  143. // NOTE this rule only supported in SFC, Users of the unplugin-vue-define-options should disable that rule: https://github.com/vuejs/eslint-plugin-vue/issues/1886
  144. // 'vue/no-duplicate-attr-inheritance': 'error',
  145. 'vue/no-multiple-objects-in-class': 'error',
  146. 'vue/no-reserved-component-names': 'error',
  147. 'vue/no-template-target-blank': 'error',
  148. 'vue/no-useless-mustaches': 'error',
  149. 'vue/no-useless-v-bind': 'error',
  150. 'vue/padding-line-between-blocks': 'error',
  151. 'vue/prefer-separate-static-class': 'error',
  152. 'vue/prefer-true-attribute-shorthand': 'error',
  153. 'vue/v-on-function-call': 'error',
  154. 'vue/valid-v-slot': ['error', {
  155. allowModifiers: true,
  156. }],
  157. // -- Extension Rules
  158. 'vue/no-irregular-whitespace': 'error',
  159. // -- Sonarlint
  160. 'sonarjs/no-duplicate-string': 'off',
  161. 'sonarjs/no-nested-template-literals': 'off',
  162. // -- Unicorn
  163. // 'unicorn/filename-case': 'off',
  164. // 'unicorn/prevent-abbreviations': ['error', {
  165. // replacements: {
  166. // props: false,
  167. // },
  168. // }],
  169. // https://github.com/gmullerb/eslint-plugin-regex
  170. 'regex/invalid': [
  171. 'error',
  172. [
  173. {
  174. regex: '@/assets/images',
  175. replacement: '@images',
  176. message: 'Use \'@images\' path alias for image imports',
  177. },
  178. {
  179. regex: '@/styles',
  180. replacement: '@styles',
  181. message: 'Use \'@styles\' path alias for importing styles from \'src/styles\'',
  182. },
  183. // {
  184. // id: 'Disallow icon of icon library',
  185. // regex: 'tabler-\\w',
  186. // message: 'Only \'mdi\' icons are allowed',
  187. // },
  188. {
  189. regex: '@core/\\w',
  190. message: 'You can\'t use @core when you are in @layouts module',
  191. files: {
  192. inspect: '@layouts/.*',
  193. },
  194. },
  195. {
  196. regex: 'useLayouts\\(',
  197. message: '`useLayouts` composable is only allowed in @layouts & @core directory. Please use `useThemeConfig` composable instead.',
  198. files: {
  199. inspect: '^(?!.*(@core|@layouts)).*',
  200. },
  201. },
  202. ],
  203. // Ignore files
  204. '\.eslintrc\.js',
  205. ],
  206. },
  207. settings: {
  208. 'import/resolver': {
  209. node: {
  210. extensions: ['.ts', '.js', '.tsx', '.jsx', '.mjs', '.png', '.jpg'],
  211. },
  212. typescript: {},
  213. alias: {
  214. map: [
  215. ['@', './src'],
  216. ],
  217. },
  218. },
  219. },
  220. overrides: [
  221. {
  222. files: ['*.json'],
  223. rules: {
  224. 'no-invalid-meta': 'off',
  225. },
  226. },
  227. ],
  228. }