Fork me on GitHub

关于ESLint

  ESLint给我个人的体验在于,它能将编程风格不同的程序员写出来的代码尽量格式化统一成像是一个人写的代码。这样的好处在于后期维护人员能较为轻松地进行代码阅读,无论是要进行代码优化亦或是DEBUG。当然这仅是代码风格上的约束,也可以称之为软约束。那硬约束是什么?我认为ESLint带来最大的提升是在拼写错误校验、冗余模块引入检测上的。相信很多人都被自己错误拼写变量造成的魔幻BUG坑过,还有冗余依赖引入造成的代码体积扩大等等。

  ESLint就可以帮我们规避这些问题。通常ESLint的应用是双重结合的,第一重是在我们coding的编辑器(本人是VSCode)内安装插件,检测到不符合规则的标红警告;第二重则是在代码commit时提示问题,并拦截提交(这个需要介入hooks使用,后文会聊)。

坑:git commit –no-verify

  为什么要说--no-verify,因为这个git commit的配置项有毒。由于一些历史原因,负责的部分项目一直都是通过git commit -nm进行代码提交…这个操作骚就骚在它能绕过pre-commitcommit-msg的周期钩子,也就是说它能直接跳过我们的ESLint检测。emm,我其实有尝试过正常校验,但是处理完毕后自动格式化了几百个文件,然后…就没有然后了,毕竟没有人想背锅(所以说构建项目的底子一定要硬)。

配置ESLint

  当前主要技术栈为React,而社区内对React项目的ESLint已经有非常多成熟的方案了,这里使用airbnb的规则来做一个说明:

  1. 查看我们要安装的eslint-config-airbnb@latest的依赖:npm info "eslint-config-airbnb@latest" peerDependencies

  2. 根据上图的关联依赖统一通过@版本号安装。

  3. 在项目根目录创建.eslintrc.js,写入配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
root: true,
extends: ['airbnb'],
parserOptions: {
ecmaFeatures: {
generators: true,
},
},
env: {
browser: true,
},
rules: {
// ...自定义配置
},
}

VSCode

  在VSCode的左边栏的扩展项内,我们可以配套安装ESLint的插件:

  安装后,它会自动应用我们前文加入的配置规则,另外一些编辑器内的如不符合标准标红、ctrl + s保存代码自动修复格式等功能需要在File -> Preferences -> Settings中,搜索ESLint定制配置:

  简单测试一下,减少一个空格:

  保存代码自动格式化:

实践出真坑

  以上弄完了,我们就可以开始踩坑了…

Expected linebreaks to be 'LF' but found 'CRLF'.

  这个问题是由于LinuxWindows换行符不同所致,在Linux中使用的是\n,对应LF;在Windows中使用的是\r\n,对应CRLF。处理方案:

1
2
3
4
rules: {
...,
["linebreak-style"]: [0, 'error', 'windows'], // 在windows环境下关闭该检测
}

Unary operator '++' used.

  ESLint认为++--这些操作在前后存在空格换行的运算中有语义变化的风险,由于JS引擎本身会根据语句去自动插入分号,所以有以下的解析歧义例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var i = 10;
var j = 20;

i ++
j
// i = 11, j = 20

var i = 10;
var j = 20;

i
++
j
// i = 10, j = 21

  当然如果团队的开发人员能够深刻理解该潜在风险,我们也可以在rules中配置禁止:

1
2
3
4
rules: {
...,
'no-plusplus': [0, 'error'],
}

JSX中的Parsing error: Unexpected token {

  由于我使用的是React,在变量写入花括号的时候报了这个校验问题,在社区上看到了相关的内容:ESLint如果单独使用就会存在种种困扰,比如兼容性上的坑,像在这种情况下我们需要先安装babel-eslint->npm i -D babel-eslint,再在.eslintrc.js内配置parser: 'babel-eslint',具体讨论见传送门

Expected indentation of 12 space characters but found 14.

  缩进问题,撸过py的朋友应该知道其实真正的缩进应该是一个tab对应两个space的长度,而在windows下通常是一对四,则我们需要在rules中定制一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rules: {
'no-tabs': 'off',
'no-mixed-spaces-and-tabs': 'off', // 禁止空格TAB混用报错,这个其实在设置了VSCODE的TAB控制后可以去掉了
'indent': [
'error',
'tab'
],
'react/jsx-indent': [
'error',
'tab'
],
'react/jsx-indent-props': [
'error',
'tab'
],
}

Expected indentation of 1 tab but found 4 spaces.

  这个也挺坑的,同样我们要去Settings中配置。相当于把缩进用空格补位的给关了:

JSX not allowed in files with extension '.js'

  JSX的使用需要我们手动设置兼容的后缀文件,'react/jsx-filename-extension': [1, { 'extensions': [".js", '.jsx'] }]

提交拦截

  这一步需要我们介入Hooks,玩过React、Vue的人都对Hooks这个术语有所了解,其实就是对应一个完整的流程中的各个阶段(不同阶段有对应的处理逻辑)。同理,我们要在提交前去根据校验规则拦截住当前不符合规则的部分,我们就需要介入git hooks中的pre-commit部分。

  我们在项目根目录的隐藏文件夹.git内找到相关的一些hooks

  具体步骤:
  ① npm i -D pre-commit
  ② package.json中配置scripts,写入操作key,这个要与pre-commit配置项中的对应。
  ③ 对src路径下的jsjsx检查:"lint": "eslint --ext .js --ext .jsx src"
  ④ pre-commit的值为数组格式,支持多个,这里我们直接塞前面配的lint进去:"pre-commit": ["lint"]

  尝试在有格式校验问题的情况下提交:

  从上图我们可以得知本次提交并没有通过我们定制的hooks环节,并且输出了具体文件具体代码的问题定位,修改成符合规范的即可。

基础的Rules语法

  由于我们在.eslintrc.jsextendsairbnb的配置规则可能有些不满足我们的需求,需要调整。这种情况下,就需要我们自定义地重写或新增rules规则。

  具体的rules配置可以直接去官方文档查阅,这里只讲一些基础的语法认知。rules作为自定义规则,内部的元素都是以k-v格式构成,key为定制的规则名,value则是我们具体设置的校验,可以是字符串或数组,如果仅是设置规则开关,字符串格式就可以满足:

  off0表明规则禁用。
  warn1表明规则警告,该设置仅会提供警告信息,如IDE中标记,控制台输出,但是不会影像hooks中的exit code(用来判定是否可以进入下一阶段,是否能够提交)。
  error2表明规则开启,该设置下规则不通过的无法提交。

  如果是复合情况就比较复杂,首先value是数组格式,第一个参数还是以上的规则开关标志,其后的参数可以是字符串也可以是对象,具体要看对应key给出的支持情况。e.g.

1
2
3
/*eslint object-curly-spacing: ["error", "always", { "arraysInObjects": false }]*/
/* eslint implicit-arrow-linebreak: ["error", "below"] */
/*eslint linebreak-style: ["error", "windows"]*/