CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-parcel--transformer-babel

A Parcel transformer plugin that transforms JavaScript code using Babel with automatic configuration discovery and intelligent defaults for modern JavaScript, TypeScript, JSX, and Flow.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

babel-processing.mddocs/

Babel Processing Engine

Core Babel 7 processing functionality that performs the actual code transformation with comprehensive AST management, source mapping, and performance optimization.

Capabilities

Babel 7 Transformation

Main function that performs Babel transformation using @babel/core with full configuration and AST management.

/**
 * Performs Babel 7 transformation on JavaScript/TypeScript/JSX assets
 * Handles AST processing, plugin configuration, and performance tracing
 * Modifies the asset's AST in place rather than returning it
 * @param opts - Transformation options
 * @returns Promise that resolves when transformation is complete (returns undefined)
 */
async function babel7(opts: Babel7TransformOptions): Promise<void>;

interface Babel7TransformOptions {
  asset: MutableAsset;              // The asset being transformed
  options: PluginOptions;           // Parcel plugin options
  logger: PluginLogger;             // Logger for warnings and errors
  babelOptions: any;                // Babel configuration object
  additionalPlugins?: Array<any>;   // Extra plugins from asset metadata
  tracer: PluginTracer;            // Performance tracing utility
}

Babel Configuration Assembly

The function assembles a comprehensive Babel configuration from multiple sources:

// Configuration structure passed to @babel/core
interface BabelTransformConfig {
  plugins: Array<any>;              // Combined plugins array
  presets: Array<any>;              // Babel presets
  code: false;                      // Disable code generation
  ast: true;                        // Enable AST output
  filename: string;                 // Source file path
  babelrc: false;                   // Disable .babelrc loading
  configFile: false;                // Disable babel.config.* loading
  parserOpts: ParserOptions;        // Parser configuration
  caller: CallerOptions;            // Caller identification
  wrapPluginVisitorMethod?: Function; // Performance tracing wrapper
}

interface ParserOptions {
  sourceFilename: string;           // Relative source filename
  allowReturnOutsideFunction: true; // Allow top-level returns
  strictMode: false;                // Disable strict mode enforcement
  sourceType: 'module';             // Always treat as ES module
  plugins: Array<string>;           // Syntax plugins to enable
}

interface CallerOptions {
  name: 'parcel';                   // Identifies Parcel as caller
  version: string;                  // Transformer version
  targets: string;                  // JSON stringified targets
  outputFormat: string;             // Output format (esm, cjs, etc.)
}

AST Processing Modes

The function handles two different processing modes based on asset state:

// Mode 1: Transform from existing AST
const result = await babelCore.transformFromAstAsync(
  ast.program,                      // Existing AST program
  asset.isASTDirty() ? undefined : await asset.getCode(), // Code if AST is clean
  config                           // Babel configuration
);

// Mode 2: Transform from source code
const result = await babelCore.transformAsync(
  await asset.getCode(),            // Source code string
  config                           // Babel configuration
);

Source Map Remapping

When transforming from source code, the function remaps AST locations using existing source maps:

/**
 * Remaps AST node locations using source map for accurate debugging
 * Applied when transforming from source code rather than existing AST
 */
if (res.ast && !ast) {
  let map = await asset.getMap();
  if (map) {
    remapAstLocations(babelCore.types, res.ast, map);
  }
}

External Dependencies Handling

Processes external dependencies declared by Babel plugins:

// External dependency processing
if (res.externalDependencies) {
  for (let filePath of res.externalDependencies) {
    if (!path.isAbsolute(filePath)) {
      // Warn about non-absolute dependencies
      logger.warn({
        message: `Ignoring non-absolute Babel external dependency: ${filePath}`,
        hints: ['Please report this to the corresponding Babel plugin and/or to Parcel.']
      });
    } else {
      // Track file changes/creation for cache invalidation
      if (await options.inputFS.exists(filePath)) {
        asset.invalidateOnFileChange(filePath);
      } else {
        asset.invalidateOnFileCreate({ filePath });
      }
    }
  }
}

Performance Tracing

Integrates with Parcel's performance tracing system to monitor plugin execution:

/**
 * Wraps Babel plugin visitor methods for performance measurement
 * Only active when tracer.enabled is true
 */
config.wrapPluginVisitorMethod = (
  key: string,        // Plugin identifier
  nodeType: string,   // AST node type being visited
  fn: Function        // Original visitor function
) => {
  return function() {
    const measurement = tracer.createMeasurement(
      key.startsWith(options.projectRoot) 
        ? path.relative(options.projectRoot, key)
        : key,
      nodeType,
      path.relative(options.projectRoot, asset.filePath)
    );
    
    fn.apply(this, arguments);
    measurement && measurement.end();
  };
};

Syntax Plugin Configuration

Automatically configures essential syntax plugins for modern JavaScript:

const defaultSyntaxPlugins = [
  'classProperties',        // class field declarations
  'classPrivateProperties', // private class fields
  'classPrivateMethods',    // private class methods
  'exportDefaultFrom'       // export { default } from 'module'
  // 'topLevelAwait' - commented out, conditionally enabled
];

// Combined with config-specific syntax plugins
const allSyntaxPlugins = [
  ...(babelOptions.config.parserOpts?.plugins ?? []),
  ...(babelOptions.syntaxPlugins ?? []),
  ...defaultSyntaxPlugins
];

AST Output Handling

Sets the transformed AST on the asset with proper metadata:

/**
 * Sets the transformed AST on the asset
 * Includes version information for AST reuse optimization
 */
if (res.ast) {
  asset.setAST({
    type: 'babel',      // AST type identifier
    version: '7.0.0',   // Babel version for compatibility
    program: res.ast    // Transformed AST program
  });
}

Usage Example:

// Internal usage during transformation
const transformedAST = await babel7({
  asset: jsAsset,
  options: pluginOptions,
  logger: parcelLogger,
  babelOptions: {
    config: {
      presets: [['@babel/preset-env', { targets: { node: '16' } }]],
      plugins: ['@babel/plugin-proposal-class-properties']
    },
    targets: { node: '16.0.0' },
    syntaxPlugins: ['jsx']
  },
  additionalPlugins: [],
  tracer: performanceTracer
});

// AST is set on the asset and returned for further processing
console.log('Transformation complete:', transformedAST !== null);

Dependency Management

The function handles automatic installation and resolution of Babel dependencies:

  • @babel/core: Required with version ^7.12.0
  • @babel/generator: Loaded dynamically for code generation
  • Plugin Dependencies: Resolved and cached automatically
  • Version Validation: Ensures compatible versions across the pipeline

Error Handling

  • Transformation Errors: Full context with source location
  • Dependency Errors: Clear messages for missing or incompatible packages
  • Configuration Errors: Detailed information about invalid settings
  • AST Errors: Validation of AST structure and compatibility

Performance Optimizations

  • AST Reuse: Avoids re-parsing when compatible AST exists
  • Lazy Loading: Dependencies loaded only when needed
  • Source Map Optimization: Efficient location remapping
  • Plugin Tracing: Optional performance monitoring
  • Cache Integration: Leverages Parcel's caching system

Install with Tessl CLI

npx tessl i tessl/npm-parcel--transformer-babel

docs

babel-processing.md

configuration.md

error-handling.md

index.md

transformer.md

utilities.md

tile.json