使用 ESLint 檢查 TypeScript 代碼

BenjaminHar 7年前發布 | 22K 次閱讀 TypeScript

TypeScript 與 ESLint

ESLint 是一個代碼檢查工具,主要用來發現代碼錯誤、統一代碼風格,目前已被廣泛的應用于各種 JavaScript 項目中。

它通過插件化的特性極大的豐富了適用范圍,搭配 typescript-eslint-parser 之后,甚至可以用來檢查 TypeScript 代碼。

為什么需要 ESLint

TypeScript 除了是一個編譯 ts 文件的工具以外,還可以 作為一個靜態代碼檢查工具使用

TypeScript 會對文件進行語法解析,如果遇到一些語法錯誤,或使用了未定義的變量,則會報錯。

ESLint 也會對文件進行語法解析,它可以對一些代碼風格進行約束,發現未定義的變量,但是對于錯誤的屬性或方法引用,卻無能為力。

我們對同樣一段代碼分別運行 tsc 和 eslint ,會得到如下報錯信息:

let myName = 'Tom';

console.log(My name is ${myNane}); console.log(My name is ${myName.toStrng()}); console.log(My name is ${myName})

// tsc 報錯信息: // // index.ts(3,27): error TS2552: Cannot find name 'myNane'. Did you mean 'myName'? // index.ts(4,34): error TS2551: Property 'toStrng' does not exist on type 'string'. Did you mean 'toString'? // // // eslint 報錯信息: // // /path/to/index.ts // 3:27 error 'myNane' is not defined no-undef // 5:38 error Missing semicolon semi // // ? 2 problems (2 errors, 0 warnings) // 1 errors, 0 warnings potentially fixable with the --fix option.</pre>

存在的問題 tsc 是否報錯 eslint 是否報錯
myName 被勿寫成了 myNane :white_check_mark: :white_check_mark:
toString 被勿寫成了 toStrng :white_check_mark:? :x:
少了一個分號 :x: :white_check_mark:

上例中,由于 eslint 無法識別 myName 存在哪些方法,所以對于拼寫錯誤的 toString 沒有檢查出來。而代碼風格的錯誤不影響編譯,故 tsc 沒有檢查出來。

未定義的變量兩者都能檢查出來。

值得注意的是, tsc 不僅檢查出來了代碼問題,還非常智能的給出了修改建議。

下面是 TypeScirpt 作為一個靜態代碼檢查工具,與 ESLint 的關系圖:

上圖中,TypeScript 與 ESLint 有重疊的部分,也有各自獨立的部分,雖然發現代碼錯誤比統一的代碼風格更重要,但是當一個項目越來越龐大,開發人員也越來越多的時候,代碼風格的約束還是必不可少的。

下面我們就來一步一步給 TypeScript 項目添加 ESLint 檢查。

安裝

ESLint 可以安裝在當前項目中或全局環境下,因為代碼檢查是項目的重要組成部分,所以我們一般會將它安裝在當前項目中。可以運行下面的腳本來安裝:

npm install eslint --save-dev

由于 ESLint 默認使用 Espree 進行語法解析,無法識別 TypeScript 的一些語法,故我們需要安裝 typescript-eslint-parser ,替代掉默認的解析器,別忘了同時安裝 typescript :

npm install typescript typescript-eslint-parser --save-dev

由于 typescript-eslint-parser 對一部分 ESLint 規則支持性不好,故我們需要安裝 eslint-plugin-typescript ,彌補一些支持性不好的規則。

npm install eslint-plugin-typescript --save-dev

創建配置文件

ESLint 需要一個配置文件來決定對哪些規則進行檢查,配置文件的名稱一般是 .eslintrc.js 或 .eslintrc.json 。

當運行 ESLint 的時候檢查一個文件的時候,它會首先嘗試讀取該文件的目錄下的配置文件,然后再一級一級往上查找,將所找到的配置合并起來,作為當前被檢查文件的配置。

我們在項目的根目錄下創建一個 .eslintrc.js ,內容如下:

module.exports = {
    parser: 'typescript-eslint-parser',
    plugins: [
        'typescript'
    ],
    rules: {
        // @fixable 必須使用 === 或 !==,禁止使用 == 或 !=,與 null 比較時除外
        'eqeqeq': [
            'error',
            'always',
            {
                null: 'ignore'
            }
        ],
        // 類和接口的命名必須遵守帕斯卡命名法,比如 PersianCat
        'typescript/class-name-casing': 'error'
    }
}

以上配置中,我們指定了兩個規則,其中 eqeqeq 是 ESLint 原生的規則(它要求必須使用 === 或 !== ,禁止使用 == 或 != ,與 null 比較時除外), typescript/class-name-casing 是 eslint-plugin-typescript 為 ESLint 增加的規則(它要求類和接口的命名必須遵守帕斯卡命名法,比如 PersianCat )。

規則的取值一般是一個數組(上例中的 eqeqeq ),其中第一項是 off 、 warn 或 error 中的一個,表示關閉、警告和報錯。后面的項都是該規則的其他配置。

如果沒有其他配置的話,則可以將規則的取值簡寫為數組中的第一項(上例中的 typescirpt/class-name-casing )。

關閉、警告和報錯的含義如下:

  • 關閉:禁用此規則
  • 警告:代碼檢查時輸出錯誤信息,但是不會影響到 exit code
  • 報錯:發現錯誤時,不僅會輸出錯誤信息,而且 exit code 將被設為 1(一般 exit code 不為 0 則表示執行出現錯誤)

檢查一個 ts 文件

創建了配置文件之后,我們來創建一個 ts 文件看看是否能用 ESLint 去檢查它了。

創建一個新文件 index.ts ,將以下內容復制進去:

interface person {
    name: string;
    age: number;
}

let tom: person = { name: 'Tom', age: 25 };

if (tom.age == 25) { console.log(tom.name + 'is 25 years old.'); }</pre>

然后執行以下命令:

./node_modules/.bin/eslint index.ts

則會得到如下報錯信息:

/path/to/index.ts
   1:11  error  Interface 'person' must be PascalCased  typescript/class-name-casing
  11:13  error  Expected '===' and instead saw '=='     eqeqeq

? 2 problems (2 errors, 0 warnings)</pre>

上面的結果顯示,剛剛配置的兩個規則都生效了:接口 person 必須寫成帕斯卡命名規范, == 必須寫成 === 。

需要注意的是,我們使用的是 ./node_modules/.bin/eslint ,而不是全局的 eslint 腳本,這是因為代碼檢查是項目的重要組成部分,所以我們一般會將它安裝在當前項目中。

可是每次執行這么長一段腳本頗有不便,我們可以在 package.json 中添加一個 script 來簡化這個步驟:

{
    "scripts": {
        "eslint": "eslint index.ts"
    }
}

這時只需執行 npm run eslint 即可。

檢查整個項目的 ts 文件

我們的項目源文件一般是放在 src 目錄下,所以需要將 package.json 中的 eslint 腳本改為對一個目錄進行檢查。由于 eslint 默認不會檢查 .ts 后綴的文件,所以需要加上參數 --ext .ts :

{
    "scripts": {
        "eslint": "eslint src --ext .ts"
    }
}

此時執行 npm run eslint 即會檢查 src 目錄下的所有 .ts 后綴的文件。

在 VSCode 中集成 ESLint 檢查

在編輯器中集成 ESLint 檢查,可以在開發過程中就發現錯誤,極大的增加了開發效率。

要在 VSCode 中集成 ESLint 檢查,我們需要先安裝 ESLint 插件,點擊「擴展」按鈕,搜索 ESLint,然后安裝即可。

VSCode 中的 ESLint 插件默認是不會檢查 .ts 后綴的,需要在「文件 => 首選項 => 設置」中,添加以下配置:

{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "typescript"
    ]
}

這時再打開一個 .ts 文件,將鼠標移到紅色提示處,即可看到這樣的報錯信息了:

使用已完善的配置

ESLint 原生的規則和 eslint-plugin-typescript 的規則太多了,而且原生的規則有一些在 TypeScript 中支持的不好,需要禁用掉。

這里我推薦使用 AlloyTeam ESLint 規則中的 TypeScript 版本 ,它已經為我們提供了一套完善的配置規則。

安裝:

npm install --save-dev eslint typescript typescript-eslint-parser eslint-plugin-typescript eslint-config-alloy

在你的項目根目錄下創建 .eslintrc.js ,并將以下內容復制到文件中:

module.exports = {
    extends: [
        'eslint-config-alloy/typescript',
    ],
    globals: {
        // 這里填入你的項目需要的全局變量
        // 這里值為 false 表示這個全局變量不允許被重新賦值,比如:
        //
        // jQuery: false,
        // $: false
    },
    rules: {
        // 這里填入你的項目需要的個性化配置,比如:
        //
        // // @fixable 一個縮進必須用兩個空格替代
        // 'indent': [
        //     'error',
        //     2,
        //     {
        //         SwitchCase: 1,
        //         flatTernaryExpressions: true
        //     }
        // ]
    }
};

使用 ESLint 檢查 tsx 文件

如果需要同時支持對 tsx 文件的檢查,則需要對以上步驟做一些調整:

安裝 eslint-plugin-react

npm install --save-dev eslint-plugin-react

package.json 中的 scripts.eslint 添加 .tsx 后綴

{
    "scripts": {
        "eslint": "eslint src --ext .ts,.tsx"
    }
}

VSCode 的配置中新增 typescriptreact 檢查

{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "typescript",
        "typescriptreact"
    ]
}

使用 AlloyTeam ESLint 規則中的 TypeScript React 版本

AlloyTeam ESLint 規則中的 TypeScript React 版本

Troubleshootings

Cannot find module 'typescript-eslint-parser'

你運行的是全局的 eslint,需要改為運行 ./node_modules/.bin/eslint 。

cannot read property type of null

需要關閉 eslint-plugin-react 中的規則 react/jsx-indent 。

VSCode 沒有顯示出 ESLint 的報錯

  1. 檢查「文件 => 首選項 => 設置」中有沒有配置正確
  2. 檢查必要的 npm 包有沒有安裝
  3. 檢查 .eslintrc.js 有沒有配置
  4. 檢查文件是不是在 .eslintignore 中

如果以上步驟都不奏效,則可以在「文件 => 首選項 => 設置」中配置 "eslint.trace.server": "messages" ,按 Ctrl + Shift + U 打開輸出面板,然后選擇 ESLint 輸出,查看具體錯誤。

 

 本文由用戶 BenjaminHar 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!