1. 程式人生 > 實用技巧 >從零開始 eslint(一)

從零開始 eslint(一)

概述

eslint 是用來在 js 檔案中識別和報告模式匹配的工具,它的目的是保證程式碼的一致性和避免錯誤。我們可以在編碼的過程中配合相關的程式碼編輯工具提前發現錯誤或者不規範的程式碼,例如我們可以在 vscode 中直接看到不符合規則程式碼段;也可以配合相關的命令列工具執行程式碼檢查並且發現錯誤,例如在 webpack 執行程式碼構建的過程中發現不符合規範的錯誤並且報告錯誤。

使用

eslint 的使用很方便,如果我們要在編碼的過程中發現提前發現錯誤,我們需要配合相關的程式碼編輯器使用。下面以 vscode 為例做一個使用說明。

  1. 在 vscode 擴充套件程式中安裝 eslint 擴充套件,並且啟用擴充套件
  2. 在專案根路徑下(這裡涉及到 eslint 配置檔案的優先順序問題,後面會做說明) 編寫 eslint 配置檔案

只需要上面簡單兩步就可以達到在編輯器中提示錯誤的目的。但是如果你需要使用命令列工具檢查錯誤,你需要本地或者全域性安裝 eslint,然後通過 eslint 提供的 cli 相關命令達到程式碼檢查的目的。在我們的專案中通常需要兩種方式同時使用,這樣我們就需要在上面兩步的基礎之上在專案中安裝 eslint(或者全域性安裝)。下面做一個完整的例項說明:

  1. 本地安裝

    # 專案根目錄下執行以下命令 project
    
    npm install eslint -D
    
  2. 編寫 eslint 配置檔案

    // project/.eslintrc.js
    
    module.exports = {
      rules: {
        'no-console': 'error'
      }
    }
    
  3. 在編輯器中編寫程式碼如下

    // project/src/index.js
    
    console.log(123)
    

    然後我們可以看到如下錯誤

  4. 在命令列錯誤提示,執行如下命令

    # 本地安裝
    npx eslint src/index.js
    
    # 如果是全域性安裝可以直接執行
    eslint src/index.js
    

    我們可以在命令列中看到如下錯誤

    上面幾個簡單的操作我們就可以實現 eslint 的錯誤提示功能

除了上面的使用方式,還可以根據需要以 nodejs API 的方式使用 eslint

配置說明

1. 支援的配置方式

在專案中可以使用兩種方式來對 eslint 進行配置

  • 通過 js 註釋的方式進行配置,例如:

    // eslint-disable-next-line no-console
    console.log(123)
    
  • 通過配置檔案的方式進行配置,配置檔案支援的多種格式的檔案,如果存在多個只會採用一個,優先順序順序如下:

    • .eslintrc.js
    • .eslintrc.yaml
    • .eslintrc.yml
    • .eslintrc.json
    • package.json

如果存在多個配置檔案,將會按照上面的順序決定配置項,只會按照順序選擇優先順序最高的配置檔案。除此之外,還有層疊規則,層疊的意思也就是說多個配置檔案會進行規則合併,優先順序高的會覆蓋優先順序低的規則。下面看幾個例子來說明優先順序規則和層疊規則。

project
|—— src
|   |—— .eslintrc.yaml
|   |—— index.js
|—— .eslintrc.js
|—— .eslintrc.json

上面這種目錄結果中 eslint 規則作用於 index.js 檔案的規則可以描述為:

  • 根據優先順序規則,project/.eslintrc.json 檔案中的 eslint 規則不會起任何作用
  • 根據層疊規則,project/src/.eslintrc.yaml 會與 project/.eslintrc.js 規則合併,並且 project/src/.eslintrc.yaml 中的同名規則會覆蓋 project/.eslintrc.js

如果不希望外層的規則生效,可以在內層的配置檔案中新增 root 屬性為 true。

2. 支援的配置項

相容到 eslint 的靈活性,可以通過配置檔案的方式對 eslint 每一條規則進行配置。一般來說一個 eslint 配置檔案具有以下基本配置。

2.1 parserOptions

該配置項允許你設定你想要支援的 js 語言選項。考慮到 es 存在多個版本,且語法不盡相同,所以你可以在這個配置項中指定所需要支援的 es 版本。一個完整的配置可以參考下面:

module.exports = {
  "parserOptions": {
    // 需要支援的 es 版本,選擇不同的版本將可以支援不同版本的語法特性,例如如果指定 ecmaVersion = 3,則無法支援 es6 中新的語法特性,像 const、let 都無法支援
    "ecmaVersion": 2015,

    // 表示你想支援額外的語言特性
    "ecmaFeatures": {
      // js 檔案中允許使用 jsx
      "jsx": true,

      // js 檔案中允許使用全域性 return
      "globalReturn": true,

      // 全域性嚴格模式
      "impliedStrict": true
    },
    "sourceType": "module"
  }
}

下面通過一個例子對 ecmaVersion 做個說明,對於下面這段程式碼不同的 ecmaVersion 會有不同的檢查結果

const {x, y, ...rest} = {x: 1, y: 2, a: 3, b: 4}

如果配置檔案中設定的 ecmaVersion 在 2018 以下,將會報錯

error Parsing error: Unexpected token ..

如果 ecmaVersion 不低於 2018 將會 lint 成功

2.2 parser

通過 parser 可以指定一個程式碼解析器,eslint 預設使用的程式碼解析器是 esprima,解析器的作用是將符合 ecma 規範的程式碼轉換成抽象語法樹。常見的程式碼解析器除了 esprima 之外還有 babel 所使用的 babylon 以及 webpack 核心所使用的 acron,但是在 eslint 中指定的解析器需要滿足特定的條件,所以無法直接使用 babylon 和 acron,目前我們在 eslint 中常用的程式碼解析器有 @babel/eslint-parse 和 @typescript-eslint/parser。配置示例如下:

module.exports = {
  "parser": "@typescript-eslint/parser",
  "rules": {
    "semi": "error"
  }
}

通常我們在對 ts 檔案進行程式碼檢查的時候需要用到 @typescript-eslint/parser,否則會出現 esprima 無法解析語法而導致報錯。

2.3 processor

當我們需要為一些非 js 檔案型別執行eslint 規則的檢查時,需要為這些檔案型別指定一個解析器,解析器可以用來將非 js 型別的檔案轉換成為可以被 eslint parser 所識別的語法,但是 processor 不能作為獨立的配置項在使用,必須放在 plugins 中。例如想要對 json 檔案像 js 檔案一樣使用 eslint 規則檢查,需要使用一個 plugin,plugin 中需要匯出固定的內容。看一下 eslint-plugin-json-processor 的實現。

module.exports = {
  processors: {
    '.json': {
      preprocess: function(text, filename) {
        return [
            { text: `(${ text })`, filename: filename },
        ]
      },

      supportsAutofix: false
    }
  }
}

eslint 在執行的過程中會根據 processors 的 key 進行匹配,如果跟所要檢查的檔案字尾相同,則會執行對應的解析器。

如果需要使用 eslint-plugin-json-processor 需要按照如下的方式:

module.exports = {
  plugins: [
    'eslint-plugin-json-processor'
  ],
  rules: {
    'quotes': ['error', 'single']
  }
}

這樣就會對 json 檔案中的引號起到檢查作用。

2.4 globals

如果開啟了 no-undef 規則,在檔案中使用未宣告的變數將會出現檢查錯誤,此時我們可以在 globals 配置項中允許需要被使用的全域性變數,lint 規則就不會發生檢查錯誤。

// 如果我們在檔案中使用了 window
window.appName = 'myApp'

此時 eslint 會報出如下錯誤

error 'window' is not defined no-undef

如果在這種場景下需要繞過 eslint 檢查,可以在 globals 配置中允許使用 window

// .eslintrc.js
module.exports = {
  globals: {
    window: true
  }
}

這樣就可以繞過對 window 的檢查

2.5 env

有時候在檔案中可能需要針對某一類的全域性變數繞過檢查,例如我們編寫的程式碼時執行在瀏覽器環境中,常常會使用 windowdocument 這一類的全域性變數,除了可以一個一個在 globals 中進行允許之外,還可以在 env 配置中設定某一個或某幾個環境變數。下面列出一些常用的的環境型別,更多完整的可以在這裡檢視

env 說明
browser 允許使用瀏覽器環境中的全域性變數,如:window、document
node 允許使用node環境中的全域性變數,如:global、module
jquery 允許使用jquery全域性變數,如:$、jQuery