or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--plugin-transform-block-scoped-functions

Babel plugin to ensure function declarations at the block level are block scoped

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

To install, run

npx @tessl/cli install tessl/npm-babel--plugin-transform-block-scoped-functions@7.27.0

index.mddocs/

@babel/plugin-transform-block-scoped-functions

@babel/plugin-transform-block-scoped-functions is a Babel plugin that transforms function declarations within block statements to ensure proper block-level scoping semantics. It converts function declarations inside blocks (like if statements, loops, or switch cases) into let-bound variable declarations containing function expressions, preventing function hoisting issues and ensuring ES6+ block scoping behavior.

Package Information

  • Package Name: @babel/plugin-transform-block-scoped-functions
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-transform-block-scoped-functions

Core Imports

// CommonJS
const plugin = require("@babel/plugin-transform-block-scoped-functions");

// ES modules (for Babel configuration)
import plugin from "@babel/plugin-transform-block-scoped-functions";

Basic Usage

Babel Configuration (.babelrc or babel.config.js)

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

Transformation Example

Input:

if (true) {
  function f() {
    return 1;
  }
  console.log(f()); // 1
}

Output:

if (true) {
  let f = function() {
    return 1;
  };
  console.log(f()); // 1
}

Capabilities

Plugin Function

The main plugin export that integrates with Babel's transformation pipeline. The plugin enforces Babel 7+ compatibility through version assertion.

/**
 * Main Babel plugin function created using declare() from @babel/helper-plugin-utils
 * Internally calls api.assertVersion(REQUIRED_VERSION(7)) to ensure Babel 7+ compatibility
 * @param api - Babel API object containing helper functions and version checks
 * @returns Babel plugin object with visitor methods
 */
export default function(api: any): BabelPlugin;

interface BabelPlugin {
  /** Plugin identifier name */
  name: string;
  /** AST visitor methods for transformation */
  visitor: PluginVisitor;
}

interface PluginVisitor {
  /** Transforms function declarations within block statements */
  BlockStatement(path: NodePath<t.BlockStatement>): void;
  /** Transforms function declarations within switch case consequents */
  SwitchCase(path: NodePath<t.SwitchCase>): void;
}

Block Statement Transformation

Handles function declarations within block statements, converting them to let-bound variable declarations.

/**
 * Transforms function declarations within block statements
 * @param path - NodePath for the BlockStatement node
 */
BlockStatement(path: NodePath<t.BlockStatement>): void;

Behavior:

  • Skips transformation if the block is a function body
  • Skips transformation if the block is part of an export declaration
  • Processes each statement in the block body using transformStatementList

Switch Case Transformation

Handles function declarations within switch case consequents.

/**
 * Transforms function declarations within switch case consequents
 * @param path - NodePath for the SwitchCase node
 */
SwitchCase(path: NodePath<t.SwitchCase>): void;

Behavior:

  • Processes each statement in the switch case consequent using transformStatementList

Transformation Rules

Standard Transformation

In all Babel versions, the plugin transforms function declarations within blocks:

// Before transformation
{
  function myFunc() {
    return "hello";
  }
}

// After transformation  
{
  let myFunc = function() {
    return "hello";
  };
}

Babel 8 Enhanced Rules

In Babel 8, additional rules apply based on strict mode and function characteristics:

  • Strict Mode: All function declarations in blocks are transformed
  • Non-Strict Mode: Only async functions, generator functions, and async generator functions are transformed
  • Regular Functions: In non-strict mode, regular function declarations are left unchanged to maintain legacy hoisting behavior

Hoisting Behavior

Transformed variable declarations receive special hoisting treatment:

// The generated variable declaration gets _blockHoist = 2
let myFunc = function() { /* ... */ };
// This ensures proper ordering within the block

Error Conditions

The plugin operates at the AST transformation level and does not throw runtime errors. Potential issues:

  • Syntax Errors: If the source code has invalid function declarations, Babel's parser will catch these before the plugin runs
  • Type Errors: In TypeScript contexts, function name changes may affect type checking (handled by TypeScript compiler)

Version Compatibility

  • Node.js: Requires Node.js >=6.9.0
  • Babel 8: Requires Node.js ^20.19.0 || >=22.12.0
  • Babel Core: Requires @babel/core ^7.0.0-0

Dependencies

Runtime Dependencies

  • @babel/helper-plugin-utils: Provides the declare() function for plugin creation

Peer Dependencies

  • @babel/core: Required for AST types and transformation APIs

Types

// From @babel/core
interface NodePath<T = Node> {
  node: T;
  parent: Node;
  isInStrictMode(): boolean;
  isFunctionDeclaration(): boolean;
  get(key: string): NodePath | NodePath[];
  replaceWith(node: Node): void;
  getData(key: string): any;
}

// From @babel/types
interface BlockStatement extends Node {
  body: Statement[];
}

interface SwitchCase extends Node {
  consequent: Statement[];
}

interface FunctionDeclaration extends Node {
  id: Identifier | null;
  async: boolean;
  generator: boolean;
}

interface VariableDeclaration extends Node {
  kind: "var" | "let" | "const";
  declarations: VariableDeclarator[];
  _blockHoist?: number;
}