or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

babel-helper-function-name

babel-helper-function-name is a Babel helper library that automatically assigns names to anonymous functions in JavaScript code during compilation. It intelligently handles complex scenarios such as function expressions in object properties, variable assignments, and method definitions, ensuring that functions receive appropriate names for better debugging and stack traces.

Package Information

  • Package Name: babel-helper-function-name
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install babel-helper-function-name

Core Imports

import functionNameHelper from "babel-helper-function-name";

For CommonJS:

const functionNameHelper = require("babel-helper-function-name");

Basic Usage

import functionNameHelper from "babel-helper-function-name";
import * as t from "babel-types";

// During Babel AST transformation
const result = functionNameHelper({
  node: functionNode,        // The function AST node
  parent: parentNode,        // Parent AST node
  scope: scope,              // Babel scope object
  id: identifierNode         // Optional: suggested identifier
});

// The function now has an appropriate name assigned

Architecture

babel-helper-function-name operates within the Babel compilation pipeline and provides:

  • Smart Name Detection: Automatically infers function names from context (object properties, variable assignments, etc.)
  • Self-Reference Analysis: Detects when functions reference themselves and creates wrapper functions when needed
  • Scope Management: Handles naming conflicts and scope binding issues
  • Generator Support: Works with both regular and generator functions
  • Arity Preservation: Maintains function parameter count in generated wrappers

Capabilities

Function Name Assignment

Assigns names to anonymous functions based on their context in the AST.

/**
 * Assigns a name to an anonymous function based on its context
 * @param options - Configuration object containing AST nodes and scope information
 * @param options.node - The function AST node to name
 * @param options.parent - The parent AST node providing context
 * @param options.scope - Babel scope object for the function
 * @param options.id - Optional identifier to use as the function name
 * @returns The original node, a wrapped version, or undefined if no naming needed
 */
export default function functionNameHelper({
  node,
  parent,
  scope,
  id
});

Supported Naming Patterns:

The helper automatically detects and handles these function naming scenarios:

  • Object method properties: { foo() {} } → function name becomes "foo"
  • Variable declarations: let foo = function() {} → function name becomes "foo"
  • Assignment expressions: foo = function() {} → function name becomes "foo"
  • Computed properties: { [key]: function() {} } → uses literal key values only

Self-Reference Handling:

When functions reference themselves by name, the helper creates wrapper functions to avoid scope conflicts:

// Input: self-referencing function
let factorial = function(n) {
  return n <= 1 ? 1 : n * factorial(n - 1);
};

// Output: wrapped to prevent scope issues
let factorial = (function(FUNCTION_KEY) {
  function factorial() {
    return FUNCTION_KEY.apply(this, arguments);
  }
  factorial.toString = function() {
    return FUNCTION_KEY.toString();
  };
  return factorial;
})(function(n) {
  return n <= 1 ? 1 : n * factorial(n - 1);
});

Usage Examples:

import functionNameHelper from "babel-helper-function-name";
import * as t from "babel-types";

// Example 1: Object method
const objectMethod = t.objectMethod(
  "method",
  t.identifier("myMethod"),
  [],
  t.blockStatement([])
);
const result1 = functionNameHelper({
  node: objectMethod,
  parent: t.objectExpression([objectMethod]),
  scope: scope
});

// Example 2: Variable assignment
const funcExpression = t.functionExpression(null, [], t.blockStatement([]));
const variableDeclarator = t.variableDeclarator(
  t.identifier("myFunc"),
  funcExpression
);
const result2 = functionNameHelper({
  node: funcExpression,
  parent: variableDeclarator,
  scope: scope
});

// Example 3: With explicit ID
const result3 = functionNameHelper({
  node: functionNode,
  parent: parentNode,
  scope: scope,
  id: t.identifier("customName")
});

Types

// Babel AST Node types (from babel-types)
interface Node {
  type: string;
  // Additional properties vary by node type
}

interface Identifier extends Node {
  type: "Identifier";
  name: string;
}

interface FunctionExpression extends Node {
  type: "FunctionExpression";
  id: Identifier | null;
  params: Identifier[];
  body: BlockStatement;
  generator: boolean;
  async: boolean;
}

interface ArrowFunctionExpression extends Node {
  type: "ArrowFunctionExpression";
  id: null;
  params: Identifier[];
  body: BlockStatement | Expression;
  generator: false;
  async: boolean;
}

interface FunctionDeclaration extends Node {
  type: "FunctionDeclaration";
  id: Identifier;
  params: Identifier[];
  body: BlockStatement;
  generator: boolean;
  async: boolean;
}

interface ObjectProperty extends Node {
  type: "ObjectProperty";
  key: Identifier | Literal;
  value: Expression;
  computed: boolean;
  shorthand: boolean;
}

interface ObjectMethod extends Node {
  type: "ObjectMethod";
  kind: "method" | "get" | "set";
  key: Identifier | Literal;
  params: Identifier[];
  body: BlockStatement;
  computed: boolean;
  generator: boolean;
  async: boolean;
}

interface VariableDeclarator extends Node {
  type: "VariableDeclarator";
  id: Identifier;
  init: Expression | null;
}

interface AssignmentExpression extends Node {
  type: "AssignmentExpression";
  operator: "=";
  left: Identifier | MemberExpression;
  right: Expression;
}

interface Literal extends Node {
  type: "Literal";
  value: string | number | boolean | null;
  raw: string;
}

interface BlockStatement extends Node {
  type: "BlockStatement";
  body: Statement[];
}

interface MemberExpression extends Node {
  type: "MemberExpression";
  object: Expression;
  property: Identifier | Literal;
  computed: boolean;
}

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

// Union types for common patterns
type Expression = FunctionExpression | ArrowFunctionExpression | Identifier | Literal | AssignmentExpression | MemberExpression;
type Statement = FunctionDeclaration | BlockStatement | VariableDeclaration;
type Function = FunctionExpression | ArrowFunctionExpression | FunctionDeclaration | ObjectMethod;

// Babel Scope object (from babel-traverse)
interface Scope {
  getBinding(name: string): Binding | undefined;
  getOwnBinding(name: string): Binding | undefined;
  getBindingIdentifier(name: string): Identifier | undefined;
  hasBinding(name: string): boolean;
  hasGlobal(name: string): boolean;
  hasOwnBinding(name: string): boolean;
  generateUidIdentifier(name: string): Identifier;
  rename(oldName: string, newName?: string): void;
  traverse(node: Node, visitor: object, state?: any): void;
  getProgramParent(): Scope;
  parent?: Scope;
  references: { [key: string]: boolean };
}

interface Binding {
  kind: "param" | "local" | "hoisted" | "module" | "const" | "let" | "var";
  constant: boolean;
  // Additional properties
}

Dependencies

This helper requires the following Babel packages:

  • babel-types: For AST node type checking and creation
  • babel-traverse: For AST scope management (used through scope parameter)
  • babel-template: For creating wrapper function templates
  • babel-helper-get-function-arity: For determining function parameter count
  • babel-runtime: For Babel runtime helpers

Error Handling

The helper gracefully handles edge cases:

  • No naming needed: Returns undefined when function already has a name
  • Unsupported patterns: Skips naming for complex computed properties
  • Scope conflicts: Uses wrapper functions or scope renaming as appropriate
  • Class expressions: Currently doesn't support wrapping class expressions (returns early)

Internal Components

The module contains several internal helper components that work together to implement function naming:

Wrapper Templates

Pre-defined babel-template constructs for creating wrapper functions when self-reference is detected:

// Template for regular function wrapping
const buildPropertyMethodAssignmentWrapper = template(`
  (function (FUNCTION_KEY) {
    function FUNCTION_ID() {
      return FUNCTION_KEY.apply(this, arguments);
    }
    FUNCTION_ID.toString = function () {
      return FUNCTION_KEY.toString();
    }
    return FUNCTION_ID;
  })(FUNCTION)
`);

// Template for generator function wrapping  
const buildGeneratorPropertyMethodAssignmentWrapper = template(`
  (function (FUNCTION_KEY) {
    function* FUNCTION_ID() {
      return yield* FUNCTION_KEY.apply(this, arguments);
    }
    FUNCTION_ID.toString = function () {
      return FUNCTION_KEY.toString();
    };
    return FUNCTION_ID;
  })(FUNCTION)
`);

AST Visitor

Internal visitor object for traversing function bodies to detect self-references:

const visitor = {
  "ReferencedIdentifier|BindingIdentifier"(path, state) {
    // Detects when function references itself by name
    // Sets state.selfReference = true when found
  }
};

Helper Functions

Internal functions that support the main functionality:

/**
 * Wraps a function with appropriate template when self-reference is detected
 * @param state - Analysis state containing selfReference flag
 * @param method - The function node to potentially wrap
 * @param id - The identifier to use for the function name
 * @param scope - Babel scope object
 * @returns Wrapped function expression or original method
 */
function wrap(state, method, id, scope);

/**
 * Analyzes function body for self-references and binding conflicts
 * @param node - Function node to analyze
 * @param name - Proposed function name
 * @param scope - Babel scope object  
 * @returns State object with analysis results
 */
function visit(node, name, scope);

Integration Notes

This helper is designed for use within Babel plugins and presets during JavaScript compilation. It should be called during AST traversal when encountering function nodes that need naming. The helper integrates with Babel's scope analysis system and requires a properly initialized scope object to function correctly.