診斷與記錄
Parcel 包含對豐富診斷的支援,用於以與格式無關的方式描述錯誤和警告。它還包括一個內建記錄系統,允許報告器外掛處理所有記錄和錯誤,並將它們呈現給使用者。
診斷
#Diagnostic
是 JavaScript 物件,具有一組建立有用的記錄訊息所需的屬性。這可以是從詳細訊息到警告或錯誤的任何內容。診斷可以包括訊息、關於正在處理的檔案的資訊、程式碼框架、錯誤資訊、關於如何潛在解決問題的提示,以及連結至文件以深入了解。
@parcel/diagnostic
套件中的 ThrowableDiagnostic
類別使用診斷支援來延伸 JavaScript Error
物件。在您的外掛中擲回錯誤時,請使用 ThrowableDiagnostic
物件來附加包含關於錯誤內容的診斷。Parcel 會自動將您的外掛名稱附加為診斷的來源。
import ThrowableDiagnostic from '@parcel/diagnostic';
throw new ThrowableDiagnostic({
diagnostic: {
message: 'An error occurred'
}
});
您也可以一次擲回多個診斷,方法是將陣列傳遞給 ThrowableDiagnostic
的 diagnostic
選項。
格式化訊息
#為了格式化診斷中的訊息,支援極簡版本的 Markdown。此格式特別建置為與終端機和其他呈現目標(例如瀏覽器和編輯器)相容,同時在沒有任何格式化顯示時也不會過於難以理解。@parcel/reporter-cli
使用 @parcel/markdown-ansi
函式庫將這些 Markdown 字串轉換為 ANSI 逸出序列,以便在終端機中呈現。
支援的 Markdown 功能為 **粗體**
、*斜體*
/_斜體_
、__底線__
和 ~~刪除線~~
。
@parcel/diagnostic
套件包含一些用於處理 Markdown 訊息的工具程式。md
標記範本字串會處理 Markdown 字串中內插表達式的跳脫。這可確保表達式中的任何特殊 Markdown 字元不會影響格式化。
import {md} from '@parcel/diagnostic';
throw new ThrowableDiagnostic({
diagnostic: {
message: md`**Error**: Could not parse ${filePath}`
}
});
還有一些用於格式化內插表達式的工具程式,包括 md.bold
、md.italic
、md.underline
和 md.strikethrough
。
import {md} from '@parcel/diagnostic';
throw new ThrowableDiagnostic({
diagnostic: {
message: md`**Error**: Could not parse ${md.underline(filePath)}`
}
});
程式碼框架
#Diagnostic
可能附帶一個或多個程式碼框架。程式碼框架包含一個檔案路徑,以及一個或多個程式碼重點,這些重點提供有關錯誤發生在檔案中何處的背景資訊。程式碼重點由檔案中的行和欄位位置定義,並且可能在該位置顯示訊息。
程式碼框架也應包含發生錯誤的檔案的原始程式碼。如果省略,Parcel 會從檔案系統中讀取檔案。但是,在許多情況下,輸入原始程式碼可能來自之前執行的另一個外掛程式,因此程式碼會以某種方式進行修改。將程式碼包含在程式碼框架中可避免此問題。
throw new ThrowableDiagnostic({
diagnostic: {
message: md`Could not parse ${asset.filePath}`,
codeFrames: [{
filePath: asset.filePath,
code: await asset.getCode(),
codeHighlights: [
{
start: {
line: 1,
column: 5,
},
end: {
line: 2,
column: 3,
},
message: 'Expected a string but got a number'
}
]
}]
}
});
提示
#診斷也可以包含有關如何解決問題的提示,以及連結至供使用者進一步了解的說明文件。這些資訊透過 hints
和 documentationURL
屬性提供。
throw new ThrowableDiagnostic({
diagnostic: {
message: 'Could not find a config file',
hints: ['Create a tool.config.json file in the project root.'],
documentationURL: 'http://example.com/'
}
});
記錄器
#Parcel 的記錄器可用於記錄外掛程式中的訊息。外掛程式的每個函式都會傳遞一個 Logger
執行個體作為參數。此執行個體具有 Parcel 識別您的外掛程式為訊息來源所需的所有資訊。
記錄器接受診斷,診斷是 JavaScript 物件,其中包含一組標準化的屬性,用於描述記錄訊息、其來源和背景,例如程式碼框架。報告程式外掛程式使用這些資訊來記錄您的訊息,同時完全自由地決定如何格式化和顯示這些資料。
一個記錄器
針對每個記錄層級都有函式,包括詳細
、資訊
、記錄
、警告
和錯誤
。這些記錄層級指定記錄訊息的嚴重性,這對於格式化和篩選很有用。例如,--log-level
CLI 選項可用於選擇您想要查看的訊息。每個記錄函式也有一個單一參數,可以是單一診斷
物件或診斷陣列,具體取決於您要記錄多少訊息。
注意:Parcel 外掛程式的結果會快取。這表示外掛程式發出的任何記錄或警告只會在重新建置期間顯示,而不會在快取時顯示。
記錄層級
#層級 | 何時使用 | 函式 |
---|---|---|
詳細 | 當您想要記錄任何可用於除錯問題的內容時使用,但對於一般使用來說並非特別有趣。 | logger.verbose(...) |
資訊 | 使用此記錄任何與問題無關的資訊。 | logger.info(...) 或 logger.log(...) |
警告 | 使用此記錄任何與非重大問題相關的內容。 | logger.warning(...) |
錯誤 | 使用此記錄任何重大問題。您可能想要擲出ThrowableDiagnostic 來導致建置失敗。 | logger.error(...) 或 throw ThrowableDiagnostic(...) |
如何記錄訊息
#熟悉 Diagnostic
格式後,即可記錄任何想要的內容,從冗長的訊息到帶有程式碼框架和提示的錯誤。此範例顯示如何記錄警告,並完整提供程式碼框架、提示和文件網址。
import {Transformer} from '@parcel/plugin';
export default new Transformer({
async transform({asset, logger}) {
// ...
logger.warn({
message: 'This feature is deprecated.',
codeFrames: [{
filePath: asset.filePath,
code: await asset.getCode(),
codeHighlights: [{
start: {
line: 1,
column: 5
},
end: {
line: 1,
column: 10
}
}]
}],
hints: ['Please use this other feature instead.'],
documentationURL: 'http://example.com/'
});
},
});
自動收集的記錄和錯誤
#Parcel 會自動收集使用 console.log
和其他 console
方法建立的任何記錄。每當呼叫 console.log
時,Parcel 會擷取它,將它轉換為 Diagnostic
物件,並將它傳送給 Reporter 外掛程式,就像傳送給 logger
的訊息一樣。不過,不建議這麼做,因為 Parcel 沒有直接呼叫 logger
時那麼多資訊。
Parcel 也會處理外掛程式中擲回的任何錯誤。這些錯誤會轉換成 Diagnostic
,並加入有關外掛程式的資訊。擲回的錯誤會傳送給 Reporter 外掛程式,而且會暫停建置。
API
#PluginLogger parcel/packages/core/logger/src/Logger.js:90
interface PluginLogger {
verbose(diagnostic: DiagnosticWithoutOrigin | Array<DiagnosticWithoutOrigin>): void,
info(diagnostic: DiagnosticWithoutOrigin | Array<DiagnosticWithoutOrigin>): void,
log(diagnostic: DiagnosticWithoutOrigin | Array<DiagnosticWithoutOrigin>): void,
warn(diagnostic: DiagnosticWithoutOrigin | Array<DiagnosticWithoutOrigin>): void,
error(input: Diagnostifiable | DiagnosticWithoutOrigin | Array<DiagnosticWithoutOrigin>): void,
}
參照
Bundler、Compressor、DedicatedThreadValidator、MultiThreadValidator、Namer、Optimizer、Packager、Reporter、Resolver、Runtime、TransformerDiagnosticHighlightLocation parcel/packages/core/diagnostic/src/diagnostic.js:8
這些位置是從 1 開始的(因此 1
是第一行/第一欄)
type DiagnosticHighlightLocation = {|
+line: number,
+column: number,
|}
參照
DiagnosticCodeHighlight,getJSONSourceLocationDiagnosticSeverity parcel/packages/core/diagnostic/src/diagnostic.js:13
類型
type DiagnosticSeverity = 'error' | 'warn' | 'info';
DiagnosticCodeHighlight parcel/packages/core/diagnostic/src/diagnostic.js:19
注意:一個 tab 字元永遠被計算為一個單一字元。這是為了避免在不同機器上突顯不一致
type DiagnosticCodeHighlight = {|
start: DiagnosticHighlightLocation,
此突顯應該突顯的第一個字元的所在位置。
end: DiagnosticHighlightLocation,
此突顯應該突顯的最後一個字元的所在位置。
message?: string,
應該顯示在程式碼中此位置的訊息(選用)。
|}
參照
DiagnosticCodeFrame,generateJSONCodeHighlightsDiagnosticCodeFrame parcel/packages/core/diagnostic/src/diagnostic.js:33
描述如何格式化程式碼框架。程式碼框架是程式碼片段的可視化,其中包含一定數量的程式碼突顯,指向程式碼中的特定區塊。
type DiagnosticCodeFrame = {|
code?: string,
原始檔的內容。
如果沒有傳遞程式碼,它將從 filePath 讀取,請記住資產目前的程式碼可能與輸入內容不同。
filePath?: string,
此程式碼框架所述檔案的路徑(選用,絕對或相對於專案根目錄)
language?: string,
此程式碼框架所述檔案的語言(選用)
codeHighlights: Array<DiagnosticCodeHighlight>,
|}
參照
診斷Diagnostic parcel/packages/core/diagnostic/src/diagnostic.js:53
一個與樣式無關的錯誤、警告和資訊發射方式。報告器負責呈現訊息、程式碼框架、提示等。
type Diagnostic = {|
message: string,
這是您想要記錄的訊息。
origin?: string,
拋出此錯誤的插件或檔案名稱
stack?: string,
錯誤的堆疊追蹤(選用)
name?: string,
錯誤名稱(選用)
codeFrames?: ?Array<DiagnosticCodeFrame>,
程式碼框架指向此診斷連結的檔案中某個位置(選用)
hints?: Array<string>,
建議解決此問題方法的字串選用清單
documentationURL?: string,
了解診斷的更多資訊的說明文件 URL。
|}
參照
BuildFailureEvent、DiagnosticLogEvent、DiagnosticWithoutOrigin、Diagnostifiable、ResolveResult、ThrowableDiagnostic、ThrowableDiagnosticOpts、ValidateResult、anyToDiagnostic、errorToDiagnosticPrintableError parcel/packages/core/diagnostic/src/diagnostic.js:78
interface PrintableError extends Error {
fileName?: string,
filePath?: string,
codeFrame?: string,
highlightedCodeFrame?: string,
loc?: ?{
column: number,
line: number,
...
},
source?: string,
}
參照
Diagnostifiable、errorToDiagnosticDiagnosticWithoutOrigin parcel/packages/core/diagnostic/src/diagnostic.js:91
type DiagnosticWithoutOrigin = {|
...Diagnostic,
origin?: string,
|}
參照
PluginLoggerDiagnostifiable parcel/packages/core/diagnostic/src/diagnostic.js:97
可以轉換為診斷的項目。
類型
type Diagnostifiable = Diagnostic | Array<Diagnostic> | ThrowableDiagnostic | PrintableError | Error | string;
參照
PluginLogger、anyToDiagnosticanyToDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:106
將指定值標準化成診斷。
類型
function anyToDiagnostic(input: Diagnostifiable): Array<Diagnostic> {}
errorToDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:123
將指定錯誤標準化成診斷。
類型
function errorToDiagnostic(error: ThrowableDiagnostic | PrintableError | string, defaultValues?: {|
origin?: ?string,
filePath?: ?string,
|}): Array<Diagnostic> {}
ThrowableDiagnosticOpts parcel/packages/core/diagnostic/src/diagnostic.js:189
type ThrowableDiagnosticOpts = {
diagnostic: Diagnostic | Array<Diagnostic>,
}
參照
ThrowableDiagnosticThrowableDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:198
可throw
的診斷錯誤包裝器(例如,用於發出建置錯誤訊號)。
interface ThrowableDiagnostic extends Error {
diagnostics: Array<Diagnostic>,
constructor(opts: ThrowableDiagnosticOpts): void,
}
參照
Diagnostifiable、errorToDiagnosticgenerateJSONCodeHighlights parcel/packages/core/diagnostic/src/diagnostic.js:225
將 JSON5 檔案中包含訊息的位置清單轉換成診斷清單。使用 @mischnic/json-sourcemap。
參數說明
code
:JSON 程式碼ids
:JSON 金鑰路徑清單(key: "/some/parent/child"
)與對應訊息,type
表示 JSON 物件中值的鍵是否應標示。
類型
function generateJSONCodeHighlights(data: string | {|
data: mixed,
pointers: {|
[key: string]: Mapping
|},
|}, ids: Array<{|
key: string,
type?: ?'key' | 'value',
message?: string,
|}>): Array<DiagnosticCodeHighlight> {}
參照
encodeJSONKeyComponentgetJSONSourceLocation parcel/packages/core/diagnostic/src/diagnostic.js:251
轉換 @mischnic/json-sourcemap 中 result.pointers
陣列的項目。
類型
function getJSONSourceLocation(pos: Mapping, type?: ?'key' | 'value'): {|
start: DiagnosticHighlightLocation,
end: DiagnosticHighlightLocation,
|} {}
encodeJSONKeyComponent parcel/packages/core/diagnostic/src/diagnostic.js:281
在 generateJSONCodeHighlights 中使用物件金鑰作為 key
之前,先清除物件金鑰
類型
function encodeJSONKeyComponent(component: string): string {}
escapeMarkdown parcel/packages/core/diagnostic/src/diagnostic.js:287
類型
function escapeMarkdown(s: string): string {}
TemplateInput parcel/packages/core/diagnostic/src/diagnostic.js:296
類型
type TemplateInput = $FlowFixMe;
參照
mdmd parcel/packages/core/diagnostic/src/diagnostic.js:299
類型
function md(strings: Array<string>, ...params: Array<TemplateInput>): string {}