or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-transform-object-rest-spread

Babel plugin that transforms ES6+ object rest and spread syntax to ES5-compatible code

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

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-transform-object-rest-spread@7.28.0

index.mddocs/

@babel/plugin-transform-object-rest-spread

The @babel/plugin-transform-object-rest-spread plugin transforms ECMAScript object rest and spread syntax into ES5-compatible code. It enables developers to use modern object destructuring and spread operations while maintaining compatibility with older JavaScript environments.

Package Information

  • Package Name: @babel/plugin-transform-object-rest-spread
  • Package Type: npm (Babel plugin)
  • Language: TypeScript (compiled to JavaScript)
  • Installation: npm install --save-dev @babel/plugin-transform-object-rest-spread

Core Imports

This is a Babel plugin, so it's typically configured in your Babel configuration:

// babel.config.js
module.exports = {
  plugins: [
    "@babel/plugin-transform-object-rest-spread"
  ]
};

With options:

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-transform-object-rest-spread", {
      useBuiltIns: true,
      loose: false
    }]
  ]
};

For programmatic usage with Babel's API:

import transformObjectRestSpread from "@babel/plugin-transform-object-rest-spread";
import { transform } from "@babel/core";

const result = transform(code, {
  plugins: [transformObjectRestSpread]
});

Basic Usage

Once configured, the plugin automatically transforms object rest and spread syntax in your code:

// Input: Object rest in destructuring
const { a, b, ...rest } = obj;

// Input: Object spread in object literals
const newObj = { ...obj1, prop: 'value', ...obj2 };

// Input: Object rest in function parameters
function fn({ param1, ...restParams }) {
  // Function body
}

// All of the above are transformed to ES5-compatible code

Architecture

The plugin operates as a Babel transformation plugin that:

  • AST Visitor: Traverses the Abstract Syntax Tree to find object rest/spread patterns
  • Transformation Engine: Converts modern syntax to ES5-compatible helper function calls
  • Helper System: Uses Babel helpers like objectWithoutProperties and objectSpread2
  • Configuration System: Respects Babel assumptions and plugin options for optimization
  • Compatibility Layer: Supports both ES modules and CommonJS output formats

Capabilities

Plugin Configuration

The main plugin export function that integrates with Babel's transformation pipeline.

import { declare } from "@babel/helper-plugin-utils";
import type { PluginPass } from "@babel/core";

/**
 * Main plugin export - default export from the package
 * This is a Babel plugin factory function created using declare()
 * @param api - Babel API object
 * @param opts - Plugin options
 * @returns Babel plugin configuration object
 */
export default declare((api: any, opts: Options) => {
  api.assertVersion(7);
  // Plugin implementation returns PluginVisitor object
});

interface Options {
  /** Whether to use built-in Object.assign instead of helper functions (default: auto-detected based on targets) */
  useBuiltIns?: boolean;
  /** Enable loose mode for more compact but less spec-compliant output (default: false) */
  loose?: boolean;
}

/**
 * Plugin visitor interface - returned by the main plugin function
 */
interface PluginVisitor {
  name: "transform-object-rest-spread";
  manipulateOptions?: (opts: any, parser: any) => void;
  visitor: {
    Function(path: NodePath<t.Function>): void;
    VariableDeclarator(path: NodePath<t.VariableDeclarator>, file: PluginPass): void;
    ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>): void;
    CatchClause(path: NodePath<t.CatchClause>): void;
    AssignmentExpression(path: NodePath<t.AssignmentExpression>, file: PluginPass): void;
    ForXStatement(path: NodePath<t.ForXStatement>): void;
    ArrayPattern(path: NodePath<t.ArrayPattern>): void;
    ObjectExpression(path: NodePath<t.ObjectExpression>, file: PluginPass): void;
  };
}

Transformation Patterns

The plugin handles several distinct patterns of object rest and spread syntax:

Object Rest in Variable Declarations

Transforms object rest patterns in variable declarations:

// Input
const { a, b, ...rest } = obj;

// Output (conceptual - actual output uses helper functions)
const a = obj.a;
const b = obj.b;
const rest = objectWithoutProperties(obj, ["a", "b"]);

Object Spread in Object Expressions

Transforms object spread syntax in object literals:

// Input
const result = { ...obj1, prop: 'value', ...obj2 };

// Output (conceptual - actual output uses helper functions)
const result = objectSpread2({}, obj1, { prop: 'value' }, obj2);

Object Rest in Function Parameters

Transforms object rest patterns in function parameter lists:

// Input
function fn({ param1, ...restParams }) {
  // Function body
}

// Output (simplified - actual transformation is more complex)
function fn(_ref) {
  const param1 = _ref.param1;
  const restParams = objectWithoutProperties(_ref, ["param1"]);
  // Function body
}

Object Rest in Assignment Expressions

Transforms object rest patterns in assignment contexts:

// Input
({ a, ...rest } = obj);

// Output (conceptual)
var _obj = obj;
a = _obj.a;
rest = objectWithoutProperties(_obj, ["a"]);

Object Rest in Control Flow

Transforms object rest patterns in for-in/for-of loops and catch clauses:

// Input: for-of with object rest
for (const { key, ...rest } of items) {
  // Loop body
}

// Input: catch clause with object rest
try {
  // Code
} catch ({ message, ...errorDetails }) {
  // Error handling
}

Plugin Options

useBuiltIns Option

Controls whether to use native Object.assign or Babel helper functions:

interface UseBuiltInsOption {
  /** 
   * When true, uses native Object.assign for object spread operations
   * When false, uses Babel's _extends helper function
   * When undefined, auto-detects based on compilation targets
   */
  useBuiltIns?: boolean;
}

Usage Example:

// With useBuiltIns: true
const result = Object.assign({}, obj1, obj2);

// With useBuiltIns: false
const result = _extends({}, obj1, obj2);

loose Option

Controls whether to use loose mode for more compact output:

interface LooseOption {
  /**
   * When true, generates more compact but less spec-compliant code
   * Affects symbol handling and property enumeration behavior
   * Default: false
   */
  loose?: boolean;
}

Usage Example:

// With loose: false (strict mode)
// Generates more comprehensive checks for symbols and getters

// With loose: true  
// Generates simpler, faster code with fewer edge case checks

Helper Functions

While not directly exposed as public API, the plugin uses several internal helper functions that are worth understanding:

shouldStoreRHSInTemporaryVariable

Utility function to determine if the right-hand side of an assignment should be stored in a temporary variable to avoid duplication:

import type { types as t } from "@babel/core";

/**
 * Utility function exported from shouldStoreRHSInTemporaryVariable.ts
 * Determines if RHS should be stored in temporary variable to avoid duplication
 * @param node - AST node representing the left-hand side pattern  
 * @returns Whether to store RHS in temporary variable
 */
export default function shouldStoreRHSInTemporaryVariable(
  node: t.LVal | t.PatternLike
): boolean;

Compatibility Data

Browser compatibility information for Object.assign feature detection:

/**
 * Browser compatibility data exported from compat-data.ts
 * Contains minimum version information for Object.assign support
 */
export default {
  "Object.assign": {
    chrome: "49",
    opera: "36",
    edge: "13",
    firefox: "36",
    safari: "10",
    node: "6",
    deno: "1",
    ios: "10",
    samsung: "5",
    opera_mobile: "36",
    electron: "0.37"
  }
};

interface CompatData {
  "Object.assign": {
    [browser: string]: string;
  };
}

Internal Helper Functions

The plugin uses several internal functions that transform AST nodes. While not part of the public API, understanding these functions helps explain the plugin's behavior:

/**
 * Internal utility functions used by the plugin (not exported)
 */

/**
 * Checks if a node contains object rest elements
 * @param path - AST node path to check
 * @returns true if the node contains object rest patterns
 */
function hasObjectRestElement(
  path: NodePath<t.LVal | t.PatternLike | t.TSParameterProperty>
): boolean;

/**
 * Checks if an object expression contains spread elements
 * @param node - Object expression node to check
 * @returns true if the object contains spread syntax
 */
function hasSpread(node: t.ObjectExpression): boolean;

/**
 * Extracts all keys from an object pattern for rest transformation
 * @param node - Object pattern to extract keys from
 * @returns Object containing keys array and metadata
 */
function extractNormalizedKeys(node: t.ObjectPattern): {
  keys: t.Expression[];
  allPrimitives: boolean;
  hasTemplateLiteral: boolean;
};

/**
 * Creates the object rest transformation call expression
 * @param path - Object pattern path
 * @param file - Plugin pass instance
 * @param objRef - Reference to the source object
 * @returns Tuple containing declarators, argument, and call expression
 */
function createObjectRest(
  path: NodePath<t.ObjectPattern>,
  file: PluginPass,
  objRef: t.Identifier | t.MemberExpression
): [t.VariableDeclarator[], t.AssignmentExpression["left"], t.CallExpression];

/**
 * Gets the appropriate helper function for object spread operations
 * @param file - Plugin pass instance
 * @returns Helper function reference (Object.assign or _extends)
 */
function getExtendsHelper(file: PluginPass): t.MemberExpression | t.Identifier;

Required Type Imports

The plugin requires several Babel types and utilities:

import { declare } from "@babel/helper-plugin-utils";
import { types as t } from "@babel/core";
import type { PluginPass, NodePath, Scope } from "@babel/core";
import { convertFunctionParams } from "@babel/plugin-transform-parameters";
import { isRequired } from "@babel/helper-compilation-targets";
import { unshiftForXStatementBody } from "@babel/plugin-transform-destructuring";

Babel Integration

The plugin integrates with Babel's ecosystem through several mechanisms:

Babel Assumptions

The plugin respects the following Babel assumptions for optimization:

  • ignoreFunctionLength: Whether to ignore function.length when transforming parameters
  • objectRestNoSymbols: Whether object rest excludes symbol properties
  • pureGetters: Whether getters are side-effect free (enables optimizations)
  • setSpreadProperties: Whether to use simple property assignment for spread

Version Compatibility

The plugin requires Babel 7.0.0 or higher and handles version-specific differences. The plugin automatically adapts its behavior based on the Babel version being used, with enhanced features available in Babel 8+.

Dependencies

The plugin has the following dependencies:

/**
 * Package dependencies as specified in package.json
 */
interface Dependencies {
  "@babel/helper-compilation-targets": string;
  "@babel/helper-plugin-utils": string;
  "@babel/plugin-transform-destructuring": string;
  "@babel/plugin-transform-parameters": string;
  "@babel/traverse": string;
}

/**
 * Peer dependencies - must be installed by consuming applications
 */
interface PeerDependencies {
  "@babel/core": "^7.0.0-0";
}

/**
 * Engine requirements
 */
interface Engines {
  node: ">=6.9.0";
}

Error Handling

The plugin validates configuration options and throws descriptive errors for invalid settings:

// Invalid loose option
{
  plugins: [
    ["@babel/plugin-transform-object-rest-spread", { loose: "invalid" }]
  ]
}
// Throws: ".loose must be a boolean, or undefined"

Performance Considerations

  • Loose Mode: Enables faster but less compliant transformations
  • useBuiltIns: Reduces bundle size when targeting modern environments
  • Assumption Flags: Allow fine-tuned optimizations based on code patterns
  • Helper Hoisting: Reuses helper functions to minimize code duplication