診斷與記錄

Parcel 包含對豐富診斷的支援,用於以與格式無關的方式描述錯誤和警告。它還包括一個內建記錄系統,允許報告器外掛處理所有記錄和錯誤,並將它們呈現給使用者。

診斷

#

Diagnostic 是 JavaScript 物件,具有一組建立有用的記錄訊息所需的屬性。這可以是從詳細訊息到警告或錯誤的任何內容。診斷可以包括訊息、關於正在處理的檔案的資訊、程式碼框架、錯誤資訊、關於如何潛在解決問題的提示,以及連結至文件以深入了解。

@parcel/diagnostic 套件中的 ThrowableDiagnostic 類別使用診斷支援來延伸 JavaScript Error 物件。在您的外掛中擲回錯誤時,請使用 ThrowableDiagnostic 物件來附加包含關於錯誤內容的診斷。Parcel 會自動將您的外掛名稱附加為診斷的來源。

import ThrowableDiagnostic from '@parcel/diagnostic';

throw new ThrowableDiagnostic({
diagnostic: {
message: 'An error occurred'
}
});

您也可以一次擲回多個診斷,方法是將陣列傳遞給 ThrowableDiagnosticdiagnostic 選項。

格式化訊息

#

為了格式化診斷中的訊息,支援極簡版本的 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.boldmd.italicmd.underlinemd.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'
}
]
}]
}
});

提示

#

診斷也可以包含有關如何解決問題的提示,以及連結至供使用者進一步了解的說明文件。這些資訊透過 hintsdocumentationURL 屬性提供。

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

#

DiagnosticHighlightLocation parcel/packages/core/diagnostic/src/diagnostic.js:8

這些位置是從 1 開始的(因此 1 是第一行/第一欄)

type DiagnosticHighlightLocation = {|
  +line: number,
  +column: number,
|}
參照
DiagnosticCodeHighlightgetJSONSourceLocation

DiagnosticSeverity 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,

應該顯示在程式碼中此位置的訊息(選用)。

|}
參照
DiagnosticCodeFramegenerateJSONCodeHighlights

DiagnosticCodeFrame 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。

|}
參照
BuildFailureEventDiagnosticLogEventDiagnosticWithoutOriginDiagnostifiableResolveResultThrowableDiagnosticThrowableDiagnosticOptsValidateResultanyToDiagnosticerrorToDiagnostic

PrintableError 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,
}
參照
DiagnostifiableerrorToDiagnostic

DiagnosticWithoutOrigin parcel/packages/core/diagnostic/src/diagnostic.js:91

type DiagnosticWithoutOrigin = {|
  ...Diagnostic,
  origin?: string,
|}
參照
PluginLogger

Diagnostifiable parcel/packages/core/diagnostic/src/diagnostic.js:97

可以轉換為診斷的項目。

類型
type Diagnostifiable = Diagnostic | Array<Diagnostic> | ThrowableDiagnostic | PrintableError | Error | string;
參照
PluginLoggeranyToDiagnostic

anyToDiagnostic 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>,
}
參照
ThrowableDiagnostic

ThrowableDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:198

throw的診斷錯誤包裝器(例如,用於發出建置錯誤訊號)。

interface ThrowableDiagnostic extends Error {
  diagnostics: Array<Diagnostic>,
  constructor(opts: ThrowableDiagnosticOpts): void,
}
參照
DiagnostifiableerrorToDiagnostic

generateJSONCodeHighlights 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> {}
參照
encodeJSONKeyComponent

getJSONSourceLocation parcel/packages/core/diagnostic/src/diagnostic.js:251

轉換 @mischnic/json-sourcemapresult.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;
參照
md

md parcel/packages/core/diagnostic/src/diagnostic.js:299

類型
function md(strings: Array<string>, ...params: Array<TemplateInput>): string {}