.eslintrc.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. console.log(
  2. '\x1B[0;37;44m INFO \x1B[0m',
  3. '\x1B[0;;34m ' +
  4. `读取了: ${__filename.slice(__dirname.length + 1)}` +
  5. ' \x1B[0m'
  6. );
  7. module.exports = {
  8. root: true,
  9. settings: {
  10. 'import/parsers': {
  11. '@typescript-eslint/parser': ['.ts', '.tsx'],
  12. },
  13. 'import/resolver': {
  14. typescript: {
  15. alwaysTryTypes: true, // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
  16. project: './tsconfig.json',
  17. },
  18. },
  19. },
  20. env: {
  21. browser: true,
  22. node: true,
  23. },
  24. extends: [
  25. // 'airbnb-base', // airbnb的eslint规范,它会对import和require进行排序,挺好的。如果不用它的话,需要在env添加node:true
  26. 'eslint:recommended',
  27. 'plugin:import/recommended',
  28. 'plugin:vue/vue3-essential', // plugin:vue/vue3-essential或plugin:vue/vue3-strongly-recommended或plugin:vue/vue3-recommended'
  29. '@vue/eslint-config-typescript', // 启用这个规则后,vscode保存文件时格式化很慢
  30. // '@vue/eslint-config-typescript/recommended', // 启用这个规则后,vscode保存文件时格式化很慢
  31. '@vue/eslint-config-prettier',
  32. ],
  33. parser: 'vue-eslint-parser',
  34. parserOptions: {
  35. parser: '@typescript-eslint/parser',
  36. ecmaVersion: 'latest',
  37. ecmaFeatures: {
  38. jsx: true,
  39. },
  40. tsconfigRootDir: __dirname, // https://typescript-eslint.io/docs/linting/typed-linting
  41. project: ['./tsconfig.json'], // https://typescript-eslint.io/docs/linting/typed-linting
  42. },
  43. plugins: ['import'],
  44. // overrides: [],
  45. // rules会覆盖extends里面的规则(https://eslint.org/docs/latest/user-guide/migrating-to-6.0.0#-overrides-in-an-extended-config-file-can-now-be-overridden-by-a-parent-config-file)
  46. // rules里面的规则不会对overrides里面的文件生效
  47. rules: {
  48. /**
  49. * 0 => off
  50. * 1 => warn
  51. * 2 => error
  52. */
  53. 'no-shadow': 0, // 禁止变量声明与外层作用域的变量同名
  54. 'class-methods-use-this': 0, // 类方法如果不使用this的话会报错
  55. 'no-console': 0, // 此规则不允许调用console对象的方法。
  56. 'spaced-comment': ['error', 'always', { exceptions: ['-', '+'] }], // 该规则强制注释中 // 或 /* 后空格的一致性
  57. 'no-var': 2, // 要求let或const代替var
  58. camelcase: [
  59. 'error',
  60. { properties: 'never' }, // properties默认always,即检查属性名;可以设置为never,即不检查属性名
  61. ], // 强制执行驼峰命名约定
  62. 'no-underscore-dangle': 2, // 此规则不允许在标识符中使用悬空下划线。
  63. 'no-param-reassign': 2, // 禁止对 function 的参数进行重新赋值
  64. 'no-nested-ternary': 2, // 禁止嵌套三元
  65. 'no-plusplus': 2, // 禁用一元操作符 ++ 和 --
  66. 'no-unused-vars': 0, // 禁止出现未使用过的变量
  67. 'vars-on-top': 2, // 要求所有的 var 声明出现在它们所在的作用域顶部
  68. 'prefer-const': 2, // 要求使用 const 声明那些声明后不再被修改的变量
  69. 'prefer-template': 2, // 要求使用模板字符串代替字符串连接
  70. 'new-cap': 2, // 要求构造函数名称以大写字母开头
  71. 'no-restricted-syntax': [
  72. // 禁用一些语法
  73. 'error',
  74. // 'ForInStatement',
  75. // 'ForOfStatement',
  76. {
  77. selector: 'ForInStatement',
  78. /**
  79. * 用 map() / every() / filter() / find() / findIndex() / reduce() / some() / ... 遍历数组,
  80. * 和使用 Object.keys() / Object.values() / Object.entries() 迭代你的对象生成数组。
  81. * 拥有返回值得纯函数比这个更容易解释
  82. */
  83. message:
  84. 'for in会迭代遍历原型链(__proto__),建议使用map/every/filter等遍历数组,使用Object.{keys,values,entries}等遍历对象',
  85. },
  86. {
  87. selector: 'ForOfStatement',
  88. message:
  89. '建议使用map/every/filter等遍历数组,使用Object.{keys,values,entries}等遍历对象',
  90. },
  91. ], // https://github.com/BingKui/javascript-zh#%E8%BF%AD%E4%BB%A3%E5%99%A8%E5%92%8C%E5%8F%91%E7%94%9F%E5%99%A8
  92. 'no-iterator': 2, // 禁止使用__iterator__迭代器
  93. 'require-await': 2, // 禁止使用不带 await 表达式的 async 函数
  94. 'no-empty': 2, // 禁止空块语句
  95. 'guard-for-in': 2, // 要求for-in循环包含if语句
  96. 'global-require': 2, // 此规则要求所有调用require()都在模块的顶层,此规则在 ESLint v7.0.0中已弃用。请使用 中的相应规则eslint-plugin-node:https://github.com/mysticatea/eslint-plugin-node
  97. 'no-unused-expressions': [
  98. 2,
  99. {
  100. allowShortCircuit: true, // 允许短路
  101. allowTernary: true, // 允许三元
  102. },
  103. ], // 禁止未使用的表达式,即let a = true && console.log(1)允许,但是true && console.log(1)不行
  104. 'object-shorthand': ['error', 'always'], // (默认)希望尽可能使用速记。var foo = {x:x};替换为var foo = {x};
  105. 'no-useless-escape': 2, // 禁止不必要的转义字符
  106. // eslint-plugin-import插件
  107. // https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md
  108. 'import/order': [
  109. 'error',
  110. {
  111. groups: [
  112. 'builtin', // 如:import fs from 'fs';
  113. 'external', // 如:import _ from 'lodash';
  114. 'internal', // 如:import foo from 'src/foo';
  115. 'parent', // 如:import foo from '../foo';
  116. 'sibling', // 如:import bar from './bar';
  117. // ['sibling', 'parent'],
  118. // ['parent', 'sibling'],
  119. 'index', // 如:import main from './';
  120. 'object', // 如:import log = console.log;
  121. 'type', // 如:import type { Foo } from 'foo';
  122. ],
  123. pathGroups: [
  124. {
  125. pattern: '@/**',
  126. group: 'internal',
  127. },
  128. ],
  129. 'newlines-between': 'always', // 强制或禁止导入组之间的新行
  130. // 根据导入路径以字母顺序排列每个组中的顺序
  131. alphabetize: {
  132. order: 'asc', // 使用asc按升序排序,使用desc按降序排序(默认值:ignore)。
  133. caseInsensitive: true, // 使用true忽略大小写,而false考虑大小写(默认值:false)。
  134. orderImportKind: 'asc', // 使用asc以升序对各种导入类型进行排序,例如以type或typeof为前缀的导入,具有相同的导入路径。使用desc按降序排序(默认值:忽略)
  135. },
  136. },
  137. ],
  138. 'import/newline-after-import': 2, // 强制在最后一个顶级导入语句或 require 调用之后有一个或多个空行
  139. 'import/no-extraneous-dependencies': 2, // 禁止导入未在package.json中声明的外部模块。
  140. /**
  141. * a.js
  142. * export const version = '1.0.0';
  143. * export const bar = { name: 'bar', version };
  144. * export default bar;
  145. * b.js
  146. * import bar from './a';
  147. * console.log(bar.version); // 检测到你使用的version有具名导出,import/no-named-as-default-member就会提示`import {version} from './a'`
  148. */
  149. 'import/no-named-as-default-member': 1, // https://github.com/import-js/eslint-plugin-import/blob/v2.26.0/docs/rules/no-named-as-default-member.md
  150. /**
  151. * import/named
  152. * 在import { version } from 'vuex';的时候会验证vuex有没有具名导出version,
  153. * 但是在vue3的时候,import { defineComponent } from 'vue';会报错defineComponent not found in 'vue'
  154. * 因此vue3项目关闭该规则
  155. */
  156. // 'import/named': 0,
  157. // 'import/prefer-default-export': 0, // 当模块只有一个导出时,更喜欢使用默认导出而不是命名导出。
  158. // 'import/extensions': 0, // 确保在导入路径中一致使用文件扩展名。在js/ts等文件里引其他文件都不能带后缀(比如.css和.jpg),因此关掉
  159. // 'import/no-unresolved': 0, // 不能解析带别名的路径的模块,但实际上是不影响代码运行的。找不到解决办法,暂时关掉。
  160. /**
  161. * a.js
  162. * export const bar = 'bar';
  163. * export const foo = 'foo';
  164. * export default foo;
  165. * b.js
  166. * import bar from './a'; // import/no-named-as-default规则会报错,因为import/no-named-as-default规则误以为你将具名导出的bar作为了默认导出来使用,但是实际上可能我就是想用默认导出的foo
  167. * // import barr from './a'; // 改个名字import/no-named-as-default规则就不会报错了。
  168. * // 不幸的是,React + Redux 是最常见的场景。但是,还有很多其他情况,HOC 会迫使开发人员关闭此规则。https://github.com/import-js/eslint-plugin-import/issues/544#issuecomment-245082471
  169. */
  170. 'import/no-named-as-default': 0, // https://github.com/import-js/eslint-plugin-import/blob/v2.26.0/docs/rules/no-named-as-default.md
  171. // @typescript-eslint插件
  172. '@typescript-eslint/no-unused-vars': 2,
  173. '@typescript-eslint/restrict-template-expressions': [
  174. 'error',
  175. {
  176. allowBoolean: true,
  177. allowNumber: true,
  178. },
  179. ], // 强制模板文字表达式为string类型。即const a = {};console.log(`${a}`);会报错
  180. '@typescript-eslint/no-floating-promises': 0, // 要求适当处理类似 Promise 的语句。即将await或者return Promise,或者对promise进行.then或者.catch
  181. '@typescript-eslint/no-explicit-any': 0, // 不允许定义any类型。即let a: any;会报错
  182. '@typescript-eslint/no-non-null-assertion': 0, // 禁止使用非空断言(后缀运算符!)。即const el = document.querySelector('.app');console.log(el!.tagName);会报错
  183. '@typescript-eslint/ban-ts-comment': 0, // 禁止使用@ts-<directive>注释
  184. '@typescript-eslint/no-unsafe-assignment': 0, // 不允许将具有类型的值分配any给变量和属性。即const a: any = {};const b = a;会报错
  185. '@typescript-eslint/no-unsafe-argument': 0, // 不允许用any类型的值调用一个函数。即let a: any;Object.keys(a);会报错
  186. '@typescript-eslint/no-unsafe-member-access': 0, // 不允许对类型为any的值进行成员访问。即const a: any = [];console.log(a[0]);会报错
  187. '@typescript-eslint/no-unsafe-return': 0, // 不允许从一个函数中返回一个类型为any的值
  188. '@typescript-eslint/no-unsafe-call': 0, // 不允许调用any类型的值
  189. '@typescript-eslint/no-var-requires': 0, // 即不允许var foo = require('foo');。但是允许import foo = require('foo');
  190. '@typescript-eslint/restrict-plus-operands': 0, // 要求加法的两个操作数是相同的类型并且是bigint, number, 或string。即const a = '1';console.log(a + 1);会报错
  191. // vueeslint插件
  192. 'vue/multi-word-component-names': 0,
  193. },
  194. };