or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel-plugin-transform-es2015-for-of

Babel plugin that compiles ES2015 for...of loops to ES5-compatible code

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/babel-plugin-transform-es2015-for-of@6.23.x

To install, run

npx @tessl/cli install tessl/npm-babel-plugin-transform-es2015-for-of@6.23.0

index.mddocs/

Babel Plugin Transform ES2015 For-Of

A Babel plugin that compiles ES2015 for...of loops to ES5-compatible code. It provides comprehensive transformation support for arrays, iterables, and other objects with two modes: strict spec-compliant mode with full iterator protocol error handling, and loose mode optimized for performance.

Package Information

  • Package Name: babel-plugin-transform-es2015-for-of
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install --save-dev babel-plugin-transform-es2015-for-of

Core Imports

The plugin exports a single default function that creates a Babel plugin configuration:

// Default export from plugin module
export default function ({ messages, template, types: t }) {
  // Returns Babel plugin object with visitor pattern
}

Note: This is a Babel plugin, so it's typically not imported directly in application code. Instead, it's configured through Babel's configuration system.

Basic Usage

Via .babelrc Configuration

{
  "plugins": ["transform-es2015-for-of"]
}

With options:

{
  "plugins": [
    ["transform-es2015-for-of", {
      "loose": true
    }]
  ]
}

Via CLI

babel --plugins transform-es2015-for-of script.js

Via Node API

require("babel-core").transform("code", {
  plugins: ["transform-es2015-for-of"]
});

Capabilities

Plugin Function

The main export is a plugin factory function that creates a Babel plugin configuration.

/**
 * Creates a Babel plugin for transforming ES2015 for...of loops
 * @param {object} param0 - Destructured Babel core objects
 * @param {object} param0.messages - Babel messages for error reporting
 * @param {function} param0.template - Babel template helper for AST generation
 * @param {object} param0.types - Babel types utility object (destructured as t)
 * @returns {object} Babel plugin configuration with visitor pattern
 */
export default function ({ messages, template, types: t }) {
  return {
    visitor: {
      ForOfStatement(path: NodePath<ForOfStatement>, state: PluginPass): void {
        // Transform for...of statements based on configuration
      }
    }
  };
}

Configuration Options

The plugin accepts configuration options through Babel's plugin system:

interface PluginOptions {
  /** Enable loose mode for better performance with arrays (default: false) */
  loose?: boolean;
}

Transformation Modes

The plugin provides three transformation strategies:

1. Array Optimization (Automatic)

For literal arrays, the plugin automatically generates optimized for loops:

Input:

for (let a of [1, 2, 3]) {
  console.log(a);
}

Output:

var _arr = [1, 2, 3];
for (var _i = 0; _i < _arr.length; _i++) {
  var a = _arr[_i];
}

2. Spec Mode (Default)

Full iterator protocol compliance with proper error handling:

Input:

for (var i of foo) {
  console.log(i);
}

Output:

var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
  for (var _iterator = foo[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
    var i = _step.value;
    console.log(i);
  }
} catch (err) {
  _didIteratorError = true;
  _iteratorError = err;
} finally {
  try {
    if (!_iteratorNormalCompletion && _iterator.return) {
      _iterator.return();
    }
  } finally {
    if (_didIteratorError) {
      throw _iteratorError;
    }
  }
}

3. Loose Mode

Optimized for performance, especially with arrays:

Input:

for (var i of foo) {
  console.log(i);
}

Output:

for (var _iterator = foo, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  var _ref;

  if (_isArray) {
    if (_i >= _iterator.length) break;
    _ref = _iterator[_i++];
  } else {
    _i = _iterator.next();
    if (_i.done) break;
    _ref = _i.value;
  }

  var i = _ref;
  console.log(i);
}

Visitor Pattern

The plugin uses Babel's visitor pattern to transform AST nodes:

interface BabelPlugin {
  visitor: {
    /** Visitor method for ForOfStatement AST nodes */
    ForOfStatement(path: NodePath, state: PluginPass): void;
  };
}

interface NodePath<T = Node> {
  /** The AST node being visited */
  node: T;
  /** Babel scope utilities */
  scope: Scope;
  /** Parent path in the AST */
  parentPath: NodePath;
  /** Replace this node with multiple nodes */
  replaceWithMultiple(nodes: Node[]): void;
  /** Ensure the node body is a block statement */
  ensureBlock(): void;
  /** Get child path by property name */
  get(key: string): NodePath;
  /** Remove this node from the AST */
  remove(): void;
}

interface PluginPass {
  /** Plugin options passed via configuration */
  opts: PluginOptions;
}

Supported For-Of Patterns

The plugin handles various for...of loop patterns:

Variable Declarations

// let declaration
for (let item of iterable) { }

// const declaration  
for (const item of iterable) { }

// var declaration
for (var item of iterable) { }

Identifiers and Patterns

// Existing identifier
for (item of iterable) { }

// Destructuring pattern
for (const { name, age } of users) { }

// Array destructuring
for (const [key, value] of entries) { }

// Member expression
for (obj.prop of iterable) { }

Labeled Statements

outer: for (const item of iterable) {
  if (condition) break outer;
}

Dependencies

The plugin requires:

  • babel-runtime: Runtime helpers for transformation
  • Babel core infrastructure (messages, template, types)

Internal Architecture

Template System

The plugin uses Babel's template system with three core templates for code generation:

/** Template for array literal optimization */
const buildForOfArray: (replacements: {
  KEY: Node,
  ARR: Node,
  BODY: Node
}) => Node;

/** Template for loose mode transformation */
const buildForOfLoose: (replacements: {
  LOOP_OBJECT: Node,
  IS_ARRAY: Node,
  OBJECT: Node,
  INDEX: Node,
  ID: Node
}) => Node;

/** Template for spec-compliant transformation */
const buildForOf: (replacements: {
  ITERATOR_HAD_ERROR_KEY: Node,
  ITERATOR_COMPLETION: Node,
  ITERATOR_ERROR_KEY: Node,
  ITERATOR_KEY: Node,
  STEP_KEY: Node,
  OBJECT: Node,
  BODY: Node
}) => Node[];

Internal Transformation Functions

The plugin uses three internal functions to handle different transformation strategies:

/**
 * Handles array literal optimization transformation
 * @param {NodePath} path - The ForOfStatement path
 * @returns {Node[]} Array of replacement nodes
 */
function _ForOfStatementArray(path: NodePath<ForOfStatement>): Node[];

/**
 * Implements loose mode transformation for better performance
 * @param {NodePath} path - The ForOfStatement path
 * @param {object} file - Babel file object for error reporting
 * @returns {TransformResult} Transformation result object
 */
function loose(path: NodePath<ForOfStatement>, file: BabelFile): TransformResult;

/**
 * Implements spec-compliant transformation with full iterator protocol
 * @param {NodePath} path - The ForOfStatement path
 * @param {object} file - Babel file object for error reporting
 * @returns {TransformResult} Transformation result object
 */
function spec(path: NodePath<ForOfStatement>, file: BabelFile): TransformResult;

Transformation Result Type

interface TransformResult {
  /** Whether to replace the parent node instead of current node */
  replaceParent: boolean;
  /** Variable declaration node to inject into loop body */
  declar?: Node;
  /** The transformed loop node */
  loop: Node;
  /** Final replacement node(s) */
  node: Node | Node[];
}

Error Handling

Loose Mode Limitations

In loose mode, an iterator's return method will not be called on abrupt completions caused by thrown errors. This is a performance trade-off for better array iteration speed.

Unsupported Patterns

The plugin throws errors for unsupported for...of left-hand side patterns using Babel's error reporting:

// This will cause a build error with code frame context
file.buildCodeFrameError(left, messages.get("unknownForHead", left.type));

Error reporting uses Babel's message system with helpful code frame context showing the exact location of unsupported syntax.