診断とログ
Parcelは、フォーマットに依存しない方法でエラーと警告を記述するために使用される豊富な診断情報をサポートしています。また、Reporterプラグインがすべてのログとエラーを処理し、ユーザーに提示できるようにする組み込みのログシステムも含まれています。
診断情報
#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には、1つ以上のコードフレームを添付できます。コードフレームには、ファイルパスと1つ以上のコードハイライトが含まれており、ファイル内のエラーが発生した場所に関するコンテキストを示します。コードハイライトは、ファイル内の行と列の位置で定義され、その位置に表示されるメッセージが含まれている場合もあります。
コードフレームには、エラーが発生したファイルのソースコードも含まれている必要があります。省略した場合、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がメッセージの起源としてプラグインを識別するために必要なすべての情報が含まれています。
ロガーはDiagnosticを受け入れます。これは、ログメッセージ、その起源、コードフレームなどのコンテキストを記述する標準化されたプロパティのセットを持つJavaScriptオブジェクトです。Reporterプラグインはこの情報を使用してメッセージをログ出力しますが、このデータのフォーマットと表示方法を完全に自由に制御できます。
Loggerには、verbose、info、log、warn、errorなど、各ログレベルの関数があります。これらのログレベルはログメッセージの重大度を指定し、フォーマットとフィルタリングに役立ちます。たとえば、--log-level CLIオプションを使用して、表示するメッセージを選択できます。各ログ出力関数には、1つのパラメーターがあり、ログ出力するメッセージの数に応じて、単一のDiagnosticオブジェクトまたは診断情報の配列のいずれかになります。
**注記**: Parcelプラグインの結果はキャッシュされます。つまり、プラグインが出力するログや警告は、再ビルド時のみ表示され、キャッシュされている場合は表示されません。
ログレベル
#| レベル | 使用する場合 | 関数 |
|---|---|---|
| verbose | 通常の使用ではそれほど興味深いものではない一方で、問題のデバッグに使用できるものをログ出力する場合に使用します。 | |
| info | 問題に関連しない情報をログ出力する場合に使用します。 | logger.info(...)またはlogger.log(...) |
| warning | 重大ではない問題に関連するものをログ出力する場合に使用します。 | |
| error | 重大な問題をログ出力する場合に使用します。代わりにThrowableDiagnosticをスローしてビルドを失敗させることもできます。 | logger.error(...)またはthrow ThrowableDiagnostic(...) |
メッセージのログ出力方法
#Diagnosticのフォーマットに慣れたら、詳細なメッセージからコードフレームとヒントを含むエラーまで、何でもログ出力できます。この例では、コードフレーム、ヒント、ドキュメントURLを含む警告をログ出力する方法を示しています。
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オブジェクトに変換して、loggerに送信されたメッセージと同様にReporterプラグインに送信します。ただし、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
注記: タブ文字は常に1文字としてカウントされます。これは、マシン間でのハイライトの不一致を防ぐためです。
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>, |} 参照元
診断情報診断情報 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
スローできる診断情報ラッパーエラー(ビルドエラーをシグナルするために使用など)。
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 {}