eslint.config.mjs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. import parserVue from 'vue-eslint-parser'
  2. import js from '@eslint/js'
  3. import pluginTs from '@typescript-eslint/eslint-plugin'
  4. import parserTs from '@typescript-eslint/parser'
  5. import pluginTurbo from 'eslint-config-turbo/flat'
  6. import pluginComments from 'eslint-plugin-eslint-comments'
  7. import * as pluginImport from 'eslint-plugin-import-x'
  8. import pluginJsdoc from 'eslint-plugin-jsdoc'
  9. import pluginJsonc from 'eslint-plugin-jsonc'
  10. import pluginNode from 'eslint-plugin-n'
  11. import perfectionistPlugin from 'eslint-plugin-perfectionist'
  12. import pluginPrettier from 'eslint-plugin-prettier'
  13. import pluginRegexp from 'eslint-plugin-regexp'
  14. import pluginUnicorn from 'eslint-plugin-unicorn'
  15. import pluginUnusedImports from 'eslint-plugin-unused-imports'
  16. import pluginVue from 'eslint-plugin-vue'
  17. import globals from 'globals'
  18. import parserJsonc from 'jsonc-eslint-parser'
  19. export default [
  20. {
  21. ignores: ['types/auto-import.d.ts', 'types/components.d.ts', 'dist/**', '.trae/**', 'build/**'],
  22. },
  23. // vue 检查
  24. ...pluginVue.configs['flat/essential'],
  25. ...pluginVue.configs['flat/strongly-recommended'],
  26. ...pluginVue.configs['flat/recommended'],
  27. {
  28. files: ['**/*.vue'],
  29. languageOptions: {
  30. parser: parserVue,
  31. globals: globals.browser,
  32. parserOptions: {
  33. ecmaFeatures: {
  34. jsx: true,
  35. },
  36. extraFileExtensions: ['.vue'],
  37. parser: parserTs,
  38. sourceType: 'module',
  39. },
  40. },
  41. plugins: {
  42. vue: pluginVue,
  43. },
  44. processor: pluginVue.processors['.vue'],
  45. rules: {
  46. ...pluginVue.configs.base.rules,
  47. 'vue/attribute-hyphenation': [
  48. 'error',
  49. 'always',
  50. {
  51. ignore: [],
  52. },
  53. ],
  54. 'vue/no-export-in-script-setup': 'off',
  55. 'vue/attributes-order': 'off',
  56. 'vue/block-order': [
  57. 'error',
  58. {
  59. order: ['template', 'script', 'style'],
  60. },
  61. ],
  62. 'vue/component-name-in-template-casing': ['error', 'PascalCase'],
  63. 'vue/component-options-name-casing': ['error', 'PascalCase'],
  64. 'vue/custom-event-name-casing': ['error', 'kebab-case'],
  65. 'vue/define-macros-order': [
  66. 'error',
  67. {
  68. order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots'],
  69. },
  70. ],
  71. 'vue/dot-location': ['error', 'property'],
  72. 'vue/dot-notation': ['error', { allowKeywords: true }],
  73. 'vue/eqeqeq': ['error', 'smart'],
  74. 'vue/html-closing-bracket-newline': 'error',
  75. 'vue/html-indent': 'off',
  76. // 'vue/html-indent': ['error', 2],
  77. 'vue/html-quotes': ['error', 'double'],
  78. 'vue/html-self-closing': [
  79. 'error',
  80. {
  81. html: {
  82. component: 'always',
  83. normal: 'never',
  84. void: 'always',
  85. },
  86. math: 'always',
  87. svg: 'always',
  88. },
  89. ],
  90. 'vue/max-attributes-per-line': 'off',
  91. 'vue/multi-word-component-names': 'off',
  92. 'vue/multiline-html-element-content-newline': 'error',
  93. 'vue/no-empty-pattern': 'error',
  94. 'vue/no-extra-parens': ['error', 'functions'],
  95. 'vue/no-irregular-whitespace': 'error',
  96. 'vue/no-loss-of-precision': 'error',
  97. 'vue/no-reserved-component-names': 'off',
  98. 'vue/no-restricted-syntax': [
  99. 'error',
  100. 'DebuggerStatement',
  101. 'LabeledStatement',
  102. 'WithStatement',
  103. ],
  104. 'vue/no-restricted-v-bind': ['error', '/^v-/'],
  105. 'vue/no-sparse-arrays': 'error',
  106. 'vue/no-unused-refs': 'error',
  107. 'vue/no-useless-v-bind': 'error',
  108. 'vue/object-shorthand': [
  109. 'error',
  110. 'always',
  111. {
  112. avoidQuotes: true,
  113. ignoreConstructors: false,
  114. },
  115. ],
  116. 'vue/one-component-per-file': 'error',
  117. 'vue/prefer-import-from-vue': 'error',
  118. 'vue/prefer-separate-static-class': 'error',
  119. 'vue/prefer-template': 'error',
  120. 'vue/prop-name-casing': ['error', 'camelCase'],
  121. 'vue/require-default-prop': 'error',
  122. 'vue/require-explicit-emits': 'error',
  123. 'vue/require-prop-types': 'off',
  124. 'vue/singleline-html-element-content-newline': 'off',
  125. 'vue/space-infix-ops': 'error',
  126. 'vue/space-unary-ops': ['error', { nonwords: false, words: true }],
  127. 'vue/v-on-event-hyphenation': [
  128. 'error',
  129. 'always',
  130. {
  131. autofix: true,
  132. ignore: [],
  133. },
  134. ],
  135. },
  136. },
  137. // javascript 检查
  138. {
  139. languageOptions: {
  140. ecmaVersion: 'latest',
  141. globals: {
  142. ...globals.browser,
  143. ...globals.es2021,
  144. ...globals.node,
  145. document: 'readonly',
  146. navigator: 'readonly',
  147. window: 'readonly',
  148. },
  149. parserOptions: {
  150. ecmaFeatures: {
  151. jsx: true,
  152. },
  153. ecmaVersion: 'latest',
  154. sourceType: 'module',
  155. },
  156. sourceType: 'module',
  157. },
  158. linterOptions: {
  159. reportUnusedDisableDirectives: true,
  160. },
  161. plugins: {
  162. 'unused-imports': pluginUnusedImports,
  163. },
  164. rules: {
  165. ...js.configs.recommended.rules,
  166. 'accessor-pairs': ['error', { enforceForClassMembers: true, setWithoutGet: true }],
  167. 'array-callback-return': 'error',
  168. 'block-scoped-var': 'error',
  169. 'constructor-super': 'error',
  170. 'default-case-last': 'error',
  171. 'dot-notation': ['error', { allowKeywords: true }],
  172. eqeqeq: ['error', 'always'],
  173. 'keyword-spacing': 'off',
  174. 'new-cap': ['error', { capIsNew: false, newIsCap: true, properties: true }],
  175. 'no-alert': 'error',
  176. 'no-array-constructor': 'error',
  177. 'no-async-promise-executor': 'warn',
  178. 'no-caller': 'error',
  179. 'no-case-declarations': 'error',
  180. 'no-class-assign': 'error',
  181. 'no-compare-neg-zero': 'error',
  182. 'no-cond-assign': ['error', 'always'],
  183. 'no-console': ['warn', { allow: ['warn', 'error'] }],
  184. 'no-const-assign': 'error',
  185. 'no-control-regex': 'error',
  186. 'no-debugger': 'error',
  187. 'no-delete-var': 'error',
  188. 'no-dupe-args': 'error',
  189. 'no-dupe-class-members': 'error',
  190. 'no-dupe-keys': 'error',
  191. 'no-duplicate-case': 'error',
  192. 'no-empty': ['error', { allowEmptyCatch: true }],
  193. 'no-empty-character-class': 'error',
  194. 'no-empty-function': 'off',
  195. 'no-empty-pattern': 'error',
  196. 'no-eval': 'error',
  197. 'no-ex-assign': 'error',
  198. 'no-extend-native': 'error',
  199. 'no-extra-bind': 'error',
  200. 'no-extra-boolean-cast': 'error',
  201. 'no-fallthrough': 'error',
  202. 'no-func-assign': 'error',
  203. 'no-global-assign': 'error',
  204. 'no-implied-eval': 'error',
  205. 'no-import-assign': 'error',
  206. 'no-invalid-regexp': 'error',
  207. 'no-irregular-whitespace': 'error',
  208. 'no-iterator': 'error',
  209. 'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
  210. 'no-lone-blocks': 'error',
  211. 'no-loss-of-precision': 'error',
  212. 'no-misleading-character-class': 'error',
  213. 'no-multi-str': 'error',
  214. 'no-new': 'error',
  215. 'no-new-func': 'error',
  216. 'no-new-object': 'error',
  217. 'no-new-symbol': 'error',
  218. 'no-new-wrappers': 'error',
  219. 'no-obj-calls': 'error',
  220. 'no-octal': 'error',
  221. 'no-octal-escape': 'error',
  222. 'no-proto': 'error',
  223. 'no-prototype-builtins': 'error',
  224. 'no-redeclare': ['error', { builtinGlobals: false }],
  225. 'no-regex-spaces': 'error',
  226. 'no-restricted-globals': [
  227. 'error',
  228. { message: 'Use `globalThis` instead.', name: 'global' },
  229. { message: 'Use `globalThis` instead.', name: 'self' },
  230. ],
  231. 'no-restricted-properties': [
  232. 'error',
  233. {
  234. message: 'Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.',
  235. property: '__proto__',
  236. },
  237. {
  238. message: 'Use `Object.defineProperty` instead.',
  239. property: '__defineGetter__',
  240. },
  241. {
  242. message: 'Use `Object.defineProperty` instead.',
  243. property: '__defineSetter__',
  244. },
  245. {
  246. message: 'Use `Object.getOwnPropertyDescriptor` instead.',
  247. property: '__lookupGetter__',
  248. },
  249. {
  250. message: 'Use `Object.getOwnPropertyDescriptor` instead.',
  251. property: '__lookupSetter__',
  252. },
  253. ],
  254. 'no-restricted-syntax': [
  255. 'error',
  256. 'DebuggerStatement',
  257. 'LabeledStatement',
  258. 'WithStatement',
  259. 'TSEnumDeclaration[const=true]',
  260. 'TSExportAssignment',
  261. ],
  262. 'no-self-assign': ['error', { props: true }],
  263. 'no-self-compare': 'error',
  264. 'no-sequences': 'error',
  265. 'no-shadow-restricted-names': 'error',
  266. 'no-sparse-arrays': 'error',
  267. 'no-template-curly-in-string': 'error',
  268. 'no-this-before-super': 'error',
  269. 'no-throw-literal': 'error',
  270. 'no-undef': 'off',
  271. 'no-undef-init': 'error',
  272. 'no-unexpected-multiline': 'error',
  273. 'no-unmodified-loop-condition': 'error',
  274. 'no-unneeded-ternary': ['error', { defaultAssignment: false }],
  275. 'no-unreachable': 'error',
  276. 'no-unreachable-loop': 'error',
  277. 'no-unsafe-finally': 'error',
  278. 'no-unsafe-negation': 'error',
  279. 'no-unused-expressions': [
  280. 'error',
  281. {
  282. allowShortCircuit: true,
  283. allowTaggedTemplates: true,
  284. allowTernary: true,
  285. },
  286. ],
  287. 'no-unused-vars': [
  288. 'error',
  289. {
  290. args: 'none',
  291. caughtErrors: 'none',
  292. ignoreRestSiblings: true,
  293. vars: 'all',
  294. },
  295. ],
  296. 'no-use-before-define': ['error', { classes: false, functions: false, variables: false }],
  297. 'no-useless-backreference': 'error',
  298. 'no-useless-call': 'error',
  299. 'no-useless-catch': 'error',
  300. 'no-useless-computed-key': 'error',
  301. 'no-useless-constructor': 'error',
  302. 'no-useless-rename': 'error',
  303. 'no-useless-return': 'error',
  304. 'no-var': 'error',
  305. 'no-with': 'error',
  306. 'object-shorthand': ['error', 'always', { avoidQuotes: true, ignoreConstructors: false }],
  307. 'one-var': ['error', { initialized: 'never' }],
  308. 'prefer-arrow-callback': [
  309. 'error',
  310. {
  311. allowNamedFunctions: false,
  312. allowUnboundThis: true,
  313. },
  314. ],
  315. 'prefer-const': [
  316. 'error',
  317. {
  318. destructuring: 'all',
  319. ignoreReadBeforeAssign: true,
  320. },
  321. ],
  322. 'prefer-exponentiation-operator': 'error',
  323. 'prefer-promise-reject-errors': 'error',
  324. 'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
  325. 'prefer-rest-params': 'error',
  326. 'prefer-spread': 'error',
  327. 'prefer-template': 'error',
  328. 'space-before-function-paren': 'off',
  329. 'spaced-comment': 'error',
  330. 'symbol-description': 'error',
  331. 'unicode-bom': ['error', 'never'],
  332. 'unused-imports/no-unused-imports': 'error',
  333. 'unused-imports/no-unused-vars': [
  334. 'error',
  335. {
  336. args: 'after-used',
  337. argsIgnorePattern: '^_',
  338. vars: 'all',
  339. varsIgnorePattern: '^_',
  340. },
  341. ],
  342. 'use-isnan': ['error', { enforceForIndexOf: true, enforceForSwitchCase: true }],
  343. 'valid-typeof': ['error', { requireStringLiterals: true }],
  344. 'vars-on-top': 'error',
  345. yoda: ['error', 'never'],
  346. },
  347. },
  348. {
  349. ignores: [
  350. 'dist/**',
  351. 'node_modules/**',
  352. '*.d.ts',
  353. 'public/**',
  354. '**/*.lock',
  355. '**/*.sh',
  356. '**/*.ttf',
  357. '**/*.woff',
  358. '**/.turbo',
  359. '**/.nuxt',
  360. '**/pnpm-lock.yaml',
  361. '**/.vercel',
  362. '**/.changeset',
  363. '**/.idea',
  364. '**/.cache',
  365. '**/.output',
  366. '**/CHANGELOG*.md',
  367. '**/LICENSE*',
  368. '**/temp',
  369. '**/.temp',
  370. '**/tmp',
  371. '**/.tmp',
  372. '**/.history',
  373. ],
  374. },
  375. // turborepo 规则
  376. {
  377. plugins: {
  378. turbo: pluginTurbo,
  379. },
  380. },
  381. // 查找正则表达式错误和正则表达式样式指南违规的
  382. {
  383. plugins: {
  384. regexp: pluginRegexp,
  385. },
  386. rules: {
  387. ...pluginRegexp.configs.recommended.rules,
  388. },
  389. },
  390. // 超过 100 条强大的 ESLint 规则
  391. {
  392. plugins: {
  393. unicorn: pluginUnicorn,
  394. },
  395. rules: {
  396. ...pluginUnicorn.configs.recommended.rules,
  397. 'unicorn/no-array-reduce': 'off',
  398. 'unicorn/better-regex': 'off',
  399. 'unicorn/consistent-destructuring': 'off',
  400. 'unicorn/consistent-function-scoping': 'off',
  401. 'unicorn/expiring-todo-comments': 'off',
  402. 'unicorn/filename-case': 'off',
  403. 'unicorn/import-style': 'off',
  404. 'unicorn/no-array-for-each': 'off',
  405. 'unicorn/no-null': 'off',
  406. 'unicorn/no-useless-undefined': 'off',
  407. 'unicorn/prefer-at': 'off',
  408. 'unicorn/prefer-dom-node-text-content': 'off',
  409. 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
  410. 'unicorn/prefer-global-this': 'off',
  411. 'unicorn/prefer-top-level-await': 'off',
  412. 'unicorn/prevent-abbreviations': 'off',
  413. 'unicorn/no-nested-ternary': 'off',
  414. },
  415. },
  416. {
  417. files: ['**/*.?([cm])[jt]s?(x)'],
  418. rules: {
  419. 'unicorn/no-process-exit': 'off',
  420. },
  421. },
  422. // JSDoc 规则
  423. {
  424. plugins: {
  425. jsdoc: pluginJsdoc,
  426. },
  427. rules: {
  428. 'jsdoc/check-access': 'warn',
  429. 'jsdoc/check-param-names': 'warn',
  430. 'jsdoc/check-property-names': 'warn',
  431. 'jsdoc/check-types': 'warn',
  432. 'jsdoc/empty-tags': 'warn',
  433. 'jsdoc/implements-on-classes': 'warn',
  434. 'jsdoc/no-defaults': 'warn',
  435. 'jsdoc/no-multi-asterisks': 'warn',
  436. 'jsdoc/require-param-name': 'warn',
  437. 'jsdoc/require-property': 'warn',
  438. 'jsdoc/require-property-description': 'warn',
  439. 'jsdoc/require-property-name': 'warn',
  440. 'jsdoc/require-returns-check': 'warn',
  441. 'jsdoc/require-returns-description': 'warn',
  442. 'jsdoc/require-yields-check': 'warn',
  443. },
  444. },
  445. // 注释规则
  446. {
  447. plugins: {
  448. 'eslint-comments': pluginComments,
  449. },
  450. rules: {
  451. 'eslint-comments/no-aggregating-enable': 'error',
  452. 'eslint-comments/no-duplicate-disable': 'error',
  453. 'eslint-comments/no-unlimited-disable': 'error',
  454. 'eslint-comments/no-unused-enable': 'error',
  455. },
  456. },
  457. // 自动排序和整理对象、导入、类型、枚举和 JSX 属性
  458. perfectionistPlugin.configs['recommended-natural'],
  459. {
  460. rules: {
  461. 'perfectionist/sort-exports': [
  462. 'error',
  463. {
  464. order: 'asc',
  465. type: 'natural',
  466. },
  467. ],
  468. 'perfectionist/sort-imports': [
  469. 'error',
  470. {
  471. customGroups: {
  472. type: {
  473. 'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'],
  474. },
  475. value: {
  476. vue: ['^vue$', '^vue-.+', '^@vue/.+'],
  477. },
  478. },
  479. environment: 'node',
  480. groups: [
  481. ['external-type', 'builtin-type', 'type'],
  482. 'vue-type',
  483. ['parent-type', 'sibling-type', 'index-type'],
  484. 'builtin',
  485. 'vue',
  486. 'external',
  487. ['parent', 'sibling', 'index'],
  488. 'side-effect',
  489. 'side-effect-style',
  490. 'style',
  491. 'object',
  492. 'unknown',
  493. ],
  494. internalPattern: ['^#/.+'],
  495. newlinesBetween: 'always',
  496. order: 'asc',
  497. type: 'natural',
  498. },
  499. ],
  500. 'perfectionist/sort-modules': 'off',
  501. 'perfectionist/sort-named-exports': [
  502. 'error',
  503. {
  504. order: 'asc',
  505. type: 'natural',
  506. },
  507. ],
  508. 'perfectionist/sort-objects': [
  509. 'off',
  510. {
  511. customGroups: {
  512. items: 'items',
  513. list: 'list',
  514. children: 'children',
  515. },
  516. groups: ['unknown', 'items', 'list', 'children'],
  517. ignorePattern: ['children'],
  518. order: 'asc',
  519. type: 'natural',
  520. },
  521. ],
  522. },
  523. },
  524. // node.js 的 ESLint 规则
  525. {
  526. plugins: {
  527. n: pluginNode,
  528. },
  529. rules: {
  530. 'n/handle-callback-err': ['error', '^(err|error)$'],
  531. 'n/no-deprecated-api': 'error',
  532. 'n/no-exports-assign': 'error',
  533. 'n/no-extraneous-import': [
  534. 'error',
  535. {
  536. allowModules: ['unbuild', 'vitest', 'vite', '@vue/test-utils', '@playwright/test'],
  537. },
  538. ],
  539. 'n/no-new-require': 'error',
  540. 'n/no-path-concat': 'error',
  541. 'n/no-unsupported-features/es-syntax': [
  542. 'error',
  543. {
  544. ignores: [],
  545. version: '>=18.0.0',
  546. },
  547. ],
  548. 'n/prefer-global/buffer': ['error', 'never'],
  549. 'n/prefer-global/process': ['error', 'always'],
  550. 'n/process-exit-as-throw': 'error',
  551. },
  552. },
  553. {
  554. files: ['**/*.?([cm])[jt]s?(x)'],
  555. rules: {
  556. 'n/prefer-global/process': 'off',
  557. },
  558. },
  559. // 支持 es6+ 导入/导出语法的校验,并防止文件路径和导入名称拼写错误的问题
  560. {
  561. plugins: {
  562. import: pluginImport,
  563. },
  564. rules: {
  565. 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
  566. 'import/first': 'error',
  567. 'import/newline-after-import': 'error',
  568. 'import/no-duplicates': 'error',
  569. 'import/no-mutable-exports': 'error',
  570. 'import/no-named-default': 'error',
  571. 'import/no-self-import': 'error',
  572. 'import/no-unresolved': 'off',
  573. 'import/no-webpack-loader-syntax': 'error',
  574. },
  575. },
  576. // 禁用部分 typescript 规则校验
  577. {
  578. files: ['**/__tests__/**/*.?([cm])[jt]s?(x)'],
  579. name: 'disables/test',
  580. rules: {
  581. '@typescript-eslint/ban-ts-comment': 'off', // 不允许 @ts-<directive> 注释或要求指令后有描述。
  582. 'no-console': 'off', // 不允许使用 console
  583. },
  584. },
  585. {
  586. files: ['**/*.d.ts'],
  587. name: 'disables/dts',
  588. rules: {
  589. '@typescript-eslint/triple-slash-reference': 'off', // 不允许使用某些三斜杠指令,而使用 ES6 风格的导入声明
  590. },
  591. },
  592. {
  593. files: ['**/*.js', '**/*.mjs', '**/*.cjs'],
  594. name: 'disables/js',
  595. rules: {
  596. '@typescript-eslint/explicit-module-boundary-types': 'off', // 要求导出函数和类的公共类方法具有明确的返回和参数类型
  597. },
  598. },
  599. // 检查 JSON 、 JSONC 和 JSON5 文件
  600. {
  601. files: ['**/*.json', '**/*.json5', '**/*.jsonc', '*.code-workspace'],
  602. languageOptions: {
  603. parser: parserJsonc,
  604. },
  605. plugins: {
  606. jsonc: pluginJsonc,
  607. },
  608. rules: {
  609. 'jsonc/no-bigint-literals': 'error',
  610. 'jsonc/no-binary-expression': 'error',
  611. 'jsonc/no-binary-numeric-literals': 'error',
  612. 'jsonc/no-dupe-keys': 'error',
  613. 'jsonc/no-escape-sequence-in-identifier': 'error',
  614. 'jsonc/no-floating-decimal': 'error',
  615. 'jsonc/no-hexadecimal-numeric-literals': 'error',
  616. 'jsonc/no-infinity': 'error',
  617. 'jsonc/no-multi-str': 'error',
  618. 'jsonc/no-nan': 'error',
  619. 'jsonc/no-number-props': 'error',
  620. 'jsonc/no-numeric-separators': 'error',
  621. 'jsonc/no-octal': 'error',
  622. 'jsonc/no-octal-escape': 'error',
  623. 'jsonc/no-octal-numeric-literals': 'error',
  624. 'jsonc/no-parenthesized': 'error',
  625. 'jsonc/no-plus-sign': 'error',
  626. 'jsonc/no-regexp-literals': 'error',
  627. 'jsonc/no-sparse-arrays': 'error',
  628. 'jsonc/no-template-literals': 'error',
  629. 'jsonc/no-undefined-value': 'error',
  630. 'jsonc/no-unicode-codepoint-escapes': 'error',
  631. 'jsonc/no-useless-escape': 'error',
  632. 'jsonc/space-unary-ops': 'error',
  633. 'jsonc/valid-json-number': 'error',
  634. 'jsonc/vue-custom-block/no-parsing-error': 'error',
  635. },
  636. },
  637. // package.json 文件排序
  638. {
  639. files: ['**/package.json'],
  640. rules: {
  641. 'jsonc/sort-array-values': [
  642. 'error',
  643. {
  644. order: { type: 'asc' },
  645. pathPattern: '^files$|^pnpm.neverBuiltDependencies$',
  646. },
  647. ],
  648. 'jsonc/sort-keys': [
  649. 'error',
  650. {
  651. order: [
  652. 'name',
  653. 'version',
  654. 'description',
  655. 'private',
  656. 'keywords',
  657. 'homepage',
  658. 'bugs',
  659. 'repository',
  660. 'license',
  661. 'author',
  662. 'contributors',
  663. 'categories',
  664. 'funding',
  665. 'type',
  666. 'scripts',
  667. 'files',
  668. 'sideEffects',
  669. 'bin',
  670. 'main',
  671. 'module',
  672. 'unpkg',
  673. 'jsdelivr',
  674. 'types',
  675. 'typesVersions',
  676. 'imports',
  677. 'exports',
  678. 'publishConfig',
  679. 'icon',
  680. 'activationEvents',
  681. 'contributes',
  682. 'peerDependencies',
  683. 'peerDependenciesMeta',
  684. 'dependencies',
  685. 'optionalDependencies',
  686. 'devDependencies',
  687. 'engines',
  688. 'packageManager',
  689. 'pnpm',
  690. 'overrides',
  691. 'resolutions',
  692. 'husky',
  693. 'simple-git-hooks',
  694. 'lint-staged',
  695. 'eslintConfig',
  696. ],
  697. pathPattern: '^$',
  698. },
  699. {
  700. order: { type: 'asc' },
  701. pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$',
  702. },
  703. {
  704. order: { type: 'asc' },
  705. pathPattern: '^(?:resolutions|overrides|pnpm.overrides)$',
  706. },
  707. {
  708. order: ['types', 'import', 'require', 'default'],
  709. pathPattern: '^exports.*$',
  710. },
  711. ],
  712. },
  713. },
  714. // tsconfig.json 文件排序
  715. {
  716. files: ['**/tsconfig.json', '**/tsconfig.*.json'],
  717. rules: {
  718. 'jsonc/sort-keys': [
  719. 'error',
  720. {
  721. order: ['extends', 'compilerOptions', 'references', 'files', 'include', 'exclude'],
  722. pathPattern: '^$',
  723. },
  724. {
  725. order: [
  726. /* Projects */
  727. 'incremental',
  728. 'composite',
  729. 'tsBuildInfoFile',
  730. 'disableSourceOfProjectReferenceRedirect',
  731. 'disableSolutionSearching',
  732. 'disableReferencedProjectLoad',
  733. /* Language and Environment */
  734. 'target',
  735. 'jsx',
  736. 'jsxFactory',
  737. 'jsxFragmentFactory',
  738. 'jsxImportSource',
  739. 'lib',
  740. 'moduleDetection',
  741. 'noLib',
  742. 'reactNamespace',
  743. 'useDefineForClassFields',
  744. 'emitDecoratorMetadata',
  745. 'experimentalDecorators',
  746. /* Modules */
  747. 'baseUrl',
  748. 'rootDir',
  749. 'rootDirs',
  750. 'customConditions',
  751. 'module',
  752. 'moduleResolution',
  753. 'moduleSuffixes',
  754. 'noResolve',
  755. 'paths',
  756. 'resolveJsonModule',
  757. 'resolvePackageJsonExports',
  758. 'resolvePackageJsonImports',
  759. 'typeRoots',
  760. 'types',
  761. 'allowArbitraryExtensions',
  762. 'allowImportingTsExtensions',
  763. 'allowUmdGlobalAccess',
  764. /* JavaScript Support */
  765. 'allowJs',
  766. 'checkJs',
  767. 'maxNodeModuleJsDepth',
  768. /* Type Checking */
  769. 'strict',
  770. 'strictBindCallApply',
  771. 'strictFunctionTypes',
  772. 'strictNullChecks',
  773. 'strictPropertyInitialization',
  774. 'allowUnreachableCode',
  775. 'allowUnusedLabels',
  776. 'alwaysStrict',
  777. 'exactOptionalPropertyTypes',
  778. 'noFallthroughCasesInSwitch',
  779. 'noImplicitAny',
  780. 'noImplicitOverride',
  781. 'noImplicitReturns',
  782. 'noImplicitThis',
  783. 'noPropertyAccessFromIndexSignature',
  784. 'noUncheckedIndexedAccess',
  785. 'noUnusedLocals',
  786. 'noUnusedParameters',
  787. 'useUnknownInCatchVariables',
  788. /* Emit */
  789. 'declaration',
  790. 'declarationDir',
  791. 'declarationMap',
  792. 'downlevelIteration',
  793. 'emitBOM',
  794. 'emitDeclarationOnly',
  795. 'importHelpers',
  796. 'importsNotUsedAsValues',
  797. 'inlineSourceMap',
  798. 'inlineSources',
  799. 'mapRoot',
  800. 'newLine',
  801. 'noEmit',
  802. 'noEmitHelpers',
  803. 'noEmitOnError',
  804. 'outDir',
  805. 'outFile',
  806. 'preserveConstEnums',
  807. 'preserveValueImports',
  808. 'removeComments',
  809. 'sourceMap',
  810. 'sourceRoot',
  811. 'stripInternal',
  812. /* Interop Constraints */
  813. 'allowSyntheticDefaultImports',
  814. 'esModuleInterop',
  815. 'forceConsistentCasingInFileNames',
  816. 'isolatedModules',
  817. 'preserveSymlinks',
  818. 'verbatimModuleSyntax',
  819. /* Completeness */
  820. 'skipDefaultLibCheck',
  821. 'skipLibCheck',
  822. ],
  823. pathPattern: '^compilerOptions$',
  824. },
  825. ],
  826. },
  827. },
  828. // typescript 规则
  829. {
  830. files: ['**/*.?([cm])[jt]s?(x)'],
  831. languageOptions: {
  832. parser: parserTs,
  833. parserOptions: {
  834. createDefaultProgram: false,
  835. ecmaFeatures: {
  836. jsx: true,
  837. },
  838. ecmaVersion: 'latest',
  839. extraFileExtensions: ['.vue'],
  840. jsxPragma: 'React',
  841. project: './tsconfig.*.json',
  842. sourceType: 'module',
  843. },
  844. },
  845. plugins: {
  846. '@typescript-eslint': pluginTs,
  847. },
  848. rules: {
  849. ...pluginTs.configs['eslint-recommended'].overrides?.[0].rules,
  850. ...pluginTs.configs.strict.rules,
  851. '@typescript-eslint/ban-ts-comment': [
  852. 'error',
  853. {
  854. 'ts-check': false,
  855. 'ts-expect-error': 'allow-with-description',
  856. 'ts-ignore': 'allow-with-description',
  857. 'ts-nocheck': 'allow-with-description',
  858. },
  859. ],
  860. // '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
  861. '@typescript-eslint/consistent-type-definitions': 'off',
  862. '@typescript-eslint/explicit-function-return-type': 'off',
  863. '@typescript-eslint/explicit-module-boundary-types': 'off',
  864. '@typescript-eslint/no-empty-function': [
  865. 'error',
  866. {
  867. allow: ['arrowFunctions', 'functions', 'methods'],
  868. },
  869. ],
  870. '@typescript-eslint/no-explicit-any': 'off',
  871. '@typescript-eslint/no-namespace': 'off',
  872. '@typescript-eslint/no-non-null-assertion': 'error',
  873. '@typescript-eslint/no-unused-expressions': 'off',
  874. '@typescript-eslint/no-unused-vars': [
  875. 'error',
  876. {
  877. argsIgnorePattern: '^_',
  878. varsIgnorePattern: '^_',
  879. },
  880. ],
  881. '@typescript-eslint/no-use-before-define': 'off',
  882. '@typescript-eslint/no-var-requires': 'error',
  883. 'unused-imports/no-unused-vars': 'off',
  884. },
  885. },
  886. // prettier 规则
  887. {
  888. plugins: {
  889. prettier: pluginPrettier,
  890. },
  891. rules: {
  892. 'prettier/prettier': 'warn',
  893. },
  894. },
  895. ]