or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-transform-destructuring

Compile ES2015 destructuring to ES5

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/plugin-transform-destructuring@7.28.x

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-transform-destructuring@7.28.0

index.mddocs/

@babel/plugin-transform-destructuring

@babel/plugin-transform-destructuring is a Babel plugin that compiles ES2015 (ES6) destructuring syntax to ES5-compatible code. It transforms array destructuring, object destructuring, destructuring in function parameters, catch clauses, and for-in/for-of loops. The plugin handles complex patterns including nested destructuring, default values, and rest patterns while preserving the semantic behavior of destructuring operations.

Package Information

  • Package Name: @babel/plugin-transform-destructuring
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-transform-destructuring

Core Imports

import transformDestructuring from "@babel/plugin-transform-destructuring";
import { 
  Options,
  buildObjectExcludingKeys,
  unshiftForXStatementBody
} from "@babel/plugin-transform-destructuring";

For CommonJS:

const transformDestructuring = require("@babel/plugin-transform-destructuring");
const { buildObjectExcludingKeys, unshiftForXStatementBody } = require("@babel/plugin-transform-destructuring");

Basic Usage

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-transform-destructuring", {
      allowArrayLike: false,
      loose: false,
      useBuiltIns: false
    }]
  ]
};
// Input code (ES2015+ destructuring)
const { name, age } = user;
const [first, second, ...rest] = items;
function greet({ name = "World" }) {
  console.log(`Hello, ${name}!`);
}

// Output after transformation (ES5 compatible)
const name = user.name, age = user.age;
const first = items[0], second = items[1], rest = items.slice(2);
function greet(_ref) {
  const name = _ref.name === void 0 ? "World" : _ref.name;
  console.log("Hello, " + name + "!");
}

Architecture

The plugin is built around several key components:

  • Babel Plugin Interface: Standard Babel plugin architecture using declare() from @babel/helper-plugin-utils
  • Visitor Pattern: AST visitors for different destructuring contexts (variables, assignments, loops, etc.)
  • DestructuringTransformer: Core transformation engine that converts destructuring patterns to sequential assignments
  • Utility Functions: Helper functions for handling object rest patterns, array conversions, and variable declarations
  • Configuration Options: Plugin options for controlling transformation behavior and assumptions

Capabilities

Plugin Configuration

Main plugin export that integrates with Babel's transformation pipeline.

/**
 * Main Babel plugin export for destructuring transformation
 * @param api - Babel API object with version checking and assumptions
 * @param options - Plugin configuration options
 * @returns Babel plugin object with visitor methods
 */
declare function transformDestructuring(api: any, options: Options): {
  name: string;
  visitor: PluginVisitor;
};

export default transformDestructuring;

interface Options {
  /** Enable transformation of array-like objects (e.g., arguments, NodeList) */
  allowArrayLike?: boolean;
  /** Enable loose mode transformations for better performance */
  loose?: boolean;
  /** Use built-in methods when available instead of helper functions */
  useBuiltIns?: boolean;
}

interface PluginVisitor {
  ExportNamedDeclaration(path: NodePath): void;
  ForXStatement(path: NodePath<ForXStatement>): void;
  CatchClause(path: NodePath): void;
  AssignmentExpression(path: NodePath, state: any): void;
  VariableDeclaration(path: NodePath, state: any): void;
}

DestructuringTransformer Class

Core transformation engine for converting destructuring patterns to sequential assignments.

/**
 * Main class for transforming destructuring patterns into sequential assignments
 */
export class DestructuringTransformer {
  arrayRefSet: Set<string>;
  
  constructor(opts: DestructuringTransformerOption);
  
  /**
   * Initialize destructuring transformation for a given pattern and reference
   * @param pattern - The destructuring pattern (ArrayPattern, ObjectPattern, etc.)
   * @param ref - The expression being destructured
   */
  init(pattern: LVal, ref: Expression): void;
  
  /**
   * Add a destructuring assignment to the transformation
   * @param id - The target identifier or pattern
   * @param init - The initialization expression
   */
  push(id: LVal | PatternLike, init: Expression | null): void;
  
  /**
   * Convert an expression to an array for array destructuring
   * @param node - The expression to convert
   * @param count - Optional specific number of elements needed
   * @returns Expression that evaluates to an array
   */
  toArray(node: Expression, count?: false | number): Expression;
  
  /**
   * Build a variable assignment statement
   * @param id - The assignment target
   * @param init - The initialization expression
   * @returns Variable assignment node
   */
  buildVariableAssignment(
    id: AssignmentExpression["left"], 
    init: Expression
  ): ExpressionStatement | VariableDeclaration;
  
  /**
   * Build a variable declaration statement
   * @param id - The identifier being declared
   * @param init - The initialization expression
   * @returns Variable declaration node
   */
  buildVariableDeclaration(id: Identifier, init: Expression): VariableDeclaration;
  
  /**
   * Returns the appropriate extends helper (Object.assign or helper function)
   * @returns Member expression or helper call
   */
  getExtendsHelper(): MemberExpression | CallExpression;
}

interface DestructuringTransformerOption {
  /** Block hoisting priority for generated nodes */
  blockHoist?: number;
  /** Assignment operator for generated assignments */
  operator?: AssignmentExpression["operator"];
  /** Array to collect generated transformation nodes */
  nodes?: DestructuringTransformerNode[];
  /** Variable declaration kind (var, let, const) */
  kind?: VariableDeclarationKindAllowsPattern;
  /** Babel scope object for identifier generation and binding management (required) */
  scope: Scope;
  /** Whether array-like objects should be treated as iterable (required) */
  arrayLikeIsIterable: boolean;
  /** Whether iterables should be assumed to be arrays for optimization (required) */
  iterableIsArray: boolean;
  /** Whether object rest should exclude symbol properties (required) */
  objectRestNoSymbols: boolean;
  /** Whether to use built-in methods instead of helper functions (required) */
  useBuiltIns: boolean;
  /** Function to register Babel helper functions (required) */
  addHelper: File["addHelper"];
}

Utility Functions

Helper functions for specific destructuring transformations.

/**
 * Build an object excluding specified keys (used for object rest patterns)
 * @param excludedKeys - Array of properties to exclude
 * @param objRef - Reference to the source object
 * @param scope - Babel scope object
 * @param addHelper - Helper function registration
 * @param objectRestNoSymbols - Whether to exclude symbol properties
 * @param useBuiltIns - Whether to use built-in Object.assign
 * @returns Call expression creating the filtered object
 */
export function buildObjectExcludingKeys<T extends ExcludingKey>(
  excludedKeys: T[],
  objRef: Expression,
  scope: Scope,
  addHelper: File["addHelper"],
  objectRestNoSymbols: boolean,
  useBuiltIns: boolean
): CallExpression;

/**
 * Convert a variable declaration containing destructuring patterns
 * @param path - NodePath for the variable declaration
 * @param addHelper - Helper function registration
 * @param arrayLikeIsIterable - Array-like transformation assumption
 * @param iterableIsArray - Iterable transformation assumption
 * @param objectRestNoSymbols - Object rest symbol handling assumption
 * @param useBuiltIns - Whether to use built-in methods
 */
export function convertVariableDeclaration(
  path: NodePath<VariableDeclaration>,
  addHelper: File["addHelper"],
  arrayLikeIsIterable: boolean,
  iterableIsArray: boolean,
  objectRestNoSymbols: boolean,
  useBuiltIns: boolean
): void;

/**
 * Convert an assignment expression containing destructuring patterns
 * @param path - NodePath for the assignment expression
 * @param addHelper - Helper function registration
 * @param arrayLikeIsIterable - Array-like transformation assumption
 * @param iterableIsArray - Iterable transformation assumption
 * @param objectRestNoSymbols - Object rest symbol handling assumption
 * @param useBuiltIns - Whether to use built-in methods
 */
export function convertAssignmentExpression(
  path: NodePath<AssignmentExpression & { left: Pattern }>,
  addHelper: File["addHelper"],
  arrayLikeIsIterable: boolean,
  iterableIsArray: boolean,
  objectRestNoSymbols: boolean,
  useBuiltIns: boolean
): void;

/**
 * Insert statements at the beginning of a for-X statement body
 * @param statementPath - NodePath for the ForXStatement
 * @param newStatements - Array of statements to insert
 */
export function unshiftForXStatementBody(
  statementPath: NodePath<ForXStatement>,
  newStatements: Statement[]
): void;

Types

/** Union type for nodes generated by the destructuring transformer */
export type DestructuringTransformerNode = 
  | VariableDeclaration 
  | ExpressionStatement 
  | ReturnStatement;

/** Variable declaration kinds that support destructuring patterns */
export type VariableDeclarationKindAllowsPattern = Exclude<
  VariableDeclaration["kind"], 
  "using" | "await using"
>;

/** Interface for objects with excludable keys used in object rest patterns */
interface ExcludingKey {
  key: Expression | PrivateName;
  computed: boolean;
}

/** Babel AST types used by the plugin */
interface LVal {} // From @babel/types
interface Pattern {} // From @babel/types  
interface PatternLike {} // From @babel/types
interface Expression {} // From @babel/types
interface Statement {} // From @babel/types
interface Identifier {} // From @babel/types
interface VariableDeclaration {} // From @babel/types
interface AssignmentExpression {} // From @babel/types
interface CallExpression {} // From @babel/types
interface MemberExpression {} // From @babel/types
interface ExpressionStatement {} // From @babel/types
interface ReturnStatement {} // From @babel/types
interface PrivateName {} // From @babel/types
interface ForXStatement {} // From @babel/types
interface NodePath<T = any> {} // From @babel/traverse
interface Scope {} // From @babel/traverse
interface File {} // From @babel/core

Plugin Behavior

Transformation Contexts

The plugin handles destructuring in the following contexts:

  1. Variable Declarations: const { x, y } = obj;const x = obj.x, y = obj.y;
  2. Assignment Expressions: ({ x, y } = obj);x = obj.x, y = obj.y;
  3. Function Parameters: function f({ x }) {}function f(_ref) { const x = _ref.x; }
  4. For-X Statements: for (const { x } of arr) {}for (const _ref of arr) { const x = _ref.x; }
  5. Catch Clauses: catch ({ message }) {}catch (_ref) { const message = _ref.message; }
  6. Export Declarations: export const { x } = obj; → Split into separate export and declaration

Pattern Types

Supports all ES2015+ destructuring patterns:

  • Object Patterns: { prop, nested: { deep } }
  • Array Patterns: [first, second, ...rest]
  • Assignment Patterns: { prop = defaultValue }
  • Rest Patterns: { ...rest } and [...rest]
  • Nested Patterns: { obj: { nested } } and [[nested]]

Configuration Options

  • allowArrayLike: When enabled, treats array-like objects (NodeList, arguments) as iterable
  • loose: Enables performance optimizations with slightly different semantics
  • useBuiltIns: Uses native Object.assign instead of helper functions when available

Error Handling

The plugin handles various edge cases:

  • Empty destructuring patterns are transformed to runtime checks
  • Missing properties default to undefined
  • Array holes are properly handled
  • Invalid destructuring targets throw runtime errors