CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-parcel--plugin

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

1.06x
Overview
Eval results
Files

transformation.mddocs/

Asset Transformation

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.

Capabilities

Transformer Class

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 */
    };
  }
});

Transformer Results

/**
 * 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;
}

Common Plugin Arguments

/**
 * 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--plugin

docs

bundling.md

compression.md

index.md

naming.md

optimization.md

packaging.md

reporting.md

resolution.md

runtime.md

transformation.md

validation.md

tile.json