Helper function to build binary assignment operator visitors for Babel AST transformations
npx @tessl/cli install tessl/npm-babel--helper-builder-binary-assignment-operator-visitor@7.25.0A Babel helper that provides a factory function for creating AST visitors that transform binary assignment operators (like +=, -=, *=, /=, etc.) into their explicit binary operation equivalents. It handles complex assignment expressions by safely exploding assignable expressions to avoid side effects during transformation.
npm install @babel/helper-builder-binary-assignment-operator-visitorimport builderVisitor from "@babel/helper-builder-binary-assignment-operator-visitor";For CommonJS:
const builderVisitor = require("@babel/helper-builder-binary-assignment-operator-visitor");import * as t from "@babel/types";
import { Visitor } from "@babel/traverse";
import builderVisitor from "@babel/helper-builder-binary-assignment-operator-visitor";
// Create a visitor for transforming += operators
const visitor: Visitor = builderVisitor({
operator: "+",
build(left: t.Expression, right: t.Expression): t.Expression {
return t.binaryExpression("+", left, right);
}
});
// Use in a Babel plugin
export default function myPlugin() {
return {
visitor
};
}The helper handles binary assignment operator transformation through several key components:
x += y) into sequence expressions with proper evaluation orderCreates a Babel visitor that transforms binary assignment operators and binary expressions for a specific operator.
/**
* Creates a Babel visitor for transforming binary assignment operators
* @param opts - Configuration options
* @returns Visitor object with AssignmentExpression and BinaryExpression handlers
*/
export default function (opts: {
/** Function that defines how to build the transformed expression from operands */
build: (
left: t.Expression | t.PrivateName | t.Super,
right: t.Expression,
) => t.Expression;
/** The binary operator to transform (e.g., "+", "-", "*", "/") */
operator: t.BinaryExpression["operator"];
}): Visitor;
interface BuilderOptions {
build: (
left: t.Expression | t.PrivateName | t.Super,
right: t.Expression,
) => t.Expression;
operator: t.BinaryExpression["operator"];
}Parameters:
opts.build: A function that takes the left and right operands and returns the transformed expression. This defines the specific transformation logic for the binary operation.opts.operator: The binary operator string to transform (e.g., "+", "-", "*", "/", "%", "**", etc.)Returns: A Babel Visitor object that can be used in Babel plugins to transform assignment expressions and binary expressions.
Usage Example:
import * as t from "@babel/types";
import builderVisitor from "@babel/helper-builder-binary-assignment-operator-visitor";
// Example: Transform *= operators for exponentiation
const visitor = builderVisitor({
operator: "*",
build(left, right) {
// Custom logic for multiplication
return t.callExpression(
t.memberExpression(t.identifier("Math"), t.identifier("pow")),
[left, right]
);
}
});
// This visitor will transform:
// x *= y → x = Math.pow(x, y)
// a * b → Math.pow(a, b)The returned visitor handles two types of AST nodes:
AssignmentExpression Handling:
+=, -=)BinaryExpression Handling:
build function transformation directly// Core types imported from @babel/types and @babel/traverse
import type { Visitor } from "@babel/traverse";
import type * as t from "@babel/types";
// Binary operators supported
type BinaryOperator = "+" | "-" | "*" | "/" | "%" | "**" | "&" | "|" | ">>" | ">>>" | "<<" | "^" | "==" | "===" | "!=" | "!==" | "<" | "<=" | ">" | ">=" | "in" | "instanceof";
// Expression types that can be used as left-hand side of assignments
type AssignableExpression = t.Expression | t.PrivateName | t.Super;
// Node types handled by the visitor
type AssignmentExpression = t.AssignmentExpression;
type BinaryExpression = t.BinaryExpression;
type MemberExpression = t.MemberExpression;
type Identifier = t.Identifier;The helper includes built-in error handling for edge cases:
@babel/plugin-transform-class-properties// Transform ??= (nullish coalescing assignment)
const nullishVisitor = builderVisitor({
operator: "??",
build(left, right) {
return t.logicalExpression("??", left, right);
}
});
// Transform |= (bitwise OR assignment)
const bitwiseOrVisitor = builderVisitor({
operator: "|",
build(left, right) {
return t.binaryExpression("|", left, right);
}
});The helper automatically handles complex left-hand side expressions:
// Input: obj.prop[computedKey()] += value
// Without safety: obj.prop[computedKey()] = obj.prop[computedKey()] + value
// With safety: (_temp = obj.prop, _temp2 = computedKey(), _temp[_temp2] = _temp[_temp2] + value)This ensures that computedKey() is only called once, preventing potential side effects or performance issues.