使用 ESlint、lint-staged 半自動提升項目代碼質量

最近在項目部署了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
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容