CtrlK
BlogDocsLog inGet started
Tessl Logo

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

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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.

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