诊断和日志

Parcel 包含对丰富诊断的支持,这些诊断用于以与格式无关的方式描述错误和警告。它还包含一个内置的日志系统,允许 Reporter 插件处理所有日志和错误,并将它们呈现给用户。

诊断

#

一个 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 对象,具有一组标准化的属性,用于描述日志消息、其来源以及代码框架等上下文。 Reporter 插件使用此信息来记录您的消息,同时完全自由地控制如何格式化和显示此数据。

一个 Logger 具有每个日志级别的函数,包括 verboseinfologwarnerror。这些日志级别指定日志消息的严重程度,这对于格式化和过滤很有用。例如,--log-level CLI 选项可用于选择要查看的消息。每个日志记录函数也只有一个参数,它可以是单个 Diagnostic 对象,也可以是诊断数组,具体取决于要记录的消息数量。

注意:Parcel 插件的结果被缓存。这意味着插件发出的任何日志或警告只会在重建期间显示,而不会在缓存时显示。

日志级别

#
级别 何时使用 函数(s)
verbose 当您想记录任何可用于调试问题的内容时使用,而这些内容对于正常使用来说并不特别有趣。 logger.verbose(...)
info 用于记录与问题无关的任何信息。 logger.info(...)logger.log(...)
warning 用于记录与非关键问题相关的任何内容。 logger.warning(...)
error 用于记录任何严重问题。您可能希望改为抛出 ThrowableDiagnostic 以导致构建失败。 logger.error(...)throw ThrowableDiagnostic(...)

如何记录消息

#

熟悉 Diagnostic 格式后,您可以记录任何想要的内容,从详细消息到带有代码框架、提示和文档 URL 的错误。此示例显示了如何记录警告,包括代码框架、提示和文档 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 对象,并将其发送到 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,
|}
被引用
DiagnosticCodeHighlight, getJSONSourceLocation

DiagnosticSeverity parcel/packages/core/diagnostic/src/diagnostic.js:13

类型
type DiagnosticSeverity = 'error' | 'warn' | 'info';

DiagnosticCodeHighlight parcel/packages/core/diagnostic/src/diagnostic.js:19

注意:制表符始终计为单个字符。这是为了防止跨机器的任何突出显示不匹配。

type DiagnosticCodeHighlight = {|
  start: DiagnosticHighlightLocation,

应为此突出显示突出显示的第一个字符的位置。

  end: DiagnosticHighlightLocation,

应为此突出显示突出显示的最后一个字符的位置。

  message?: string,

应在代码中此位置显示的消息(可选)。

|}
被引用
DiagnosticCodeFrame, generateJSONCodeHighlights

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,以详细了解诊断。

|}
被引用
BuildFailureEvent, DiagnosticLogEvent, DiagnosticWithoutOrigin, Diagnostifiable, ResolveResult, ThrowableDiagnostic, ThrowableDiagnosticOpts, ValidateResult, anyToDiagnostic, errorToDiagnostic

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 {}