版本

遷移至 v6.0.0

ESLint v6.0.0 是 ESLint 的主要版本。我們在此版本中做了一些重大變更。本指南旨在引導您了解這些重大變更。

以下列表大致按照預期每個變更影響的使用者數量排序,其中第一個項目預期影響最多的使用者。

使用者的重大變更

  1. 不再支援 Node.js 6
  2. eslint:recommended 已更新
  3. 外掛程式和可共享設定不再受 ESLint 位置的影響
  4. 預設解析器現在更嚴格地驗證選項
  5. 規則設定經過更嚴格的驗證
  6. no-redeclare 規則預設現在更嚴格
  7. comma-dangle 規則預設現在更嚴格
  8. no-confusing-arrow 規則預設現在更寬鬆
  9. 設定檔中的覆寫現在可以匹配點檔案
  10. 擴充設定檔中的覆寫現在可以被父設定檔覆寫
  11. 全域變數的設定值現在經過驗證
  12. 已移除已棄用的 experimentalObjectRestSpread 選項
  13. 規則選項中使用者提供的正規表示式會使用 unicode 標誌進行解析

外掛程式/自訂規則開發者的重大變更

  1. 外掛程式作者可能需要更新安裝指示
  2. RuleTester 現在針對規則綱要中的無效 default 關鍵字進行驗證
  3. RuleTester 現在需要在 parser 選項上使用絕對路徑
  4. eslintExplicitGlobalComment 範圍分析屬性已移除

整合開發者的重大變更

  1. 外掛程式和可共享設定不再受 ESLint 位置的影響
  2. Linter 不再嘗試從檔案系統載入遺失的解析器

不再支援 Node.js 6

截至 2019 年 4 月,Node.js 6 將達到 EOL,並且不再接收安全更新。因此,我們已決定在 ESLint v6 中停止支援它。我們現在支援以下 Node.js 版本

  • Node.js 8 (8.10.0 及以上版本)
  • Node.js 10 (10.13.0 及以上版本)
  • Node.js 11.10.1 以上的任何版本

解決方案: 使用 ESLint v6 時,請確保您升級到至少 Node.js 8。如果您無法升級,我們建議您繼續使用 ESLint v5.x,直到您能夠升級 Node.js 為止。

相關問題: eslint/eslint#11546

eslint:recommended 已更新

以下規則已新增至 eslint:recommended 設定

  • no-async-promise-executor 禁止使用 async 函數作為 Promise 建構子的引數,這通常是一個錯誤。
  • no-misleading-character-class 報告正規表示式中可能無法如預期運作的字元類別。
  • no-prototype-builtins 報告方法呼叫,例如 foo.hasOwnProperty("bar")(這是常見的錯誤來源),並建議將其替換為 Object.prototype.hasOwnProperty.call(foo, "bar")
  • no-shadow-restricted-names 禁止遮蔽變數,例如 undefined(例如使用類似 let undefined = 5; 的程式碼),因為這很可能會讓讀者感到困惑。
  • no-useless-catch 報告多餘的 catch 子句,這些子句可以從程式碼中移除而不會改變其行為。
  • no-with 禁止使用 with 陳述式,這會使程式碼難以理解並導致相容性問題。
  • require-atomic-updates 報告在非同步函數中重新賦值變數時可能發生的競爭條件錯誤。

此外,以下規則已從 eslint:recommended移除

  • no-console 禁止呼叫類似 console.log 的函數。雖然此規則在許多情況下很有用(例如,避免不小心將偵錯陳述式留在生產程式碼中),但它的適用範圍不如 eslint:recommended 中的其他規則廣泛,並且在 console.log 可以接受的情況下(例如在 CLI 應用程式中),它會產生誤報。

最後,在 ESLint v5 中,eslint:recommended 會明確停用所有未被視為「建議」的核心規則。如果 eslint:recommended 在另一個設定之後載入,這可能會導致混淆的行為,因為 eslint:recommended 會具有關閉某些規則的效果。在 ESLint v6 中,eslint:recommended 對非建議規則沒有影響。

解決方案: 若要模擬 5.x 中的 eslint:recommended 行為,您可以如下所示在設定檔中明確停用/啟用規則

{
  "extends": "eslint:recommended",

  "rules": {
    "no-async-promise-executor": "off",
    "no-misleading-character-class": "off",
    "no-prototype-builtins": "off",
    "no-shadow-restricted-names": "off",
    "no-useless-catch": "off",
    "no-with": "off",
    "require-atomic-updates": "off",

    "no-console": "error"
  }
}

在極少數情況下(如果您依賴先前的行為,其中 eslint:recommended 停用核心規則),您可能需要停用其他規則才能還原先前的行為。

相關問題: eslint/eslint#10768eslint/eslint#10873

外掛程式和可共享設定不再受 ESLint 位置的影響

先前,ESLint 相對於 ESLint 套件本身的位置載入外掛程式。因此,我們建議使用全域 ESLint 安裝的使用者也應全域安裝外掛程式,而使用本機 ESLint 安裝的使用者應在本機安裝外掛程式。但是,由於設計錯誤,此策略導致 ESLint 在某些情況下隨機無法載入外掛程式和可共享設定,尤其是在使用套件管理工具(例如 lernaYarn Plug n’ Play)時。

經驗法則:使用 ESLint v6,外掛程式應始終在本機安裝,即使 ESLint 是全域安裝的也是如此。更精確地說,ESLint v6 預設相對於最終使用者的專案解析外掛程式,並且始終相對於匯入它們的設定檔的位置解析可共享設定和解析器。

解決方案: 如果您使用 ESLint 的全域安裝(例如使用 npm install eslint --global 安裝)以及外掛程式,您應該在本機專案中安裝這些外掛程式,在這些專案中您執行 ESLint。如果您的設定檔擴充了可共享設定和/或解析器,您應該確保這些套件安裝為包含設定檔的專案的相依性。

如果您使用位於本機專案外部的設定檔(使用 --config 標誌),請考慮將外掛程式安裝為該設定檔的相依性,並將 --resolve-plugins-relative-to 標誌設定為設定檔的位置。

相關問題: eslint/eslint#10125eslint/rfcs#7

預設解析器現在更嚴格地驗證選項

espree,ESLint 使用的預設解析器,現在將在以下情況下引發錯誤

  • ecmaVersion 解析器選項設定為數字以外的其他內容,例如字串 "2015"。(先前,非數字選項將被簡單地忽略。)
  • 設定 sourceType: "module" 解析器選項,同時將 ecmaVersion 設定為 5 或保持未指定。(先前,設定 sourceType: "module" 會隱含地導致 ecmaVersion 設定為至少 2015,這可能會令人驚訝。)
  • sourceType 設定為 "script""module" 以外的任何內容。

解決方案: 如果您的設定將 ecmaVersion 設定為數字以外的其他內容,您可以透過移除 ecmaVersion 來還原先前的行為。(但是,您可能需要仔細檢查您的設定是否實際上如預期般運作。)如果您的設定設定了 parserOptions: { sourceType: "module" } 而沒有同時設定 parserOptions.ecmaVersion,您應該新增 parserOptions: { ecmaVersion: 2015 } 以還原先前的行為。

相關問題: eslint/eslint#9687eslint/espree#384

規則設定經過更嚴格的驗證

為了更早地捕獲設定錯誤,如果您嘗試設定不存在的規則,ESLint v6 將報告 linting 錯誤。

設定 ESLint v5 ESLint v6
/*eslint-enable foo*/ 無錯誤 linting 錯誤
/*eslint-disable(-line) foo*/ 無錯誤 linting 錯誤
/*eslint foo: 0*/ 無錯誤 linting 錯誤
{rules: {foo: 0}} 無錯誤 無錯誤
{rules: {foo: 1} linting 警告 linting 錯誤

解決方案: 您可以移除(內聯)設定中不存在的規則。

相關問題: eslint/eslint#9505

no-redeclare 規則預設現在更嚴格

no-redeclare 規則的預設選項已從 { builtinGlobals: false } 變更為 { builtinGlobals: true }。此外,如果全域變數已透過設定啟用,則 no-redeclare 規則現在會針對由類似 /* global foo */ 的註解啟用的全域變數報告錯誤。

解決方案

若要還原規則的先前選項,您可以將其設定如下

{
  "rules": {
    "no-redeclare": ["error", { "builtinGlobals": false }]
  }
}

此外,如果您在程式碼中看到新的 global 註解錯誤,您應該移除這些註解。

相關問題: eslint/eslint#11370eslint/eslint#11405

comma-dangle 規則預設現在更嚴格

先前,除非明確設定為檢查函數逗號,否則 comma-dangle 規則會忽略尾隨函數引數和參數。在 ESLint v6 中,函數逗號的處理方式與其他類型的尾隨逗號相同。

解決方案: 您可以使用以下方式還原規則的先前預設行為

{
  "rules": {
    "comma-dangle": ["error", {
        "arrays": "never",
        "objects": "never",
        "imports": "never",
        "exports": "never",
        "functions": "ignore"
    }]
  }
}

若要還原字串選項(例如 "always-multiline")的先前行為,請將範例中的 "never" 替換為 "always-multiline"

相關問題: eslint/eslint#11502

no-confusing-arrow 規則預設現在更寬鬆

no-confusing-arrow 規則的預設選項已從 { allowParens: false } 變更為 { allowParens: true }

解決方案: 您可以使用以下方式還原規則的先前預設行為

{
  "rules": {
    "no-confusing-arrow": ["error", { "allowParens": false }]
  }
}

相關問題: eslint/eslint#11503

設定檔中的覆寫現在可以匹配點檔案

由於錯誤,設定檔的 overrides 區段中 files 列表中的 glob 模式永遠不會匹配點檔案,因此無法讓覆寫套用至以點開頭的檔案。此錯誤已在 ESLint v6 中修正。

解決方案: 如果您不希望點檔案與覆寫匹配,請考慮在該 overrides 區段中新增類似 excludedFiles: [".*"] 的內容。請參閱 文件 以取得更多詳細資訊。

相關問題: eslint/eslint#11201

擴充設定檔中的覆寫現在可以被父設定檔覆寫

由於錯誤,先前的情況是,可共享設定中的 overrides 區塊優先於父設定的頂層。例如,使用以下設定設定,semi 規則最終將會啟用,即使它在最終使用者的設定中被明確停用

// .eslintrc.js
module.exports = {
  extends: ["foo"],
  rules: {
    semi: "off"
  }
};
// eslint-config-foo/index.js
module.exports = {
  overrides: {
    files: ["*.js"],
    rules: {
      semi: "error"
    }
  }
};

在 ESLint v6.0.0 中,父設定始終優先於擴充設定,即使使用 overrides 區塊也是如此。

解決方案: 我們預期此問題的影響非常低,因為大多數可共享設定不使用 overrides 區塊。但是,如果您使用具有 overrides 區塊的可共享設定,您可能會遇到行為變更,這是由於您的設定中明確指定但在目前為止一直處於非活動狀態的某些內容所致。如果您寧願繼承可共享設定的行為,只需從您自己的設定中移除相應的條目即可。(在上面的範例中,可以透過從 .eslintrc.js 中移除 semi: "off" 來還原先前的行為。)

相關問題: eslint/eslint#11510

全域變數的設定值現在經過驗證

先前,當使用物件設定一組全域變數時,可以使用任何內容作為物件的值。未知值將被視為與 "writable" 相同。

// .eslintrc.js
module.exports = {
  globals: {
    foo: "readonly",
    bar: "writable",
    baz: "hello!" // ???
  }
};

透過此變更,globals 物件中的任何未知值都會導致設定驗證錯誤。

解決方案: 如果您在更新後看到與全域變數相關的設定驗證錯誤,請確保為全域變數設定的所有值都是 readonlywritableoff。(ESLint 也接受一些替代拼寫和變體以實現相容性。)

已移除已棄用的 experimentalObjectRestSpread 選項

先前,當使用預設解析器時,設定可以使用 experimentalObjectRestSpread 選項來啟用對物件 rest/spread 屬性的解析支援

{
  "parserOptions": {
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true
    }
  }
}

自 ESLint v5 以來,ecmaFeatures: { experimentalObjectRestSpread: true } 等同於 ecmaVersion: 2018,並且也發出棄用警告。在 ESLint v6 中,experimentalObjectRestSpread 功能已完全移除且無效。如果您的設定依賴 experimentalObjectRestSpread 來啟用 ES2018 解析,您可能會開始看到最近語法的解析錯誤。

解決方案: 如果您使用 experimentalObjectRestSpread 選項,您應該將您的設定變更為包含以下內容

{
  "parserOptions": {
    "ecmaVersion": 2018
  }
}

如果您不確定哪個設定檔需要更新,執行 ESLint v5 並查看棄用警告中提及的設定檔可能會很有用。

相關問題: eslint/eslint#9990

規則選項中使用者提供的正規表示式會使用 unicode 標誌進行解析

類似 max-len 的規則接受字串選項,該選項被解釋為正規表示式。在 ESLint v6.0.0 中,這些正規表示式會使用 unicode 標誌 進行解釋,當匹配星芒層符號等字元時,這應該表現出更合理的行為。Unicode 正規表示式也比非 unicode 正規表示式更嚴格地驗證跳脫序列。

解決方案: 如果您在升級後遇到規則選項驗證錯誤,請確保您的規則選項中的任何正規表示式都沒有無效的跳脫序列。

相關問題: eslint/eslint#11423


外掛程式作者可能需要更新安裝指示

如果您維護外掛程式並提供安裝指示,您應該確保安裝指示與 外掛程式載入方式的面向使用者變更保持同步。特別是,如果您的外掛程式是使用 generator-eslint 套件產生的,則它可能包含關於如何將外掛程式與全域 ESLint 安裝一起使用的過時指示。

相關問題: eslint/rfcs#7

RuleTester 現在針對規則綱要中的無效 default 關鍵字進行驗證

在某些情況下,規則綱要可以使用 default 關鍵字來自動指定規則選項的預設值。但是,default 關鍵字僅在某些綱要位置有效,而在其他位置則被忽略,如果規則錯誤地期望將預設值作為規則選項提供,則會產生錯誤風險。在 ESLint v6.0.0 中,如果規則在其綱要中具有無效的 default 關鍵字,RuleTester 將會引發錯誤。

解決方案: 如果 RuleTester 開始報告關於無效預設值的錯誤,您可以移除規則綱要中指示位置的 default 屬性,並且規則的行為將保持不變。(如果發生這種情況,您可能還需要驗證規則在該位置未提供選項值時是否行為正確。)

相關問題: eslint/eslint#11473

RuleTester 現在需要在 parser 選項上使用絕對路徑

若要在測試中使用自訂解析器,我們可以將 parser 屬性與套件名稱或檔案路徑一起使用。但是,如果給定了套件名稱,則測試程式應從何處載入解析器套件尚不清楚,因為測試程式不知道哪些檔案正在執行測試程式。在 ESLint v6.0.0 中,RuleTester 不允許將 parser 屬性與套件名稱一起使用。

解決方案: 如果您在測試案例中使用具有套件名稱的 parser 屬性,請使用 require.resolve() 函數更新它,以將套件名稱解析為套件的絕對路徑。

相關問題: eslint/eslint#11728eslint/eslint#10125eslint/rfcs#7

eslintExplicitGlobalComment 範圍分析屬性已移除

先前,ESLint 會將 eslintExplicitGlobalComment 屬性新增至範圍分析中的 Variable 物件,以指示變數是因 /* global */ 註解而引入的。此屬性未記錄在文件中,並且 ESLint 團隊無法在 ESLint 核心之外找到任何屬性的用法。該屬性已在 ESLint v6 中移除,並替換為 eslintExplicitGlobalComments 屬性,如果變數是用多個 /* global */ 註解宣告的,則該屬性可以包含所有 /* global */ 註解的列表。

解決方案: 如果您維護使用 eslintExplicitGlobalComment 屬性的規則,請將其更新為使用 eslintExplicitGlobalComments 屬性作為列表。

相關問題: eslint/rfcs#17


Linter 不再嘗試從檔案系統載入遺失的解析器

先前,當使用先前未定義的解析器對程式碼進行 linting 時,Linter API 會嘗試從檔案系統載入解析器。但是,此行為令人困惑,因為 Linter 在任何其他情況下都永遠不會存取檔案系統,並且很難確保在從檔案系統載入解析器時會找到正確的解析器。

在 ESLint v6 中,Linter 將不再執行任何檔案系統操作,包括載入解析器。

解決方案: 如果您將 Linter 與自訂解析器一起使用,請在使用任何程式碼進行 linting 之前,使用 Linter#defineParser 明確定義解析器。

相關問題: eslint/rfcs#7

變更語言