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.
npm install --save-dev @babel/plugin-transform-exponentiation-operatorThe 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");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());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;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;
};
}Converts ** binary expressions to Math.pow() calls:
left ** rightMath.pow(left, right)Converts **= assignment expressions to regular assignments with Math.pow():
target **= valuetarget = Math.pow(target, value)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);The plugin handles several edge cases:
This plugin requires no configuration options. It automatically transforms all exponentiation operators it encounters.
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;
};
}/** 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;
}MIT