Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

利用 ESlint、lint-staged 半自动提升项目代码质量 #4

Open
zhangyu921 opened this issue Nov 16, 2017 · 1 comment
Open
Labels

Comments

@zhangyu921
Copy link
Owner

zhangyu921 commented Nov 16, 2017

最近在项目部署了ESlint还有一些配套的工具,比如 prettier husky lint-staged,有些心得写出来分享下。

依据本篇可以实现在git commit之时,重新格式化代码,同时进行代码检查预防一些低级错误。最终期待项目中的开发人员提交到线上的代码符合代码规范、风格统一,看起来像是一个人写的。

实现过程

-> 待提交的代码
-> git add 添加到暂存区
-> 执行 git commit
-> husky注册在git pre-commit的钩子调起 lint-staged
-> lint-staged 取得所有被提交的文件依次执行写好的任务(ESLint 和 Prettier)
-> 如果有错误(没通过ESlint检查)则停止任务,等待下次commit,同时打印错误信息
-> 成功提交

嗯……这个任务链看起来挺长的,但不要怕,也只是需要装的模块有点多罢了。
可以看成两个部分,代码整理部分、pre-commit 函数部分。

husky 注册 git hook

安装

npm i --save-dev husky lint-staged

添加 hook 函数

// package.json
{
...
    "scripts": {
        ...
        "precommit": "lint-staged", // git commit 执行这个命令,这个命令在调起 lint-staged
    },
    "lint-staged": {   // lint-staged 配置
        "app/**/*.{js,jsx}": [
            "prettier --tab-width 4 --write",
            "eslint --fix",
            "git add"
        ]
    },
...
}

这里 lint-staged 的配置是:在 git 的待提交的文件中,在 app 目录下的所有 .js .jsx 都要执行三条命令。前两条一会儿说,后一条是将处理过的代码重新 add 到 git 中。

粘贴的时候记得删掉注释,我们知道JSON是没有注释的

prettier 格式化代码

prettier 是强大的代码格式化工具,目的是统一团队的代码格式。相对于 ESlint 代码检查能力较弱。

安装

npm i --save-dev --save-exact prettier 

然后……就完成了~ 🎉🎉🎉

这里解释下刚才写在 lint-staged 里的命令参数

prettier --tab-width 4 --write

--tab-width 4 :使用4个空格作为缩进 (嗯,我更喜欢2个,不过……我们的代码规范是4个 😷)
如果想用tab作为缩进可以加上--use-tabs, 这时--tab-width代表tab数量。

--write:默认prettier是直接标准输出到终端的,这个配置代表直接改写文件。

关于prettier的还有一些配置参考这里

ESLint

ESLint 相对来说是比较复杂的部分,很多次我都被繁多的规则和海量的报错吓退过,但好在概念很容易理解,在翻看别的开源项目的时候,发现真正要自行配置的规则也不过尔尔。

而ESLint的作用主要是为了检查代码有没有错误,有没有不和代码规范的地方。虽然 ESLint 有 --fix 的选项,可以自动修复一些格式上的问题,但程度并不能和 Prettier 相当。

Prettier的概念更像是无论你怎么写,走到我这里,都会被格式成我这一种样子。而ESLint 只在发现问题的地方进行 fix,这是两者在逻辑上有区别。

配置 ESLint 主要是配置规则,规则从何而来,那当然是人写的。所以我们在很多项目里都能见到类似 .eslintrc.json等类似的文件,这就是 ESLint 的配置文件。建议是初始化后一点一点修改这个配置文件,不要照抄Airbnb等等类似的规范,不然上来可能就报非常多的错误,一看就头大。

安装:

npm install --save-dev eslint 

// 如果项目使用了 React 需要再安一个 babel-eslint
npm install --save-dev eslint babel-eslint

ESLint 也可以全局安装,全局安装后可以方便用 ESLint 直接执行。

ESLint 初始化

ESLint 初始化可以帮助开发者快速生成一个基本的配置框架。

在项目文件夹下执行

node_modules/.bin/eslint --init
// 如果全局安装了 可以直接 eslint --init

这里会给我们三种方式来初始化ESlint

image

分别是 1. 问问题 2. 使用大厂的 3. 检查现有的代码自动生成

�我们这里直接选第一个,回答一些问题来确定配置。

image

根据实际情况回答就好了,即使不小心答错也没关系,都在配置文件里随时可以修改。
image

部分同学可能有疑惑关于line endings ,其实看一下编辑器下面,如果是 LF 选择 Windows,CR 就选 Linux 就好了 。这个关于windows和linux对换行符的定义不同导致的,有兴趣的同学可以自己搜搜。

image

生成的.eslintrc.json 根据选择的回答不同,大体都长这样

{
    "env": { 
        "browser": true,
        "commonjs": true,
        "es6": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaFeatures": {
            "experimentalObjectRestSpread": true,
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "windows"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
}

ESLint 配置解释:

env: Environments,指定代码的运行环境。不同的运行环境,全局变量不一样,指明运行环境这样ESLint就能识别特定的全局变量。同时也会开启对应环境的语法支持,例如:es6。

parser:ESLint 默认使用Espree作为其解析器,但它并不能很好的适应 React 环境,所以刚才安装了 babel-eslint 用来代替默认的解析器,在配置里这么写"parser": "babel-eslint"

plugins:顾名思义就是插件,插件是单独的npm包,命名一般以eslint-plugin开头,写的时候用字符串数组的形式,可以省略eslint-plugin开头。plugins一般包含一个或多个规则配置,可以在extends中引入。

extends:ESLint 不需要自行定义大量的规则,因为很多规则已被分组作为一个规则配置。

例如:eslint:recommended就是 ESLint 的推荐规则配置,包含了ESLint的规则 里前面有✔︎的部分,recommended 规则只在ESLint升级大版本的才有可能改变。

相对的 eslint:all 是应用所有的规则,但并不推荐这么做。另外,all 规则是根据版本随时变化的。
extends 还可以以字符串数组的形式定义。

"extends": ["eslint:recommended", "plugin:react/recommended"],

plugin:react/recommended 即为 eslint-plugin-react 插件中的提供的推荐规则配置

另外还有一点,extends定义的规则如果有重复的,后面的规则会覆盖前面的。

rules:这里可以对规则进行细致的定义了,覆盖之前前面说的extends中定义的规则。例如 indent就是对缩进的修改。"indent": ["error",4] 前面一项代表错误等级,第二项是具体配置,有些规则有第三项选项,例如 indent 就有 { "SwitchCase": 1 },代表对switch语句采取什么样的缩进策略,如果不设默认是0。具体可以定义什么 rules,可以参考这里

错误等级有三级 012,分别代表offwarningerror。error错误会终止 lint-staged 执行。

globals:全局变量,如果你的项目用到其他一些自定义的全局变量,"__DEV__": false这样配置,true
和 false 代表可不可以被修改。

其他可用的配置参考这个

React Native 项目的配置例子

{
  "parser": "babel-eslint",
  "env": {
    "commonjs": true,
    "es6": true,
    "react-native/react-native": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true,
      "jsx": true
    },
    "sourceType": "module"
  },
  "plugins": [
    "react",
    "react-native",
  ],
  "rules": {
    "no-unused-vars": 1,
    "react/prop-types": 1,
    "react/display-name": 0,
  }
}

后面跟了一堆是全局变量,没有使用 react-native 的 config 是因为到目前还不适配 ESLint 4版本。
eslint-plugin-react-native已经更新了,这样配置又简洁了一些。

调试配置

配置肯定是不能拿来就用的,推荐先就只使用 eslint:recommended 版本,如果你的项目 indent 比较特殊,再到 rules 定义 indent 就可以了。

然后先用命令行命令先对代码库里比较典型文件测试一下

node_modules/.bin/eslint app/app.js --fix

加上 --fix 会自动修复一些问题,规则列表里前面有小扳手的是可以自动修复的。

image

不用担心,一开始肯定特别多。根据报错信息最后的规则名称,搜索搞清楚到底是为什么错,看这个错误对于你的项目库是什么程度,再到rules里去自定义这条规则。

处理好这一步,就完成部署 commit 自动处理代码的流程了。如果代码没有通过 ESLint 检查,就会出现这种通知,停止commit。

Webstorm
Webstorm

Terminal
image

Webstorm 插件

从前面看出 Webstorm的通知是不太友好的,我们可以用Webstorm的配置,方便更快的找到错误的发生点(但不是必须的)。

内置了ESlint工具

Webstorm 内置了ESlint工具,启动之后可以在编辑的时候就能看到哪里出错需要修复。

image

选好 Node 环境路径和 ESLint 包路径,勾线Enable就好了,会自动寻找ESLint的配置。
ESlint 路径:~/Documents/{Your Project}/node_modules/eslint

还可以在快捷键设置里给 Fix ESLint Problem 添加一个快捷键,快速进行代码格式化的操作。

image

个人感觉在检查代码出错的时候比较好用,但在实际写代码的时候我个人还是倾向于不开这个来写,经常看到报错信息,令人心情不好。

External Tools

我更倾向于自己写一个 External Tools ,方便对当前文件执行命令,在提交之前或者提交报错之后跑一遍,有详细的报错清单,找起来也很方便(但没打开ESLint设置看起来更直观)。

image

下面三项填入

node_modules/.bin/eslint
--fix $FilePathRelativeToProjectRoot$
$ProjectFileDir$

External Tools 可以设置快捷键,也可以通过 Webstorm 的命令面板搜索打开 cmd + shift + a

image

image

@zhangyu921 zhangyu921 changed the title 如何利用 ESlint 提升项目代码质量 利用 ESlint、lint-staged 半自动提升项目代码质量 Nov 22, 2017
@zhangyu921
Copy link
Owner Author

预告下,准备更新 eslint-plugin-prettier 和 eslint-config-prettier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant