诊断和日志

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

诊断

#

Diagnostic 是一个 JavaScript 对象,具有一组属性,这些属性对于创建有用的日志消息是必需的。这可以是从详细消息到警告或错误的任何内容。诊断可以包括消息、关于正在处理的文件的信息、代码框架、错误信息、关于如何潜在解决问题的提示,以及指向更多文档的链接。

@parcel/diagnostic 包中的 ThrowableDiagnostic 类扩展了 JavaScript 的 Error 对象,并支持诊断。在插件中抛出错误时,使用 ThrowableDiagnostic 对象附加带有错误上下文的诊断。Parcel 将自动将您的插件名称作为诊断的来源。

import ThrowableDiagnostic from "@parcel/diagnostic";

throw new ThrowableDiagnostic({
diagnostic: {
message: "发生了一个错误",
},
});

通过将数组传递给 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`**错误**:无法解析 ${filePath}`,
},
});

还有一些用于格式化插值表达式的实用工具,包括 md.boldmd.italicmd.underlinemd.strikethrough

import { md } from "@parcel/diagnostic";

throw new ThrowableDiagnostic({
diagnostic: {
message: md`**错误**:无法解析 ${md.underline(filePath)}`,
},
});

代码框架

#

Diagnostic 可以附加一个或多个代码框架。代码框架包括文件路径以及一个或多个代码高亮,这些高亮提供了关于错误发生位置的上下文。代码高亮由文件中的行和列位置定义,并且可能还有要在该位置显示的消息。

代码框架还应包括发生错误的文件的源代码。如果省略,Parcel 将从文件系统读取文件。但是,在许多情况下,输入源代码可能来自之前运行的另一个插件,因此代码已以某种方式被修改。在代码框架中包含代码可以避免此问题。

throw new ThrowableDiagnostic({
diagnostic: {
message: md`无法解析 ${asset.filePath}`,
codeFrames: [
{
filePath: asset.filePath,
code: await asset.getCode(),
codeHighlights: [
{
start: {
line: 1,
column: 5,
},
end: {
line: 2,
column: 3,
},
message: "预期是字符串,但得到了数字",
},
],
},
],
},
});

提示

#

诊断还可以包括关于如何修复问题的提示,以及指向文档的链接,供用户了解更多信息。这些通过 hintsdocumentationURL 属性提供。

throw new ThrowableDiagnostic({
diagnostic: {
message: "找不到配置文件",
hints: ["在项目根目录创建 tool.config.json 文件。"],
documentationURL: "http://example.com/",
},
});

日志记录器

#

Parcel 的日志记录器可用于在插件中记录消息。插件的每个函数都作为参数传递了一个 Logger 实例。该实例具有 Parcel 识别消息来源所需的所有信息。

日志记录器接受诊断,这些是具有标准化属性集的 JavaScript 对象,描述日志消息、其来源和上下文(如代码框架)。报告器插件使用这些信息记录您的消息,同时完全自由地决定如何格式化和显示这些数据。

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

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

日志级别

#
级别 使用时机 函数
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: "此功能已弃用。",
codeFrames: [
{
filePath: asset.filePath,
code: await asset.getCode(),
codeHighlights: [
{
start: {
line: 1,
column: 5,
},
end: {
line: 1,
column: 10,
},
},
],
},
],
hints: ["请改用此其他功能。"],
documentationURL: "http://example.com/",
});
},
});

自动收集的日志和错误

#

Parcel 自动收集使用 console.log 和其他 console 方法创建的任何日志。每当调用 console.log 时,Parcel 都会捕获它,将其转换为 Diagnostic 对象,并像处理直接发送到 logger 的消息一样将其发送到报告器插件。但是,不建议这样做,因为 Parcel 没有像直接调用 logger 那样多的信息。

Parcel 还处理插件内部抛出的任何错误。这些被转换为 Diagnostic,并添加了关于插件的信息。抛出的错误被发送到报告器插件,并且构建被中止。

API

#

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

These positions are 1-based (so 1 is the first line/column)

type DiagnosticHighlightLocation = {|
  +line: number,
  +column: number,
|}
Referenced by:
DiagnosticCodeHighlight, getJSONSourceLocation

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

Type
type DiagnosticSeverity = 'error' | 'warn' | 'info';

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

Note: A tab character is always counted as a single character This is to prevent any mismatch of highlighting across machines

type DiagnosticCodeHighlight = {|
  start: DiagnosticHighlightLocation,

Location of the first character that should get highlighted for this highlight.

  end: DiagnosticHighlightLocation,

Location of the last character that should get highlighted for this highlight.

  message?: string,

A message that should be displayed at this location in the code (optional).

|}
Referenced by:
DiagnosticCodeFrame, generateJSONCodeHighlights

DiagnosticCodeFrame parcel/packages/core/diagnostic/src/diagnostic.js:33

Describes how to format a code frame. A code frame is a visualization of a piece of code with a certain amount of code highlights that point to certain chunk(s) inside the code.

type DiagnosticCodeFrame = {|
  code?: string,

The contents of the source file.
If no code is passed, it will be read in from filePath, remember that the asset's current code could be different from the input contents.

  filePath?: string,

Path to the file this code frame is about (optional, absolute or relative to the project root)

  language?: string,

Language of the file this code frame is about (optional)

  codeHighlights: Array<DiagnosticCodeHighlight>,
|}
Referenced by:
Diagnostic

Diagnostic parcel/packages/core/diagnostic/src/diagnostic.js:53

A style agnostic way of emitting errors, warnings and info. Reporters are responsible for rendering the message, codeframes, hints, ...

type Diagnostic = {|
  message: string,

This is the message you want to log.

  origin?: string,

Name of plugin or file that threw this error

  stack?: string,

A stacktrace of the error (optional)

  name?: string,

Name of the error (optional)

  codeFrames?: ?Array<DiagnosticCodeFrame>,

A code frame points to a certain location(s) in the file this diagnostic is linked to (optional)

  hints?: Array<string>,

An optional list of strings that suggest ways to resolve this issue

  documentationURL?: string,

A URL to documentation to learn more about the diagnostic.

|}
Referenced by:
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,
}
Referenced by:
Diagnostifiable, errorToDiagnostic

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

type DiagnosticWithoutOrigin = {|
  ...Diagnostic,
  origin?: string,
|}
Referenced by:
PluginLogger

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

Something that can be turned into a diagnostic.

Type
type Diagnostifiable = Diagnostic | Array<Diagnostic> | ThrowableDiagnostic | PrintableError | Error | string;
Referenced by:
PluginLogger, anyToDiagnostic

anyToDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:106

Normalize the given value into a diagnostic.

Type
function anyToDiagnostic(input: Diagnostifiable): Array<Diagnostic> {}

errorToDiagnostic parcel/packages/core/diagnostic/src/diagnostic.js:123

Normalize the given error into a diagnostic.

Type
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>,
}
Referenced by:
ThrowableDiagnostic

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

An error wrapper around a diagnostic that can be thrown (e.g. to signal a build error).

interface ThrowableDiagnostic extends Error {
  diagnostics: Array<Diagnostic>,
  constructor(opts: ThrowableDiagnosticOpts): void,
}
Referenced by:
Diagnostifiable, errorToDiagnostic

generateJSONCodeHighlights parcel/packages/core/diagnostic/src/diagnostic.js:225

Turns a list of positions in a JSON5 file with messages into a list of diagnostics. Uses @mischnic/json-sourcemap.

Parameter Descriptions
  • code: the JSON code

  • ids: A list of JSON keypaths (key: "/some/parent/child") with corresponding messages, type signifies whether the key of the value in a JSON object should be highlighted.

Type
function generateJSONCodeHighlights(data: string | {|
  data: mixed,
  pointers: {|
    [key: string]: Mapping
  |},
|}, ids: Array<{|
  key: string,
  type?: ?'key' | 'value',
  message?: string,
|}>): Array<DiagnosticCodeHighlight> {}
Referenced by:
encodeJSONKeyComponent

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

Converts entries in @mischnic/json-sourcemap's result.pointers array.

Type
function getJSONSourceLocation(pos: Mapping, type?: ?'key' | 'value'): {|
  start: DiagnosticHighlightLocation,
  end: DiagnosticHighlightLocation,
|} {}

encodeJSONKeyComponent parcel/packages/core/diagnostic/src/diagnostic.js:281

Sanitizes object keys before using them as key in generateJSONCodeHighlights

Type
function encodeJSONKeyComponent(component: string): string {}

escapeMarkdown parcel/packages/core/diagnostic/src/diagnostic.js:287

Type
function escapeMarkdown(s: string): string {}

TemplateInput parcel/packages/core/diagnostic/src/diagnostic.js:296

Type
type TemplateInput = $FlowFixMe;
Referenced by:
md

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

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