or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Babel Plugin Transform Exponentiation Operator

This Babel plugin transforms JavaScript's exponentiation operator (**) and exponentiation assignment operator (**=) to ES5-compatible Math.pow() function calls, enabling modern exponentiation syntax to work in older JavaScript environments.

Package Information

  • Package Name: @babel/plugin-transform-exponentiation-operator
  • Package Type: npm (Babel Plugin)
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-transform-exponentiation-operator

Core Imports

The plugin is imported and used through Babel configuration:

// babel.config.js
{
  "plugins": ["@babel/plugin-transform-exponentiation-operator"]
}

Or with programmatic API:

import plugin from "@babel/plugin-transform-exponentiation-operator";
// or
const plugin = require("@babel/plugin-transform-exponentiation-operator");

Basic Usage

This plugin automatically transforms exponentiation syntax during Babel compilation:

Input (ES2016+ syntax):

// Binary exponentiation
const result = 2 ** 3;

// Assignment exponentiation
let base = 2;
base **= 3;

// Complex expressions
const computed = obj.prop ** (x + y);
obj.member **= getValue();

Output (ES5-compatible):

// Binary exponentiation
const result = Math.pow(2, 3);

// Assignment exponentiation
let base = 2;
base = Math.pow(base, 3);

// Complex expressions (with memoization for safety)
const computed = Math.pow(obj.prop, x + y);
obj.member = Math.pow(obj.member, getValue());

Capabilities

Plugin Factory Function

The main export is a factory function that creates a Babel plugin instance.

/**
 * Creates a Babel plugin that transforms exponentiation operators
 * @param api - Babel API object providing types, template, and other utilities
 * @returns Babel plugin configuration object
 */
declare const plugin: (
  api: PluginAPI,
  options?: any,
  dirname?: string
) => PluginObject;

export default plugin;

Plugin Configuration Object

The plugin factory returns a standard Babel plugin configuration object:

interface PluginObject {
  /** Plugin identifier */
  name: "transform-exponentiation-operator";
  /** AST visitor configuration */
  visitor: {
    /** Transforms exponentiation assignment operators (**=) */
    AssignmentExpression(path: NodePath<AssignmentExpression>): void;
    /** Transforms binary exponentiation operators (**) */
    BinaryExpression(path: NodePath<BinaryExpression>): void;
  };
}

Transformation Behaviors

Binary Exponentiation Transform

Converts ** binary expressions to Math.pow() calls:

  • Input Pattern: left ** right
  • Output Pattern: Math.pow(left, right)
  • Handles: Any valid expressions as operands

Assignment Exponentiation Transform

Converts **= assignment expressions to regular assignments with Math.pow():

  • Input Pattern: target **= value
  • Output Pattern: target = Math.pow(target, value)
  • Safety Features: Automatic memoization for complex left-hand expressions to prevent side effects

Complex Expression Handling

For complex member expressions, the plugin implements sophisticated memoization:

// Input: obj[computedKey()] **= value
// Output: (safe memoization prevents duplicate side effects)
var _obj = obj, _key = computedKey();
_obj[_key] = Math.pow(_obj[_key], value);

Edge Case Handling

The plugin handles several edge cases:

  • Function Parameters: When memoization cannot be performed (inside function parameters), wraps in IIFE
  • Member Access: Safely handles both dot notation and computed property access
  • Scope Analysis: Uses Babel's scope analysis to determine when memoization is necessary

Configuration

This plugin requires no configuration options. It automatically transforms all exponentiation operators it encounters.

Dependencies

The plugin depends on:

interface PluginDependencies {
  /** Provides the declare() utility for plugin creation */
  "@babel/helper-plugin-utils": {
    declare: <State = any, Option = any>(
      builder: (
        api: PluginAPI, 
        options: Option, 
        dirname: string
      ) => PluginObject<State & PluginPass>
    ) => (api: PluginAPI, options: Option, dirname: string) => PluginObject<State & PluginPass>;
  };
  /** Provides AST types and utilities (peer dependency) */
  "@babel/core": {
    types: BabelTypes;
    Scope: typeof Scope;
    PluginAPI: PluginAPI;
    PluginPass: PluginPass;
  };
}

Types

/** Babel plugin API interface */
interface PluginAPI {
  /** Babel version */
  version: string;
  /** AST node types and utilities */
  types: BabelTypes;
  /** Template system for creating AST nodes */
  template: Template;
  /** Assert minimum Babel version */
  assertVersion(version: number): void;
}

/** Plugin state passed through transformations */
interface PluginPass {
  [key: string]: any;
}

/** Node path wrapper for AST traversal */
interface NodePath<T = any> {
  node: T;
  scope: Scope;
  replaceWith(node: any): void;
}

/** Assignment expression AST node */
interface AssignmentExpression {
  type: "AssignmentExpression";
  operator: string;
  left: Expression | MemberExpression;
  right: Expression;
}

/** Binary expression AST node */
interface BinaryExpression {
  type: "BinaryExpression";
  operator: string;
  left: Expression;
  right: Expression;
}

/** Member expression AST node */
interface MemberExpression {
  type: "MemberExpression";
  object: Expression;
  property: Expression;
  computed: boolean;
}

/** Base expression AST node */
interface Expression {
  type: string;
}

/** Identifier AST node */
interface Identifier extends Expression {
  type: "Identifier";
  name: string;
}

/** Call expression AST node */
interface CallExpression extends Expression {
  type: "CallExpression";
  callee: Expression;
  arguments: Expression[];
}

/** Template system for creating AST nodes */
interface Template {
  expression: {
    ast: (strings: TemplateStringsArray, ...expressions: any[]) => Expression;
  };
}

/** Babel AST types namespace */
interface BabelTypes {
  isAssignmentExpression(node: any): node is AssignmentExpression;
  isBinaryExpression(node: any): node is BinaryExpression;
  isMemberExpression(node: any): node is MemberExpression;
  callExpression(callee: Expression, arguments: Expression[]): CallExpression;
  memberExpression(object: Expression, property: Expression, computed?: boolean): MemberExpression;
  assignmentExpression(operator: string, left: Expression, right: Expression): AssignmentExpression;
  identifier(name: string): Identifier;
  cloneNode<T>(node: T): T;
}

/** Scope analysis utilities */
interface Scope {
  isStatic(node: Expression): boolean;
  generateUidIdentifierBasedOnNode(node: Expression): Identifier;
  push(opts: { id: Identifier }): void;
  path: NodePath;
}

Engine Requirements

  • Node.js: >=6.9.0
  • Babel: ^7.0.0-0 (peer dependency)

License

MIT