遷移至 v2.0.0
ESLint v2.0.0 是第二個主要版本發佈。因此,在 ESLint 在 0.x 和 1.x 版本期間的運作方式與未來運作方式之間,存在一些重大變更。這些變更是直接根據 ESLint 使用者社群的回饋而產生,並且在未適當考量升級路徑的情況下進行。我們相信這些變更使 ESLint 變得更好,雖然升級需要一些工作,但我們希望這次升級的痛苦夠小,讓您能看到升級的好處。
重要: 如果您是從 0.x 版本升級,請參考遷移至 1.0.0 作為您的起點。
規則 Schema 變更
由於規則 schema 運作方式的怪異之處,如果選項足夠複雜,您可能需要在規則 schema 中考慮規則嚴重性(0、1 或 2)。這將導致如下 schema
module.exports = {
"type": "array",
"items": [
{
"enum": [0, 1, 2]
},
{
"enum": ["always", "never"]
}
],
"minItems": 1,
"maxItems": 2
};
這讓規則開發人員感到困惑,因為規則似乎不應該負責驗證自己的嚴重性。在 2.0.0 中,規則不再需要檢查自己的嚴重性。
要解決: 如果您正在匯出檢查嚴重性的規則 schema,您需要進行幾項變更
- 從 schema 中移除嚴重性
- 將
minItems
從 1 調整為 0 - 將
maxItems
減 1 進行調整
以下是正確轉換後上述 schema 的樣子
module.exports = {
"type": "array",
"items": [
{
"enum": ["always", "never"]
}
],
"minItems": 0,
"maxItems": 1
};
已移除的規則
以下規則已被棄用,並建立了新規則來取代它們。以下是已移除規則及其取代規則的列表
- no-arrow-condition 已被 no-confusing-arrow 和 no-constant-condition 的組合取代。開啟這兩個規則以獲得與
no-arrow-condition
相同的功能。 - no-empty-label 已被 no-labels 和
{"allowLoop": true, "allowSwitch": true}
選項取代。 - space-after-keywords 已被 keyword-spacing 取代。
- space-before-keywords 已被 keyword-spacing 取代。
- space-return-throw-case 已被 keyword-spacing 取代。
要解決: 您需要更新您的規則設定以使用新規則。當您使用已移除的規則時,ESLint v2.0.0 也會發出警告,並建議取代規則。希望這能在升級過程中減少意外。
設定級聯變更
在 2.0.0 之前,如果一個目錄同時包含 .eslintrc
檔案和具有 ESLint 設定資訊的 package.json
檔案,則這兩個檔案的設定將會合併在一起。在 2.0.0 中,僅使用 .eslintrc.*
檔案中的設定,而當兩者都存在時,package.json
中的設定將被忽略。否則,package.json
仍然可以與 ESLint 設定一起使用,但前提是沒有其他 .eslintrc.*
檔案存在。
要解決: 如果您在同一個目錄中同時擁有 .eslintrc.*
和具有 ESLint 設定資訊的 package.json
,請將您的設定合併到其中一個檔案中。
內建全域變數
在 2.0.0 之前,作為 ES6 標準化一部分的新全域變數(例如 Promise
、Map
、Set
和 Symbol
)包含在內建全域環境中。當例如 no-undef
允許使用 Promise
建構子時,即使在 promises 不可用的 ES5 程式碼中,這也可能導致潛在問題。在 2.0.0 中,內建環境僅包含標準 ES5 全域變數,而新的 ES6 全域變數已移至 es6
環境。
要解決: 如果您正在編寫 ES6 程式碼,如果您尚未啟用 es6
環境,請啟用它
// In your .eslintrc
{
env: {
es6: true
}
}
// Or in a configuration comment
/*eslint-env es6*/
語言選項
在 2.0.0 之前,啟用語言選項的方式是在您的設定中使用 ecmaFeatures
。在 2.0.0 中
ecmaFeatures
屬性現在位於頂層parserOptions
屬性下。- 所有 ECMAScript 6
ecmaFeatures
標誌都已被移除,改為parserOptions
下的ecmaVersion
屬性,該屬性可以設定為 3、5(預設)或 6。 ecmaFeatures.modules
標誌已被parserOptions
下的sourceType
屬性取代,該屬性可以設定為"script"
(預設)或"module"
以用於 ES6 模組。
要解決: 如果您在 ecmaFeatures
中使用任何 ECMAScript 6 功能標誌,您需要改用 ecmaVersion: 6
。ECMAScript 6 功能標誌為
arrowFunctions
- 啟用 箭頭函式binaryLiterals
- 啟用 二進位字面值blockBindings
- 啟用let
和const
(又稱 區塊綁定)classes
- 啟用類別defaultParams
- 啟用 預設函式參數destructuring
- 啟用 解構forOf
- 啟用for-of
迴圈generators
- 啟用 產生器modules
- 啟用模組和全域嚴格模式objectLiteralComputedProperties
- 啟用 計算物件字面值屬性名稱objectLiteralDuplicateProperties
- 在嚴格模式下啟用 重複的物件字面值屬性objectLiteralShorthandMethods
- 啟用 物件字面值簡寫方法objectLiteralShorthandProperties
- 啟用 物件字面值簡寫屬性octalLiterals
- 啟用 八進位字面值regexUFlag
- 啟用 正規表示式u
旗標regexYFlag
- 啟用 正規表示式y
旗標restParams
- 啟用 其餘參數spread
- 啟用陣列的 展開運算子superInFunctions
- 啟用函式內的super
參考templateStrings
- 啟用 模板字串unicodeCodePointEscapes
- 啟用 程式碼點跳脫
如果您正在使用任何這些旗標,例如
{
ecmaFeatures: {
arrowFunctions: true
}
}
那麼您應該使用 ecmaVersion
啟用 ES6
{
parserOptions: {
ecmaVersion: 6
}
}
如果您在 ecmaFeatures
中使用任何非 ES6 旗標,您需要將這些旗標移至 parserOptions
內。例如
{
ecmaFeatures: {
jsx: true
}
}
那麼您應該將 ecmaFeatures
移至 parserOptions
下
{
parserOptions: {
ecmaFeatures: {
jsx: true
}
}
}
如果您正在使用 ecmaFeatures.modules
來啟用 ES6 模組支援,如下所示
{
ecmaFeatures: {
modules: true
}
}
{
parserOptions: {
sourceType: "module"
}
}
此外,如果您在規則內使用 context.ecmaFeatures
,那麼您需要透過以下方式更新您的程式碼
- 如果您正在使用 ES6 功能旗標,例如
context.ecmaFeatures.blockBindings
,請重寫以檢查context.parserOptions.ecmaVersion > 5
。 - 如果您正在使用
context.ecmaFeatures.modules
,請重寫以檢查 Program 節點的sourceType
屬性是否為"module"
。 - 如果您正在使用非 ES6 功能旗標,例如
context.ecmaFeatures.jsx
,請重寫以檢查context.parserOptions.ecmaFeatures.jsx
。
如果您有一個具有規則的外掛程式,並且您正在使用 RuleTester,那麼您也需要更新您為使用 ecmaFeatures
的規則傳遞的選項。例如
var ruleTester = new RuleTester();
ruleTester.run("no-var", rule, {
valid: [
{
code: "let x;",
parserOptions: { ecmaVersion: 6 }
}
]
});
如果您沒有在您的設定或您的自訂/外掛程式規則和測試中使用 ecmaFeatures
,則無需進行任何變更。
"eslint:recommended"
中的新規則
{
"extends": "eslint:recommended"
}
在 2.0.0 中,以下 11 個規則已新增至 "eslint:recommended"
。
- constructor-super
- no-case-declarations
- no-class-assign
- no-const-assign
- no-dupe-class-members
- no-empty-pattern
- no-new-symbol
- no-self-assign
- no-this-before-super
- no-unexpected-multiline
- no-unused-labels
要解決: 如果您不想收到這些規則的通知,您可以簡單地停用這些規則。
{
"extends": "eslint:recommended",
"rules": {
"no-case-declarations": 0,
"no-class-assign": 0,
"no-const-assign": 0,
"no-dupe-class-members": 0,
"no-empty-pattern": 0,
"no-new-symbol": 0,
"no-self-assign": 0,
"no-this-before-super": 0,
"no-unexpected-multiline": 0,
"no-unused-labels": 0,
"constructor-super": 0
}
}
Scope 分析變更
我們在 scope 分析中發現了一些需要解決的錯誤。具體來說,我們沒有正確地考慮以所有定義方式定義的全域變數。
最初,Variable
物件和 Reference
物件互相參考
Variable#references
屬性是一個Reference
物件陣列,這些物件正在參考該變數。Reference#resolved
屬性是一個Variable
物件,該物件被參考。
但在 1.x 之前,以下變數和參考在這些屬性中具有錯誤的值(空值)
- 全域中的
var
宣告。 - 全域中的
function
宣告。 - 在設定檔中定義的變數。
- 在
/* global */
註解中定義的變數。
現在,這些變數和參考在這些屬性中具有正確的值。
Scope#through
屬性具有 Reference#resolved
為 null
的參考。因此,由於此變更,Scope#through
屬性的值也已變更。
要解決: 如果您正在使用 Scope#through
來尋找內建全域變數的參考,您需要進行幾項變更。
例如,這是您在 1.x 中可能找到 window
全域變數的方式
var globalScope = context.getScope();
globalScope.through.forEach(function(reference) {
if (reference.identifier.name === "window") {
checkForWindow(reference);
}
});
這是一種迂迴的方式來尋找變數,因為它是 ESLint 事後新增的。window
變數位於 Scope#through
中,因為找不到定義。
在 2.0.0 中,window
不再位於 Scope#through
中,因為我們已將正確的宣告新增回來。這表示您可以直接參考 window
物件(或任何其他全域物件)。因此,先前的範例將變更為這樣
var globalScope = context.getScope();
var variable = globalScope.set.get("window");
if (variable) {
variable.references.forEach(checkForWindow);
}
延伸閱讀:https://estools.github.io/escope/
使用 eslint:recommended
時的預設變更
如果您從 eslint:recommended
擴充,並且僅使用嚴重性啟用 no-multiple-empty-lines
或 func-style
,例如
{
"extends": "eslint:recommended",
"rules": {
"no-multiple-empty-lines": 2,
"func-style": 2
}
}
規則 no-multiple-empty-lines
沒有預設例外,但在 ESLint 1.x
中,套用了 eslint:recommended
的預設值,使得最多允許兩個空行。
規則 func-style
的預設設定為 "expression"
,但在 ESLint 1.x
中,eslint:recommended
將其預設為 "declaration"
。
ESLint 2.0.0 移除了這些衝突的預設值,因此您可能會開始看到與這些規則相關的 lint 錯誤。
要解決: 如果您想要維持先前的行為,請透過新增 {"max": 2}
來更新 no-multiple-empty-lines
的設定,並將 func-style
變更為 "declaration"
。例如
{
"extends": "eslint:recommended",
"rules": {
"no-multiple-empty-lines": [2, {"max": 2}],
"func-style": [2, "declaration"]
}
}
SourceCode 建構子 (Node API) 變更
SourceCode
建構子可以處理 Unicode BOM。如果第一個引數 text
具有 BOM,SourceCode
建構子會將 true
設定為 this.hasBOM
並從文字中剝離 BOM。
var SourceCode = require("eslint").SourceCode;
var code = new SourceCode("\uFEFFvar foo = bar;", ast);
assert(code.hasBOM === true);
assert(code.text === "var foo = bar;");
因此,第二個引數 ast
也應該從剝離的文字中解析。
要解決: 如果您在程式碼中使用 SourceCode
建構子,請在剝離 BOM 後解析原始碼
var ast = yourParser.parse(text.replace(/^\uFEFF/, ""), options);
var sourceCode = new SourceCode(text, ast);
規則變更
strict
- 預設為"safe"
(先前的預設值為"function"
)
外掛程式不再具有預設設定
在 v2.0.0 之前,外掛程式可以為外掛程式指定 rulesConfig
。每當有人使用外掛程式時,都會自動套用 rulesConfig
,這與 ESLint 在其他所有情況下的做法相反(預設情況下沒有任何規則開啟)。為了使外掛程式行為一致,我們已移除外掛程式中對 rulesConfig
的支援。
要解決: 如果您在設定檔中使用外掛程式,您將需要在設定檔中手動啟用外掛程式規則。