安装eslint

  1. 如果项目不存在package.json,先npm init生成一个

    1
    npm init
  2. 保证nodejs版本为(^12.22.0、^14.17.0或>=16.0.0)

    1
    npm init @eslint/config
    1. 根据自定义选择会安装默认的插件以及生成默认的.eslintrc.js配置文件
    2. 我们是react+ts的项目,结合项目本身我们约定安装以下插件(其他类型项目再补充,如有vue项目需要添加适配vue的插件)
      • @typescript-eslint/eslint-plugin
      • @typescript-eslint/parser
      • eslint
      • eslint-plugin-react
      • eslint-plugin-react-hooks
      • eslint-plugin-prettier
      • eslint-config-prettier
  3. 简易运行检测命令

    1
    npx eslint yourfile.js
  4. package.json中加入通用命令

    1
    2
    3
    4
    "scripts": {
    "lint": "eslint --ext .js,.jsx,.tsx,.ts ./src",
    "lint-fix": "eslint --fix --ext .js,.jsx,.tsx,.ts ./src"
    }
  5. 使用eslint-loader/eslint-webpack-plugin+webpack对项目运行前检查,这里使用eslint-webpack-plugin

    1
    npm install eslint-webpack-plugin --save-dev
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const ESLintPlugin = require('eslint-webpack-plugin');

    module.exports = {
    // ...
    plugins: new ESLintPlugin({
    extensions: ['js', 'ts', 'jsx', 'tsx'], // 告诉插件要检查的文件类型
    failOnError: true, // fail时报错
    }),
    // ...
    };
  6. 辅助插件配置

  • vscode可以安装eslint插件对代码进行错误高亮提示

image.png

  • webstorm

配置文件约定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
// .eslintrc.js
module.exports = {
// 环境 衍生一些全局变量的使用 这些环境并不是互斥的,所以你可以同时定义多个
// 参考文档 https://eslint.org/docs/latest/use/configure/language-options
env: {
browser: true, // document 等语法
es2021: true, // WeakRef 等新语法 添加所有 ECMAScript 2021 全局变量并自动将ecmaVersion解析器选项设置为 12
commonjs: true, // require 等语法
node: true, // process 等语法
},
// 扩展包,包含了其他的配置,直接拿来用, 如plugin:prettier/recommended 包含
//{
// "extends": ["prettier"],
// "plugins": ["prettier"],
// "rules": {
// "prettier/prettier": "error",
// "arrow-body-style": "off",
// "prefer-arrow-callback": "off"
// }
// }
// 就不用重复声明了
extends: [
'eslint:recommended', // 使用eslint的推荐配置
'plugin:react/recommended', // 使用react的推荐配置
'plugin:react-hooks/recommended', // 使用react-hooks的推荐配置
'plugin:@typescript-eslint/recommended', // 使用typescript-eslint的推荐配置
'plugin:prettier/recommended', // 使用prettier的相关推荐配置
],
// 配置plugin:react的setting 指定react的版本为自动检测
settings: {
react: {
version: 'detect',
},
},
// 导入插件
// 参考文档 https://eslint.org/docs/latest/use/configure/plugins
// 上面extends时默认导入过了
// plugins: ['@typescript-eslint', 'react', 'react-hooks'],
// 覆盖配置 约定项目中不使用
// 参考文档 https://eslint.org/docs/latest/use/configure/configuration-files#how-do-overrides-work
overrides: [],
// 解析器
// 参考文档 https://eslint.org/docs/latest/use/configure/parser
parser: '@typescript-eslint/parser', // ts必须使用此解析器
// 解析器选项
// 参考文档 https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
root: true,
// 声明在代码中的自定义全局变量
globals: {},
rules: {
// typescript-eslint 参考文档 https://typescript-eslint.io/rules
// 使用 ts-ignore
'@typescript-eslint/ban-ts-comment': 2,
// // 空方法 里面没东西
// '@typescript-eslint/no-empty-function': 2,
// 使用了不正确的type 比如string使用了String
// '@typescript-eslint/ban-types': 2,
// import foo = require('foo'); // const foo = require('foo');
'@typescript-eslint/no-var-requires': 0,

// eslint-plugin-react 参考文档 https://github.com/jsx-eslint/eslint-plugin-react/tree/master/docs/rules
// 定义props的type
'react/prop-types': 1, // 后续改为2,修改的比较多,暂时动不了,约定后面的文件都用ts或者tsx

// eslint-plugin-react-hooks 参考文档 https://legacy.reactjs.org/docs/hooks-rules.html
// 不要在循环,条件或嵌套函数中调用 Hook
'react-hooks/rules-of-hooks': 'error',

// eslint-rules 参考文档 https://eslint.org/docs/latest/rules/
// 数组的 map、filter、sort 等方法,回调函数必须有返回值
'array-callback-return': 2,
// 不能在块外使用块作用域内 var 定义的变量
'block-scoped-var': 2,
// 禁止函数 if ... else if ... else 的复杂度超过20 先忽略
complexity: 0,
// this 的别名规则,只允许 self 或 that
'consistent-this': [2, '_this'],
// if 后必须包含 { ,单行 if 除外
curly: [2, 'multi-line', 'consistent'],
// switch 语句必须包含 default
'default-case': 2,
// 必须使用 === 和 !==
eqeqeq: 2,
// 禁止使用 eval
'no-eval': 2,

// catch 定义的参数禁止赋值
'no-ex-assign': 2,

// 禁止扩展原生对象
'no-extend-native': [2, { exceptions: ['Array', 'Object'] }],

// 禁止额外的 bind
'no-extra-bind': 2,

// 禁止额外的布尔值转换
'no-extra-boolean-cast': 2,
// 禁止额外的 label
'no-extra-label': 2,

// 禁止额外的括号
'no-extra-parens': 0,
// 禁止额外的分号
'no-extra-semi': 2,
// 每一个 switch 的 case 都需要有 break, return 或 throw
// 包含注释的情况下允许
'no-fallthrough': 2,
// 不允许使用 2. 或 .5 来表示数字,需要用 2、2.0、0.5 的格式
'no-floating-decimal': 2,
// 禁止对函数声明重新赋值
'no-func-assign': 2,

// 禁止对全局变量赋值
'no-global-assign': 2,
// 禁止使用隐式类型转换
'no-implicit-coercion': [
2,
{
allow: ['+', '!!'], // 允许 + 转数值 '' + 转字符串和 !! 转布尔值
},
],
// 禁止在 setTimeout 和 setInterval 中传入字符串,因会触发隐式 eval
'no-implied-eval': 2,

// 禁止隐式定义全局变量
'no-implicit-globals': 2,
// 禁止在块作用域内使用 var 或函数声明
'no-inner-declarations': 2,
// 禁止使用非法的正则表达式
'no-invalid-regexp': 2,
// 禁止使用无效的块作用域
'no-lone-blocks': 2,
// 连续空行的数量限制
'no-multiple-empty-lines': [
2,
{
max: 3, // 文件内最多连续 3 个
maxEOF: 1, // 文件末尾最多连续 1 个
maxBOF: 1, // 文件头最多连续 1 个
},
],
// 禁止使用混合的逻辑判断,必须把不同的逻辑用圆括号括起来
'no-mixed-operators': 2,
// 禁止使用 new Object
'no-new-object': 2,

// 禁止使用 new Symbol
'no-new-symbol': 2,

// 禁止 new Boolean、Number 或 String
'no-new-wrappers': 2,

// 禁止 new 一个类而不存储该实例
'no-new': 2,

// 禁止把原生对象 Math、JSON、Reflect 当函数使用
'no-obj-calls': 2,
// 禁止对函数的参数重新赋值
'no-param-reassign': 0,
// 禁止将自己赋值给自己
'no-self-assign': 2,
// 禁止自己与自己作比较
'no-self-compare': 2,
// 禁止使用保留字作为变量名
'no-shadow-restricted-names': 2,
// 禁止在嵌套作用域中出现重名的定义,如 let a; function b() { let a }
'no-shadow': 2,
// 禁止数组中出现连续逗号
'no-sparse-arrays': 0,
// 禁止不必要的三元表达式
'no-unneeded-ternary': 2,
// 循环体内必须对循环条件进行修改
'no-unmodified-loop-condition': 2,
// 禁止定义不使用的 label
'no-unused-labels': 2,
// 禁止无效的重命名,如 import {a as a} from xxx
'no-useless-rename': 2,
// 禁止使用 var,必须用 let 或 const
'no-var': 2,
// 未使用时不能用let必须用const
'prefer-const': 2,
// 禁止属性前出现空格,如 foo. bar()
'no-whitespace-before-property': 2,
// 禁止 if 语句在没有花括号的情况下换行
'nonblock-statement-body-position': 2,
// 是否允许使用逗号一次声明多个变量
'one-var': [
2,
{
const: 'never', // 所有 const 声明必须独占一行,不允许用逗号定义多个
},
],
// ...后面不允许有空格
'rest-spread-spacing': 2,
// 禁用严格模式,禁止在任何地方出现 'use strict'
strict: [2, 'never'],
// 禁止直接对 NaN 进行判断,必须使用 isNaN
'use-isnan': 2,
// 禁止Yoda格式的判断条件,如 if (true === a),应使用 if (a === true)
yoda: 2,
// 禁止使用 console,提醒开发者,上线时要去掉
'no-console': 0,
// 禁止对 const 定义重新赋值
'no-const-assign': 2,
// 函数参数禁止重名
'no-dupe-args': 2,
// 禁止对象出现重名键值
'no-dupe-keys': 2,
// 禁止重复 import
'no-duplicate-imports': 2,
// 不要从目标对象访问 Object 原型方法 obj.hasOwnProperty('key')
'no-prototype-builtins': 2,
// 一行代码同时缩进了制表符和空格
'no-mixed-spaces-and-tabs': 2,
'no-debugger': process.env.NODE_ENV === 'development' ? 'off' : 'error', // dev环境可以使用 其他环境禁止
},
}