CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-babel--plugin-transform-block-scoping

Babel plugin that transforms ES2015 block scoping (const and let) to ES5 while preserving correct scoping semantics

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

index.mddocs/

@babel/plugin-transform-block-scoping

A Babel plugin that transforms ES2015 block-scoped declarations (const and let) into ES5-compatible var declarations while preserving correct scoping semantics. It handles complex scenarios including temporal dead zones (TDZ), loop closures, variable capturing, and binding conflicts.

Package Information

  • Package Name: @babel/plugin-transform-block-scoping
  • Package Type: npm (Babel plugin)
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-transform-block-scoping
  • Node.js: >=6.9.0

Core Imports

// Import as Babel plugin (most common)
const blockScopingPlugin = require("@babel/plugin-transform-block-scoping");

ES Module:

import blockScopingPlugin from "@babel/plugin-transform-block-scoping";

Basic Usage

Babel Configuration

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

With options:

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-transform-block-scoping", {
      tdz: false,
      throwIfClosureRequired: false
    }]
  ]
};

Programmatic Usage

import { transform } from "@babel/core";
import blockScopingPlugin from "@babel/plugin-transform-block-scoping";

const result = transform(code, {
  plugins: [
    [blockScopingPlugin, { tdz: true }]
  ]
});

Capabilities

Block Scoping Transformation

Transforms ES2015 let and const declarations to ES5 var while preserving block scoping behavior.

/**
 * Main plugin export - Babel plugin factory function
 * Requires @babel/core ^7.0.0-0 as peer dependency
 */
declare function blockScopingPlugin(
  api: any,
  options: Options
): BabelPlugin;

export default blockScopingPlugin;

interface Options {
  /** Enable temporal dead zone enforcement (default: false) */
  tdz?: boolean;
  /** Throw error when closure wrapping is required (default: false) */
  throwIfClosureRequired?: boolean;
}

interface BabelPlugin {
  name: string;
  visitor: Visitor;
}

Runtime Helpers: When TDZ is enabled or const violations occur, the plugin uses Babel runtime helpers:

  • temporalUndefined: Sentinel value for uninitialized TDZ variables
  • temporalRef: Runtime check for TDZ access
  • tdz: Throws ReferenceError for definite TDZ violations
  • readOnlyError: Throws TypeError for const reassignments

Input:

{
  let x = 1;
  const y = 2;
}

Output:

{
  var x = 1;
  var y = 2;
}

Temporal Dead Zone (TDZ) Support

When tdz: true is enabled, the plugin enforces temporal dead zone behavior by injecting runtime checks using Babel's helper functions (temporalRef, temporalUndefined, tdz).

Input with TDZ enabled:

console.log(x); // Should throw ReferenceError
let x = 1;

Output with TDZ:

var _temporalUndefined = {};
var x = _temporalUndefined;
console.log((x !== _temporalUndefined ? x : (() => {
  throw new ReferenceError('x is not defined - temporal dead zone');
})())); // Throws at runtime
x = 1;

### Loop Variable Handling

Special processing for block-scoped variables in loops, with automatic closure wrapping when variables are captured.

**Input:**
```javascript
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}

Output (with closure wrapping):

var _loop = function _loop() {
  setTimeout(() => console.log(i), 100);
};
for (var i = 0; i < 3; i++) {
  _loop();
}

Constant Violation Detection

Runtime errors for const reassignments to maintain ES2015 semantics. The plugin uses Babel's readOnlyError helper to generate appropriate error messages.

Input:

const x = 1;
x = 2; // Should throw TypeError

Output:

var x = 1;
x = ((() => {
  throw new TypeError('"x" is read-only');
})(), 2);

Error Types:

  • TypeError: Thrown for const reassignments ("varName" is read-only)
  • ReferenceError: Thrown for TDZ violations when tdz: true (cannot access 'varName' before initialization)

Variable Hoisting (Annex B.3.3)

Implements ECMAScript Annex B.3.3 function hoisting behavior for compatibility.

Input:

{
  function foo() {}
}
console.log(foo); // Should be accessible

Output:

{
  var foo = function foo() {};
}
console.log(foo);

Configuration Options

tdz (boolean, default: false)

Enable temporal dead zone enforcement with runtime checks.

// Enable TDZ
{
  "plugins": [["@babel/plugin-transform-block-scoping", { "tdz": true }]]
}

When enabled:

  • Adds runtime checks for accessing variables before declaration
  • Throws ReferenceError for TDZ violations
  • Increases bundle size due to additional runtime checks

throwIfClosureRequired (boolean, default: false)

Throw compilation error when closure wrapping would be required for loop variables.

// Strict mode - no closure wrapping allowed
{
  "plugins": [["@babel/plugin-transform-block-scoping", { "throwIfClosureRequired": true }]]
}

When enabled:

  • Prevents automatic closure wrapping in loops
  • Throws compilation error instead of transforming
  • Useful for performance-sensitive code where closures are not desired

Transformation Features

Core Capabilities

  1. Block Scope Transformation: Converts let/const to var with proper scoping
  2. Loop Variable Handling: Special processing for block-scoped variables in loops
  3. Temporal Dead Zone: Optional TDZ enforcement with runtime checks
  4. Closure Wrapping: Automatic loop body wrapping when variables are captured
  5. Constant Violation Detection: Runtime errors for const reassignments
  6. Variable Hoisting: Implements Annex B.3.3 function hoisting behavior
  7. Scope Conflict Resolution: Handles variable name conflicts across scope boundaries

Transformation Modes

  • Standard Mode: Basic let/const to var transformation
  • TDZ Mode: With temporal dead zone enforcement (tdz: true)
  • Strict Mode: Throws errors when closures are required (throwIfClosureRequired: true)

Browser Compatibility

This plugin enables let and const syntax to work in environments that don't support ES2015 block scoping:

  • Internet Explorer (all versions)
  • Chrome < 49
  • Firefox < 44
  • Safari < 10
  • Node.js < 6

Types

export interface Options {
  /** Enable temporal dead zone enforcement */
  tdz?: boolean;
  /** Throw error when closure wrapping is required */  
  throwIfClosureRequired?: boolean;
}

interface BabelPlugin {
  name: string;
  visitor: Visitor;
}

interface Visitor {
  Loop(path: NodePath<t.Loop>, state: PluginPass): void;
  VariableDeclaration(path: NodePath<t.VariableDeclaration>, state: PluginPass): void;
  ClassDeclaration(path: NodePath<t.ClassDeclaration>): void;
}

docs

index.md

tile.json