Reporter

Reporter plugins receive events from Parcel as they happen throughout the build process. For example, reporters may write status information to stdout, run a dev server, or generate a bundle analysis report at the end of a build.

Example

#

This example writes the number of bundles and build time to stdout when a build is successful.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'buildSuccess') {
let bundles = event.bundleGraph.getBundles();
process.stdout.write(`✨ Built ${bundles.length} bundles in ${event.buildTime}ms!\n`);
}
}
});

Note: Do not use console.log in Reporter plugins. Parcel overrides console methods and routes messages to Reporter plugins. This can create an infinite loop in your Reporter. If you intend to write to stdout/stderr, use process.stdout/process.stderr instead. If another reporter will handle log events, use the provided logger. See Logging for more details.

Build start

#

The buildStart event is emitted when a build is started. In watch mode, it is emitted at the start of each rebuild.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'buildStart') {
process.stdout.write('Started build!\n');
}
}
});

Build progress

#

The buildProgress event is emitted throughout the build. It includes a phase property that indicates which phase of the build is occurring, and events include additional information specific to the phase. For example, events in the transforming phase include a filePath property of the asset being transformed. See BuildProgressEvent.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'buildProgress') {
switch (event.phase) {
case 'transforming':
process.stdout.write(`Transforming ${event.filePath}...\n`);
break;
case 'resolving':
process.stdout.write(`Resolving ${event.dependency.specifier}...\n`);
break;
case 'bundling':
process.stdout.write('Bundling...\n');
break;
case 'packaging':
process.stdout.write(`Packaging ${event.bundle.displayName}...\n`);
break;
case 'optimizing':
process.stdout.write(`Optimizing ${event.bundle.displayName}...\n`);
break;
}
}
}
});

Build success

#

The buildSuccess event is emitted when a build completes successfully. It includes the full bundleGraph that was built, the buildTime, and a list of changedAssets.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'buildSuccess') {
process.stdout.write(`✨ Rebuilt ${event.changedAssets.size} assets in ${event.buildTime}ms!\n`);
}
}
});

Build failure

#

The buildFailure event is emitted when a build is completes with errors. It includes a list of Diagnostic objects describing the errors. See Diagnostics for details.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'buildFailure') {
process.stdout.write(`🚨 Build failed with ${event.diagnostics.length} errors.\n`);
}
}
});

Logging

#

All logging in Parcel is routed through Reporter plugins. The level property indicates the type of each log event. The info, warn, error, and verbose log levels include a Diagnostic object, which provides detail about the context of the log. Other log levels include only a message property.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'log') {
switch (event.level) {
case 'info':
case 'verbose':
process.stdout.write(`ℹ️ ${event.diagnostic.message}\n`);
break;
case 'warn':
process.stdout.write(`⚠️ ${event.diagnostic.message}\n`);
break;
case 'error':
process.stdout.write(`🚨 ${event.diagnostic.message}\n`);
break;
}
}
}
});

Note: Do not use console.log in Reporter plugins, especially when handling log events. Parcel overrides console methods and routes messages to Reporter plugins. This will create an infinite loop in your Reporter. Use process.stdout/process.stderr instead.

Watcher events

#

The watchStart and watchEnd events are emitted when watch mode starts and ends. Unlike buildStart and buildSuccess/buildFailure, the watcher events are only fired once rather than for each build.

import {Reporter} from '@parcel/plugin';

export default new Reporter({
report({event}) {
if (event.type === 'watchStart') {
process.stdout.write(`Watching started\n`);
} else if (event.type === 'watchEnd') {
process.stdout.write(`Watching ended\n`);
}
}
});

Relevant API

#

ProgressLogEvent parcel/packages/core/types/index.js:1742

type ProgressLogEvent = {|
  +type: 'log',
  +level: 'progress',
  +phase?: string,
  +message: string,
|}
Referenced by:
LogEvent

DiagnosticLogEvent parcel/packages/core/types/index.js:1753

A log event with a rich diagnostic

type DiagnosticLogEvent = {|
  +type: 'log',
  +level: 'error' | 'warn' | 'info' | 'verbose',
  +diagnostics: Array<Diagnostic>,
|}
Referenced by:
LogEvent

TextLogEvent parcel/packages/core/types/index.js:1762

type TextLogEvent = {|
  +type: 'log',
  +level: 'success',
  +message: string,
|}
Referenced by:
LogEvent

BuildStartEvent parcel/packages/core/types/index.js:1777

The build just started.

type BuildStartEvent = {|
  +type: 'buildStart',
|}
Referenced by:
ReporterEvent

WatchStartEvent parcel/packages/core/types/index.js:1785

The build just started in watch mode.

type WatchStartEvent = {|
  +type: 'watchStart',
|}
Referenced by:
ReporterEvent

WatchEndEvent parcel/packages/core/types/index.js:1793

The build just ended in watch mode.

type WatchEndEvent = {|
  +type: 'watchEnd',
|}
Referenced by:
ReporterEvent

ResolvingProgressEvent parcel/packages/core/types/index.js:1801

A new Dependency is being resolved.

type ResolvingProgressEvent = {|
  +type: 'buildProgress',
  +phase: 'resolving',
  +dependency: Dependency,
|}
Referenced by:
BuildProgressEvent

TransformingProgressEvent parcel/packages/core/types/index.js:1811

A new Asset is being transformed.

type TransformingProgressEvent = {|
  +type: 'buildProgress',
  +phase: 'transforming',
  +filePath: FilePath,
|}
Referenced by:
BuildProgressEvent

BundlingProgressEvent parcel/packages/core/types/index.js:1821

The BundleGraph is generated.

type BundlingProgressEvent = {|
  +type: 'buildProgress',
  +phase: 'bundling',
|}
Referenced by:
BuildProgressEvent

PackagingProgressEvent parcel/packages/core/types/index.js:1837

A new Bundle is being packaged.

type PackagingProgressEvent = {|
  +type: 'buildProgress',
  +phase: 'packaging',
  +bundle: NamedBundle,
|}
Referenced by:
BuildProgressEvent

OptimizingProgressEvent parcel/packages/core/types/index.js:1847

A new Bundle is being optimized.

type OptimizingProgressEvent = {|
  +type: 'buildProgress',
  +phase: 'optimizing',
  +bundle: NamedBundle,
|}
Referenced by:
BuildProgressEvent

BuildSuccessEvent parcel/packages/core/types/index.js:1868

The build was successful.

type BuildSuccessEvent = {|
  +type: 'buildSuccess',
  +bundleGraph: BundleGraph<PackagedBundle>,
  +buildTime: number,
  +changedAssets: Map<string, Asset>,
  +requestBundle: (bundle: NamedBundle) => Promise<BuildSuccessEvent>,
|}
Referenced by:
BuildEvent, ReporterEvent

BuildFailureEvent parcel/packages/core/types/index.js:1880

The build failed.

type BuildFailureEvent = {|
  +type: 'buildFailure',
  +diagnostics: Array<Diagnostic>,
|}
Referenced by:
BuildEvent, ReporterEvent

ValidationEvent parcel/packages/core/types/index.js:1894

A new file is being validated.

type ValidationEvent = {|
  +type: 'validation',
  +filePath: FilePath,
|}
Referenced by:
ReporterEvent

Reporter parcel/packages/core/types/index.js:1915

type Reporter = {|
  report({|
    event: ReporterEvent,
    options: PluginOptions,
    logger: PluginLogger,
  |}): Async<void>,
|}