eslint.config.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import importX from 'eslint-plugin-import-x'
  2. import tseslint from 'typescript-eslint'
  3. import { defineConfig } from 'eslint/config'
  4. import vitest from '@vitest/eslint-plugin'
  5. import { builtinModules } from 'node:module'
  6. const DOMGlobals = ['window', 'document']
  7. const NodeGlobals = ['module', 'require']
  8. const banConstEnum = {
  9. selector: 'TSEnumDeclaration[const=true]',
  10. message:
  11. 'Please use non-const enums. This project automatically inlines enums.',
  12. }
  13. export default defineConfig(
  14. {
  15. files: ['**/*.js', '**/*.ts', '**/*.tsx'],
  16. extends: [tseslint.configs.base],
  17. plugins: {
  18. 'import-x': importX,
  19. },
  20. rules: {
  21. 'no-debugger': 'error',
  22. 'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
  23. // most of the codebase are expected to be env agnostic
  24. 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals],
  25. 'no-restricted-syntax': [
  26. 'error',
  27. banConstEnum,
  28. {
  29. selector: 'ObjectPattern > RestElement',
  30. message:
  31. 'Our output target is ES2016, and object rest spread results in ' +
  32. 'verbose helpers and should be avoided.',
  33. },
  34. {
  35. selector: 'ObjectExpression > SpreadElement',
  36. message:
  37. 'esbuild transpiles object spread into very verbose inline helpers.\n' +
  38. 'Please use the `extend` helper from @vue/shared instead.',
  39. },
  40. {
  41. selector: 'AwaitExpression',
  42. message:
  43. 'Our output target is ES2016, so async/await syntax should be avoided.',
  44. },
  45. {
  46. selector: 'ChainExpression',
  47. message:
  48. 'Our output target is ES2016, and optional chaining results in ' +
  49. 'verbose helpers and should be avoided.',
  50. },
  51. ],
  52. 'sort-imports': ['error', { ignoreDeclarationSort: true }],
  53. 'import-x/no-nodejs-modules': [
  54. 'error',
  55. { allow: builtinModules.map(mod => `node:${mod}`) },
  56. ],
  57. // This rule enforces the preference for using '@ts-expect-error' comments in TypeScript
  58. // code to indicate intentional type errors, improving code clarity and maintainability.
  59. '@typescript-eslint/ban-ts-comment': [
  60. 'error',
  61. { minimumDescriptionLength: 0 },
  62. ],
  63. // Enforce the use of 'import type' for importing types
  64. '@typescript-eslint/consistent-type-imports': [
  65. 'error',
  66. {
  67. fixStyle: 'inline-type-imports',
  68. disallowTypeAnnotations: false,
  69. },
  70. ],
  71. // Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers
  72. '@typescript-eslint/no-import-type-side-effects': 'error',
  73. },
  74. },
  75. // tests, no restrictions (runs in Node / Vitest with jsdom)
  76. {
  77. files: [
  78. '**/__tests__/**',
  79. 'packages-private/dts-test/**',
  80. 'packages-private/dts-build-test/**',
  81. ],
  82. plugins: { vitest },
  83. languageOptions: {
  84. globals: {
  85. ...vitest.environments.env.globals,
  86. },
  87. },
  88. rules: {
  89. 'no-console': 'off',
  90. 'no-restricted-globals': 'off',
  91. 'no-restricted-syntax': 'off',
  92. 'vitest/no-disabled-tests': 'error',
  93. 'vitest/no-focused-tests': 'error',
  94. },
  95. },
  96. // shared, may be used in any env
  97. {
  98. files: ['packages/shared/**', 'eslint.config.js'],
  99. rules: {
  100. 'no-restricted-globals': 'off',
  101. },
  102. },
  103. // Packages targeting DOM
  104. {
  105. files: ['packages/{vue,vue-compat,runtime-dom}/**'],
  106. rules: {
  107. 'no-restricted-globals': ['error', ...NodeGlobals],
  108. },
  109. },
  110. // Packages targeting Node
  111. {
  112. files: ['packages/{compiler-sfc,compiler-ssr,server-renderer}/**'],
  113. rules: {
  114. 'no-restricted-globals': ['error', ...DOMGlobals],
  115. 'no-restricted-syntax': ['error', banConstEnum],
  116. },
  117. },
  118. // Private package, browser only + no syntax restrictions
  119. {
  120. files: [
  121. 'packages-private/template-explorer/**',
  122. 'packages-private/sfc-playground/**',
  123. ],
  124. rules: {
  125. 'no-restricted-globals': ['error', ...NodeGlobals],
  126. 'no-restricted-syntax': ['error', banConstEnum],
  127. 'no-console': 'off',
  128. },
  129. },
  130. // JavaScript files
  131. {
  132. files: ['*.js'],
  133. rules: {
  134. // We only do `no-unused-vars` checks for js files, TS files are checked by TypeScript itself.
  135. 'no-unused-vars': ['error', { vars: 'all', args: 'none' }],
  136. },
  137. },
  138. // Node scripts
  139. {
  140. files: [
  141. 'eslint.config.js',
  142. 'rollup*.config.js',
  143. 'scripts/**',
  144. './*.{js,ts}',
  145. 'packages/*/*.js',
  146. 'packages/vue/*/*.js',
  147. ],
  148. rules: {
  149. 'no-restricted-globals': 'off',
  150. 'no-restricted-syntax': ['error', banConstEnum],
  151. 'no-console': 'off',
  152. },
  153. },
  154. // Import nodejs modules in compiler-sfc
  155. {
  156. files: ['packages/compiler-sfc/src/**'],
  157. rules: {
  158. 'import-x/no-nodejs-modules': ['error', { allow: builtinModules }],
  159. },
  160. },
  161. {
  162. ignores: [
  163. '**/dist/',
  164. '**/temp/',
  165. '**/coverage/',
  166. '.idea/',
  167. 'explorations/',
  168. 'dts-build/packages',
  169. ],
  170. },
  171. )