[譯] ESLint v4.0.0 升級指南

吃土小2叉發表於2019-03-01

ESLint v4.0.0 升級指南

ESLint v4.0.0 是 ESLint 的第 4 個主版本。當然,我們希望大多數變更隻影響極少數使用者。本文旨在幫助您瞭解具體有哪些更改。

以下列表大致按每個更改可能影響的使用者數量進行排序,排序越靠前影響的使用者數越多。

ESLint 使用者請注意

  1. eslint:recommended 新增規則
  2. indent 規則將更嚴格
  3. 現在配置檔案中未識別的屬性會報告嚴重錯誤
  4. 忽略檔案將從 .eslintignore 檔案所在目錄開始解析
  5. 預設情況下 padded-blocks 規則將更嚴格
  6. 預設情況下 space-before-function-paren 規則將更嚴格
  7. 預設情況下 no-multi-spaces 規則將更嚴格
  8. 現在必須包含名稱空間,才能引用限定在名稱空間下的外掛

ESLint 外掛開發者和自定義規則開發者請注意

  1. 現在 RuleTester 將驗證測試用例物件的屬性
  2. AST 節點不再具有註釋屬性
  3. 在 AST 遍歷期間不會觸發 LineCommentBlockComments 事件
  4. 現在 Shebang 可以通過註釋 API 返回

整合開發者請注意

  1. linter.verify() API 不再支援 global 屬性
  2. 現在更多報告訊息具有完整的位置範圍
  3. 部分暴露的 API 將使用 ES2015 中的類

eslint:recommended 中新增了兩條規則:

注: 如果要與 ESLint 3.x 的 eslint:recommended 保持一致,您可以在配置檔案中禁用上述規則:

{
  "extends": "eslint:recommended",

  "rules": {
    "no-compare-neg-zero": "off",
    "no-useless-escape": "off"
  }
}複製程式碼

indent 規則將更嚴格

過去的 indent 規則在檢查縮排方面是相當寬容的:過去的縮排校驗規則會忽略許多程式碼模式。而這會讓使用者產生困擾,因為他們偶爾會有不正確的程式碼縮排,並且他們本期望 ESLint 能夠發現這些問題(譯者補充:然而並沒有發現)。

在 ESLint v4.0.0 中,indent 規則被重寫。新版規則將報告出舊版規則無法發現的縮排錯誤。另外,MemberExpression 節點、函式宣告引數以及函式呼叫引數將預設進行縮排檢查(過去為了向後相容,這些預設都被忽略了)。

為了方便升級到 ESLint 4.0.0,我們引入了 indent-legacy 規則作為 ESLint 3.x 中 indent 規則的快照。如果你在升級過程中遇到了 indent 規則的相關問題,那麼您可以藉助於 indent-legacy 規則來維持與 3.x 一致。然而,indent-legacy 規則已被棄用並且在將來不再維護,所以您最終還是應該使用 indent 規則。

注: 推薦在升級過程中不要更改 indent 配置,並修正新的縮排錯誤。然而如果要與 ESLint 3.x 的 indent 規則保持一致,您可以這樣配置:

{
  rules: {
    indent: "off",
    "indent-legacy": "error" // 用之前的 `indent` 配置替換此處
  }
}複製程式碼

現在配置檔案中未識別的屬性會報告嚴重錯誤

在建立配置檔案時,使用者有時候會犯拼寫錯誤或者弄錯配置檔案的結構。在以前,ESLint 並不會驗證配置檔案中的屬性,因此很難除錯配置檔案中的拼寫錯誤。而從 ESLint v4.0.0 起,當配置檔案中存在未識別的屬性或者屬性型別有錯誤時,ESLint 會丟擲一個錯誤。

注: 升級後如果發現配置檔案驗證出錯,請檢查配置檔案中是否存在拼寫錯誤。如果使用了未識別的屬性,那麼應該將之從配置檔案中移除,從而使 ESLint 恢復正常。

忽略檔案將從 .eslintignore 檔案所在目錄開始解析

過去由於一個 bug,.eslintignore 檔案的路徑名模板是從程式的當前工作目錄解析,而不是 .eslintignore 檔案的位置。從 ESLint 4.0 開始,.eslintignore 檔案的路徑名模板將從 .eslintignore 檔案的位置解析。

注: 如果您使用 .eslintignore 檔案,並且您經常從專案根目錄以外的地方執行 ESLint,則可能會以不同的模式匹配路徑名。您應該更新 .eslintignore 檔案中的匹配模式,以確保它們與該檔案相關,而不是與工作目錄相關。

預設情況下 padded-blocks 規則將更嚴格

現在預設情況下, padded-blocks 規則要求在類內填充空行以及在 switch 語句中填充空行。而過去除非使用者更改配置,否則預設情況下這條規則會忽略上述情況的檢查。

注: 如果此更改導致程式碼庫中出現更多的錯誤,您應該修復它們或重新配置規則。

預設情況下 space-before-function-paren 規則將更嚴格

現在預設情況下, space-before-function-paren 規則要求非同步箭頭函式的圓括號與 async 關鍵詞之間存在空格。而過去除非使用者更改配置,否則預設情況下這條規則會忽略對非同步箭頭函式的檢查。

注: 如果要與 ESLint 3.x 的預設配置保持一致,您可以這樣配置:

{
  "rules": {
    "space-before-function-paren": ["error", {
      "anonymous": "always",
      "named": "always",
      "asyncArrow": "ignore"
    }]
  }
}複製程式碼

預設情況下 no-multi-spaces 規則將更嚴格

現在預設情況下, no-multi-spaces 規則禁止行尾註釋前存在多個空格。而過去這條規則不對此進行檢查。

注: 如果要與 ESLint 3.x 的預設配置保持一致,您可以這樣配置:

{
  "rules": {
    "no-multi-spaces": ["error", {"ignoreEOLComments": true}]
  }
}複製程式碼

現在必須包含名稱空間,才能引用限定在名稱空間下的外掛

在 ESLint 3.x 中存在一個 bug:引用限定在名稱空間下的外掛可能會忽略該名稱空間。舉個例子,在 ESLint 3.x 中以下配置是合法的:

{
  "plugins": [
    "@my-organization/foo"
  ],
  "rules": {
    "foo/some-rule": "error"
  }
}複製程式碼

換句話說,過去可以引用限定名稱空間的外掛的規則(例如 foo/some-rule),同時無需明確宣告 @my-organization 的名稱空間。這是一個 bug,因為如果同時載入了一個名為 eslint-plugin-foo 的不限定名稱空間的外掛,可能會導致引用規則時產生歧義。

為了避免歧義,在 ESLint 4.0 中必須包含名稱空間,才能引用限定在名稱空間下的外掛。

{
  "plugins": [
    "@my-organization/foo"
  ],
  "rules": {
    "@my-organization/foo/some-rule": "error"
  }
}複製程式碼

注: 如果您在配置檔案中引用了限定在名稱空間下的外掛,那麼請確保在引用的時候包含名稱空間。


現在 RuleTester 將驗證測試用例物件的屬性

從 ESLint 4.0 開始,RuleTester 工具將驗證測試用例物件的屬性,如果遇到未知屬性,將丟擲錯誤。這番改動是因為我們發現開發人員在測試規則時的拼寫錯誤是比較常見的,且通常會使測試用例試圖作出的斷言無效。

注: 如果您對自定義規則的測試用例物件具有額外的屬性,則應該移除這些屬性。

AST 節點不再具有註釋屬性

在 ESLint 4.0 之前,ESLint 需要解析器實現附加註釋的解析,這個過程中,AST 節點將從原始檔的前後置註釋中獲取額外的相關聯屬性。這就使得使用者很難去開發自定義解析器,因為他們不得不去重複解析那些令人困惑同時又是 ESlint 必需的附加註釋語義。

在 ESLint 4.0 中,我們已經擺脫了附加註釋的概念,並將所有的註釋處理邏輯轉移到了 ESLint 本身。這樣可以更容易地開發自定義解析器,但這也意味著 AST 節點將不再具有 leadingCommentstrailingComments 屬性。 從概念上來說,規則作者現在可以在 tokens 上下文而不是 AST 節點的上下文中考慮註釋。

注: 如果您有一個依賴於 AST 節點的 leadingCommentstrailingComments 屬性的自定義規則,則可以分別使用 sourceCode.getCommentsBefore()sourceCode.getCommentsAfter() 替代。

此外,sourceCode 物件現在也有 sourceCode.getCommentsInside() 方法(它返回一個節點內的所有註釋),sourceCode.getAllComments() 方法(它返回檔案中的所有註釋),並允許註釋通過各種其他 token 迭代器方法(例如 getTokenBefore()getTokenAfter())並設定選項{includeComments:true} 進行訪問。

對於想要同時相容 ESLint v3.0 和 v4.0 的規則作者,現在已經不推薦使用的 sourceCode.getComments() 仍然可用,並且這兩個版本都相容。

最後請注意,以下 SourceCode 方法已被棄用,將在以後的 ESLint 版本中被移除:

  • getComments() – 請使用 getCommentsBefore()getCommentsAfter()getCommentsInside() 來替換
  • getTokenOrCommentBefore() – 請使用 getTokenBefore() 方法並設定選項 {includeComments:true} 來替換
  • getTokenOrCommentAfter() – 請使用 getTokenAfter() 方法並設定選項 {includeComments:true} 來替換

在 AST 遍歷期間不會觸發 LineCommentBlockComments 事件

從 ESLint 4.0 開始,在 AST 遍歷期間不會觸發 LineCommentBlockComments 事件。原因如下:

  • 過去這種行為依賴於在解析器級別的註釋附屬物,而自 ESLint 4.0 開始不再如此,以確保所有註釋將被考慮
  • 在 tokens 上下文中考慮註釋更容易預測和更容易理解,而非在 AST 節點上下文中考慮註釋 token

注: 規則現在可以使用sourceCode.getAllComments() 來獲取檔案中的所有註釋,而非依賴於 LineCommentBlockComment。要檢查特定型別的所有註釋,規則可以使用以下模式:

sourceCode.getAllComments().filter(comment => comment.type === "Line");
sourceCode.getAllComments().filter(comment => comment.type === "Block");複製程式碼

現在 Shebang 可以通過註釋 API 返回

(譯者注:Shebang 是一個由井號和歎號構成的字元序列 #!,其出現在文字檔案的第一行的前兩個字元。參考:Shebang_(Unix)))

在 ESLint 4.0 之前,原始檔中的 shebang 註釋不會出現在 sourceCode.getAllComments()sourceCode.getComments() 的輸出中,但它們將作為行註釋出現在 sourceCode.getTokenOrCommentBefore 的輸出中。這種不一致會給規則開發者帶來困惑。

在 ESLint 4.0 中,shebang 註釋被視為 Shebang 型別的註釋 tokens,並可以通過任何返回註釋的 SourceCode 方法返回。該變化的目的是為了讓 shebang 的評論更符合其他 tokens 的處理方式。

注: 如果您有一個自定義規則對註釋執行操作,可能需要一些額外的邏輯來確保 shebang 註釋被正確處理或被正常過濾掉:

sourceCode.getAllComments().filter(comment => comment.type !== "Shebang");複製程式碼

linter.verify() API 不再支援 global 屬性

過去,linter.verify() API 接受 global 屬性作為一個配置項,它與官方文件中的 globals 作用相同。但是,global 屬性從未出現在官方文件中或者被官方支援,並且在配置檔案中該屬性會失效。自 ESLint 4.0 起,該屬性已被移除。

注: 如果您先前使用了 global 屬性,請用 globals 屬性替換,其作用與 global 相同。

現在更多報告訊息具有完整的位置範圍

從 ESLint 3.1.0 開始,除了開始位置之外,規則還可以通過呼叫 report 時明確指定一個結束位置來指定問題報告的結束位置。這對於編輯器整合這樣的工具很有用,可以使用範圍來精確顯示出現問題的位置。從 ESLint 4.0 開始,如果報告了節點而不是一個具體位置,則該結束位置的範圍將自動從節點的結束位置推斷出來。因此,更多報告的問題將會有結束位置。

這不會帶來相容性問題。然而,這可能會導致比以前更大的報告位置範圍。例如,如果一條規則報告的是 AST 的根節點,則問題的範圍將是整個程式。在某些整合中,這可能導致使用者體驗不佳(例如,如果整個程式都被高亮顯示以指示錯誤)。

注: 如果您有處理報告問題範圍的整合,請確保以對使用者友好的方式處理大型報告範圍。

部分暴露的 API 將使用 ES2015 中的類

現在部分 ESLint 的 Node.js API,比如 CLIEngineSourceCode 以及 RuleTester 模組使用了 ES2015 中的類。當然這不會影響到介面的正常使用,不過這的確會產生一些明顯的影響(舉個例子,CLIEngine.prototype 將不可列舉)。

注: 如果您需要對 ESLint 的 Node.js API 提供的方法進行列舉遍歷,可以用諸如 Object.getOwnPropertyNames 的函式來訪問不可列舉屬性。(譯者注:可參考 MDN 文件:屬性的可列舉性和所有權


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOSReact前端後端產品設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃

相關文章