自訂格式器
自訂格式器可讓您以最符合您需求的格式顯示程式碼檢查結果,無論是特定檔案格式、特定顯示樣式,還是針對特定工具優化的格式。
ESLint 也有您可以使用的內建格式器。
您可以直接在專案中包含自訂格式器,或建立 npm 套件來單獨發佈它們。
建立自訂格式器
每個格式器都是一個函式,它接收一個 results
物件和一個 context
作為參數,並返回一個字串。例如,以下是內建的JSON 格式器的實作方式
//my-awesome-formatter.js
module.exports = function(results, context) {
return JSON.stringify(results, null, 2);
};
格式器也可以是異步函式 (從 ESLint v8.4.0 開始),以下顯示一個簡單的範例
//my-awesome-formatter.js
module.exports = async function(results) {
const formatted = await asyncTask();
return formatted;
};
要使用此格式器執行 ESLint,您可以使用 -f
(或 --format
) 命令列旗標。您必須以句點 (.
) 開始本機定義的自訂格式器的路徑,例如 ./my-awesome-formatter.js
或 ../formatters/my-awesome-formatter.js
。
eslint -f ./my-awesome-formatter.js src/
本節的其餘部分包含有關如何使用自訂格式器函式的參考資訊。
results
參數
傳遞給格式器的 results
物件是一個 result
物件的陣列,其中包含個別檔案的程式碼檢查結果。以下是一個範例輸出
[
{
filePath: "/path/to/a/file.js",
messages: [
{
ruleId: "curly",
severity: 2,
message: "Expected { after 'if' condition.",
line: 2,
column: 1,
nodeType: "IfStatement"
},
{
ruleId: "no-process-exit",
severity: 2,
message: "Don't use process.exit(); throw an error instead.",
line: 3,
column: 1,
nodeType: "CallExpression"
}
],
errorCount: 2,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0,
source:
"var err = doStuff();\nif (err) console.log('failed tests: ' + err);\nprocess.exit(1);\n"
},
{
filePath: "/path/to/Gruntfile.js",
messages: [],
errorCount: 0,
warningCount: 0,
fixableErrorCount: 0,
fixableWarningCount: 0
}
]
result
物件
results
陣列中的每個物件都是一個 result
物件。每個 result
物件都包含已檢查程式碼的檔案路徑,以及有關所遇到程式碼檢查問題的資訊。以下是每個 result
物件上可用的屬性
- filePath:已檢查程式碼的檔案的絕對路徑。
- messages:
message
物件的陣列。有關訊息的更多資訊,請參閱下文。 - errorCount:給定檔案的錯誤數。
- warningCount:給定檔案的警告數。
- stats:只有在使用
stats
選項時才存在的選用stats
物件。 - source:給定檔案的原始程式碼。如果此檔案沒有錯誤/警告,或如果存在
output
屬性,則會省略此屬性。 - output:給定檔案的原始程式碼,其中已應用盡可能多的修復。如果沒有可用的修復,則會省略此屬性。
message
物件
每個 message
物件都包含有關某些原始程式碼觸發的 ESLint 規則的資訊。每個 message
物件上可用的屬性為
- ruleId:產生錯誤或警告的規則的 ID。如果錯誤或警告不是由規則產生的 (例如,如果是剖析錯誤),則此為
null
。 - severity:失敗的嚴重性,
1
代表警告,2
代表錯誤。 - message:錯誤的人類可讀描述。
- line:問題所在行的位置。
- column:問題所在列的位置。
- nodeType:(已過時: 此屬性將在未來版本的 ESLint 中移除。) AST 中的節點類型,如果問題與特定 AST 節點無關,則為
null
。
context
參數
格式器函式接收一個 context
物件作為其第二個參數。該物件具有以下屬性
cwd
:目前的工作目錄。此值來自 ESLint 類別的cwd
建構函式選項。maxWarningsExceeded
(選用):如果設定了--max-warnings
並且警告數量超過了限制,則此屬性的值是一個包含兩個屬性的物件maxWarnings
:--max-warnings
選項的值foundWarnings
:程式碼檢查警告的數量
rulesMeta
:規則的meta
屬性值。有關規則的更多資訊,請參閱自訂規則頁面。
例如,如果已執行 no-extra-semi
規則,則該物件會如下所示
{
cwd: "/path/to/cwd",
maxWarningsExceeded: {
maxWarnings: 5,
foundWarnings: 6
},
rulesMeta: {
"no-extra-semi": {
type: "suggestion",
docs: {
description: "disallow unnecessary semicolons",
recommended: true,
url: "https://eslint.dev.org.tw/docs/rules/no-extra-semi"
},
fixable: "code",
schema: [],
messages: {
unexpected: "Unnecessary semicolon."
}
}
},
}
注意:如果程式碼檢查是由已過時的 CLIEngine
類別執行的,則 context
參數可能是一個不同的值,因為它取決於 API 使用者。如果您想要支援舊版環境,請檢查 context
參數是否為預期值。
傳遞參數給格式器
雖然格式器函式除了 results 物件和 context 之外不接收參數,但可以使用以下描述的方法將其他資料傳遞到自訂格式器中。
使用環境變數
自訂格式器可以存取環境變數,因此可以根據環境變數資料變更其行為。
以下範例使用 FORMATTER_SKIP_WARNINGS
環境變數來判斷是否在結果中顯示警告
module.exports = function(results) {
var skipWarnings = process.env.FORMATTER_SKIP_WARNINGS === "true";
var results = results || [];
var summary = results.reduce(
function(seq, current) {
current.messages.forEach(function(msg) {
var logMessage = {
filePath: current.filePath,
ruleId: msg.ruleId,
message: msg.message,
line: msg.line,
column: msg.column
};
if (msg.severity === 1) {
logMessage.type = "warning";
seq.warnings.push(logMessage);
}
if (msg.severity === 2) {
logMessage.type = "error";
seq.errors.push(logMessage);
}
});
return seq;
},
{
errors: [],
warnings: []
}
);
if (summary.errors.length > 0 || summary.warnings.length > 0) {
var warnings = !skipWarnings ? summary.warnings : []; // skip the warnings in that case
var lines = summary.errors
.concat(warnings)
.map(function(msg) {
return (
"\n" +
msg.type +
" " +
msg.ruleId +
"\n " +
msg.filePath +
":" +
msg.line +
":" +
msg.column
);
})
.join("\n");
return lines + "\n";
}
};
您將使用此自訂格式器和如下設定的環境變數執行 ESLint
FORMATTER_SKIP_WARNINGS=true eslint -f ./my-awesome-formatter.js src/
輸出將會是
error space-infix-ops
src/configs/bundler.js:6:8
error semi
src/configs/bundler.js:6:10
複雜的參數傳遞
如果您發現自訂格式器模式沒有為您想要格式化 ESLint 結果的方式提供足夠的選項,最好的選擇是使用 ESLint 的內建 JSON 格式器並將輸出傳送到第二個程式。例如
eslint -f json src/ | your-program-that-reads-JSON --option
在此範例中,your-program-that-reads-json
程式可以接受 ESLint 結果的原始 JSON 並在輸出其自己的結果格式之前處理它。您可以將盡可能多的命令列參數傳遞給該程式,以自訂輸出。
為終端機格式化
像 iTerm2 或 Guake 這樣的現代終端機期望特定的結果格式在點擊時自動開啟檔案名稱。大多數終端機都支援此格式以達到此目的
file:line:column
打包自訂格式器
自訂格式器可以透過 npm 套件發佈。為此,請建立一個名稱為 eslint-formatter-*
格式的 npm 套件,其中 *
是您的格式器的名稱 (例如 eslint-formatter-awesome
)。然後專案應該安裝套件並使用 -f
(或 --format
) 旗標使用自訂格式器,如下所示
eslint -f awesome src/
因為當指定的格式器不是以句點開頭時,ESLint 知道要尋找以 eslint-formatter-
開頭的套件,因此在使用已打包的自訂格式器時,您不需要輸入 eslint-formatter-
。
自訂格式器的 package.json
的提示
main
進入點必須是實作您的自訂格式器的 JavaScript 檔案。- 新增這些
keywords
來幫助使用者找到您的格式器"eslint"
"eslint-formatter"
"eslintformatter"
請參閱 npm 上的所有自訂格式器。
範例
摘要格式器
一個僅報告錯誤和警告總數的格式器看起來像這樣
module.exports = function(results, context) {
// accumulate the errors and warnings
var summary = results.reduce(
function(seq, current) {
seq.errors += current.errorCount;
seq.warnings += current.warningCount;
return seq;
},
{ errors: 0, warnings: 0 }
);
if (summary.errors > 0 || summary.warnings > 0) {
return (
"Errors: " +
summary.errors +
", Warnings: " +
summary.warnings +
"\n"
);
}
return "";
};
使用上述摘要格式器執行 eslint
eslint -f ./my-awesome-formatter.js src/
將產生以下輸出
Errors: 2, Warnings: 4
詳細格式器
更複雜的報告可能如下所示
module.exports = function(results, context) {
var results = results || [];
var summary = results.reduce(
function(seq, current) {
current.messages.forEach(function(msg) {
var logMessage = {
filePath: current.filePath,
ruleId: msg.ruleId,
ruleUrl: context.rulesMeta[msg.ruleId].docs.url,
message: msg.message,
line: msg.line,
column: msg.column
};
if (msg.severity === 1) {
logMessage.type = "warning";
seq.warnings.push(logMessage);
}
if (msg.severity === 2) {
logMessage.type = "error";
seq.errors.push(logMessage);
}
});
return seq;
},
{
errors: [],
warnings: []
}
);
if (summary.errors.length > 0 || summary.warnings.length > 0) {
var lines = summary.errors
.concat(summary.warnings)
.map(function(msg) {
return (
"\n" +
msg.type +
" " +
msg.ruleId + (msg.ruleUrl ? " (" + msg.ruleUrl + ")" : "") +
"\n " +
msg.filePath +
":" +
msg.line +
":" +
msg.column
);
})
.join("\n");
return lines + "\n";
}
};
當您使用此自訂格式器執行 ESLint 時
eslint -f ./my-awesome-formatter.js src/
輸出為
error space-infix-ops (https://eslint.dev.org.tw/docs/rules/space-infix-ops)
src/configs/bundler.js:6:8
error semi (https://eslint.dev.org.tw/docs/rules/semi)
src/configs/bundler.js:6:10
warning no-unused-vars (https://eslint.dev.org.tw/docs/rules/no-unused-vars)
src/configs/bundler.js:5:6
warning no-unused-vars (https://eslint.dev.org.tw/docs/rules/no-unused-vars)
src/configs/bundler.js:6:6
warning no-shadow (https://eslint.dev.org.tw/docs/rules/no-shadow)
src/configs/bundler.js:65:32
warning no-unused-vars (https://eslint.dev.org.tw/docs/rules/no-unused-vars)
src/configs/clean.js:3:6