Plugin API for Parcel bundler - provides base classes for creating Parcel plugins including transformers, resolvers, bundlers, namers, runtimes, packagers, optimizers, compressors, reporters, and validators
67
The Transformer plugin enables custom processing of individual assets during the Parcel build process. Transformers handle parsing source code into ASTs, transforming assets, and generating final output code.
Base class for creating asset transformation plugins.
/**
* Base class for asset transformation plugins
* @template T - Configuration type for this transformer
*/
export declare class Transformer<T> {
constructor(opts: TransformerOpts<T>);
}
/**
* Transformer plugin configuration interface
* @template ConfigType - Type of configuration returned by loadConfig
*/
interface TransformerOpts<ConfigType> {
/** Load configuration for this transformer */
loadConfig?: (args: {
config: Config;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}) => Promise<ConfigType> | ConfigType;
/** Check if an AST from a previous transformer can be reused */
canReuseAST?: (args: {
ast: AST;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}) => boolean;
/** Parse asset contents into an AST */
parse?: (args: {
asset: Asset;
config: ConfigType;
resolve: ResolveFn;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}) => Promise<AST | null> | AST | null;
/** Transform the asset and/or add new assets (required) */
transform(args: {
asset: MutableAsset;
config: ConfigType;
resolve: ResolveFn;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}): Promise<Array<TransformerResult | MutableAsset>>;
/** Process assets after transformation */
postProcess?: (args: {
assets: Array<MutableAsset>;
config: ConfigType;
resolve: ResolveFn;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}) => Promise<Array<TransformerResult>>;
/** Generate code from an AST */
generate?: (args: {
asset: Asset;
ast: AST;
options: PluginOptions;
logger: PluginLogger;
tracer: PluginTracer;
}) => Promise<GenerateResult>;
}Usage Example:
import { Transformer } from "@parcel/plugin";
export default new Transformer({
// Load transformer configuration
loadConfig({config, options, logger}) {
return config.getConfigFrom(/* config file path */);
},
// Check if AST can be reused
canReuseAST({ast}) {
return ast.type === 'expected-ast-type';
},
// Parse source code to AST
parse({asset, config}) {
const sourceCode = asset.getCode();
return parseToAST(sourceCode, config);
},
// Main transformation logic (required)
async transform({asset, config, resolve, logger}) {
const code = asset.getCode();
const transformedCode = await processCode(code, config);
asset.setCode(transformedCode);
asset.setMap(/* source map if needed */);
return [asset];
},
// Generate final code from AST
generate({asset, ast, options}) {
const generatedCode = generateCodeFromAST(ast);
return {
contents: generatedCode,
map: /* source map */
};
}
});/**
* Result from a transformation operation
*/
interface TransformerResult {
type: string;
contents: string;
uniqueKey?: string;
map?: SourceMap;
ast?: AST;
dependencies?: Array<Dependency>;
includedFiles?: Array<FilePath>;
env?: EnvironmentOptions;
meta?: Record<string, any>;
pipeline?: string;
symbols?: Map<Symbol, SymbolResolution>;
sideEffects?: boolean;
}/**
* Asset being processed
*/
interface Asset {
/** Get the asset's content as a string */
getCode(): string;
/** Get the asset's AST if available */
getAST(): Promise<AST | null>;
/** Get the asset's source map */
getMap(): Promise<SourceMap | null>;
/** Get asset metadata */
meta: Record<string, any>;
/** Asset file type */
type: string;
/** Asset file path */
filePath: FilePath;
}
/**
* Mutable asset for transformations
*/
interface MutableAsset extends Asset {
/** Set the asset's content */
setCode(code: string): void;
/** Set the asset's AST */
setAST(ast: AST): void;
/** Set the asset's source map */
setMap(map: SourceMap | null): void;
/** Add a dependency to this asset */
addDependency(dependency: DependencyOptions): Dependency;
/** Add an included file for invalidation */
addIncludedFile(filePath: FilePath): void;
}
/**
* Plugin options provided to all plugins
*/
interface PluginOptions {
/** Project root directory */
projectRoot: FilePath;
/** Input file system */
inputFS: FileSystem;
/** Output file system */
outputFS: FileSystem;
/** Package manager */
packageManager: PackageManager;
/** Build mode */
mode: "development" | "production";
/** Build environment */
env: EnvMap;
/** Hot module replacement options */
hmrOptions?: HMROptions;
/** Source map options */
sourceMaps: boolean;
}
/**
* Plugin logger for outputting messages
*/
interface PluginLogger {
/** Log an error */
error(message: string | Diagnostic): void;
/** Log a warning */
warn(message: string | Diagnostic): void;
/** Log info message */
info(message: string): void;
/** Log verbose message */
verbose(message: string): void;
}
/**
* Plugin tracer for performance monitoring
*/
interface PluginTracer {
/** Whether tracing is enabled */
enabled: boolean;
/** Create a new measurement */
createMeasurement(name: string, phase?: string): TraceMeasurement;
}Install with Tessl CLI
npx tessl i tessl/npm-parcel--plugindocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10