or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-transform-computed-properties

Compile ES2015 computed properties to ES5

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/plugin-transform-computed-properties@7.27.x

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-transform-computed-properties@7.27.0

index.mddocs/

@babel/plugin-transform-computed-properties

Babel plugin that transforms ES2015 computed properties in object literals to ES5-compatible code. It provides two transformation modes: loose mode for simpler assignment-based transformations and spec-compliant mode using Object.defineProperty for proper property descriptor handling.

Package Information

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

Core Imports

import transformComputedProperties from "@babel/plugin-transform-computed-properties";

For CommonJS:

const transformComputedProperties = require("@babel/plugin-transform-computed-properties");

With type definitions:

import transformComputedProperties, { type Options } from "@babel/plugin-transform-computed-properties";

Internal dependencies (used by the plugin):

import { declare } from "@babel/helper-plugin-utils";
import template from "@babel/template";
import { types as t } from "@babel/core";

Basic Usage

Babel Configuration (babel.config.js)

module.exports = {
  plugins: [
    "@babel/plugin-transform-computed-properties"  // Default (spec mode)
  ]
};

With Options

module.exports = {
  plugins: [
    ["@babel/plugin-transform-computed-properties", { loose: true }]
  ]
};

Transformation Examples

Input (ES2015 computed properties):

const key = "dynamicKey";
const obj = {
  [key]: "value",
  [expression()]: "computed",
  [`prefix_${variable}`]: "template"
};

Output (ES5-compatible, spec mode):

var _obj;
var key = "dynamicKey";
var obj = (_obj = {}, Object.defineProperty(_obj, key, {
  value: "value",
  enumerable: true,
  writable: true,
  configurable: true
}), Object.defineProperty(_obj, expression(), {
  value: "computed", 
  enumerable: true,
  writable: true,
  configurable: true
}), Object.defineProperty(_obj, "prefix_" + variable, {
  value: "template",
  enumerable: true,
  writable: true,
  configurable: true
}), _obj);

Output (ES5-compatible, loose mode):

var _obj;
var key = "dynamicKey";
var obj = (_obj = {}, _obj[key] = "value", _obj[expression()] = "computed", _obj["prefix_" + variable] = "template", _obj);

Capabilities

Plugin Factory Function

Main Babel plugin created using the declare helper from @babel/helper-plugin-utils.

/**
 * Default export: Babel plugin created via declare() helper
 * @param api - Babel API object with helper methods and version assertion
 * @param options - Plugin configuration options
 * @returns Babel plugin object with visitor pattern
 */
const transformComputedProperties = declare((api: BabelApi, options: Options) => {
  api.assertVersion(REQUIRED_VERSION(7)); // Ensures Babel 7+ compatibility
  // Plugin implementation
  return BabelPlugin;
});

export default transformComputedProperties;

interface BabelPlugin {
  name: "transform-computed-properties";
  visitor: {
    ObjectExpression: {
      exit(path: NodePath<t.ObjectExpression>, state: PluginPass): void;
    };
  };
}

Configuration Options

Plugin configuration interface for customizing transformation behavior.

interface Options {
  /**
   * Enable loose transformation mode.
   * When true, uses simple assignment instead of Object.defineProperty.
   * Note: This option is overridden by Babel's "setComputedProperties" assumption if present.
   * Priority: api.assumption("setComputedProperties") ?? options.loose
   * @default false
   */
  loose?: boolean;
}

Transformation Modes

Spec Mode (Default)

  • Uses Object.defineProperty() for property creation
  • Maintains proper property descriptors (enumerable, writable, configurable)
  • Handles getter/setter methods correctly
  • Chunks large objects to prevent deeply nested AST structures
  • Full ES5 specification compliance

Loose Mode

  • Uses simple assignment operations (obj[key] = value)
  • Better performance and smaller output
  • Less strict about property descriptors
  • Activated via loose: true option or Babel's setComputedProperties assumption

Method Handling

Getter/Setter Methods

The plugin properly handles computed getter and setter methods:

Input:

const obj = {
  get [computedKey]() { return this._value; },
  set [computedKey](value) { this._value = value; }
};

Output (spec mode):

var obj = (function() {
  var _obj = {};
  return defineAccessor("get", _obj, computedKey, function() { 
    return this._value; 
  }), defineAccessor("set", _obj, computedKey, function(value) { 
    this._value = value; 
  }), _obj;
})();

Regular Methods

Computed regular methods are converted to function expressions:

Input:

const obj = {
  [methodName]() { return "hello"; }
};

Output:

var _obj = {};
Object.defineProperty(_obj, methodName, {
  value: function() { return "hello"; },
  enumerable: true,
  writable: true, 
  configurable: true
});

Helper Dependencies

The plugin generates calls to Babel runtime helpers:

  • defineProperty: Used in spec mode for regular properties via state.addHelper("defineProperty")
  • defineAccessor: Used for getter/setter methods via state.addHelper("defineAccessor")

For compatibility with older Babel versions (@babel/helpers <= 7.20.6), the plugin includes a fallback DefineAccessorHelper created using template.expression.ast.

These helpers are automatically added by Babel's plugin system when needed.

Browser Compatibility

This plugin enables computed property syntax to work in environments that don't support ES2015, including:

  • Internet Explorer 11 and older
  • Legacy mobile browsers
  • Node.js versions prior to v4

Performance Considerations

  • Loose mode: Generates smaller, faster code but less spec-compliant
  • Spec mode: Full compliance but larger output with defineProperty calls
  • Large objects: Automatically chunks properties into groups of 10 (CHUNK_LENGTH_CAP) to prevent deeply nested AST structures
  • Version compatibility: BABEL_8_BREAKING flag provides conditional compilation for different Babel versions
  • Evaluation order: Maintains proper left-to-right evaluation of computed expressions

Types

// Internal types used by the plugin (not part of public API)
type PropertyInfo = {
  scope: Scope;
  objId: t.Identifier;
  body: t.Statement[];
  computedProps: t.ObjectMember[];
  initPropExpression: t.ObjectExpression;
  state: PluginPass;
};

// Babel core types used in the plugin
interface BabelApi {
  assertVersion(version: number | string): void;
  assumption(name: string): boolean | undefined;
}

interface PluginPass {
  addHelper(name: string): t.Identifier;
  availableHelper(name: string): boolean;
  file: BabelFile;
}

interface BabelFile {
  scope: Scope;
  get(key: string): any;
  set(key: string, value: any): void;
}

interface Scope {
  generateUidIdentifier(name: string): t.Identifier;
  generateUidIdentifierBasedOnNode(node: t.Node): t.Identifier;
  push(opts: { id: t.Identifier; init?: t.Expression }): void;
}

interface NodePath<T = t.Node> {
  node: T;
  parent: t.Node;
  scope: Scope;
  replaceWith(replacement: t.Node): void;
  replaceWithMultiple(nodes: t.Node[]): void;
}

// Constants used internally
const CHUNK_LENGTH_CAP = 10; // Prevents deeply nested AST structures