or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-babel--helper-split-export-declaration

Babel helper utility for transforming export declarations by splitting them into separate variable declarations and export statements during JavaScript/TypeScript compilation.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@babel/helper-split-export-declaration@7.24.x

To install, run

npx @tessl/cli install tessl/npm-babel--helper-split-export-declaration@7.24.0

index.mddocs/

@babel/helper-split-export-declaration

@babel/helper-split-export-declaration is a Babel helper utility that provides functionality for transforming export declarations during JavaScript/TypeScript compilation. It specifically handles the splitting of export declarations into separate variable declarations and export statements, which is essential for Babel's AST transformation pipeline.

Package Information

  • Package Name: @babel/helper-split-export-declaration
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @babel/helper-split-export-declaration

Core Imports

import splitExportDeclaration from "@babel/helper-split-export-declaration";
import { NodePath } from "@babel/traverse";
import * as t from "@babel/types";

For CommonJS:

const splitExportDeclaration = require("@babel/helper-split-export-declaration").default;
const { NodePath } = require("@babel/traverse");
const t = require("@babel/types");

Basic Usage

import splitExportDeclaration from "@babel/helper-split-export-declaration";
import { NodePath } from "@babel/traverse";
import * as t from "@babel/types";

// Real-world usage in a Babel plugin visitor
const babelPlugin = {
  visitor: {
    // Transform export default class declarations
    ExportDefaultDeclaration(path: NodePath<t.ExportDefaultDeclaration>) {
      if (!path.get("declaration").isClassDeclaration()) return;
      // Split: export default class Foo {} → class Foo {} + export { Foo as default }
      splitExportDeclaration(path);
    },

    // Transform named export declarations with variable declarations
    ExportNamedDeclaration(path: NodePath<t.ExportNamedDeclaration>) {
      if (!path.node.declaration) return;
      // Split: export const x = 1, y = 2; → const x = 1, y = 2; + export { x, y }
      splitExportDeclaration(path);
    }
  }
};

// In module transformation helpers
function nameAnonymousExports(programPath: NodePath<t.Program>) {
  programPath.get("body").forEach(child => {
    if (!child.isExportDefaultDeclaration()) return;
    // Split anonymous exports to give them names for module processing
    splitExportDeclaration(child);
  });
}

Architecture

@babel/helper-split-export-declaration is built around a single transformation function that handles two main scenarios:

  • Default Export Processing: Converts export default X into separate variable declaration and named export, handling both standalone declarations (functions, classes) and expressions with appropriate identifier generation
  • Named Export Processing: Converts export const x = 1, y = 2 into separate declaration const x = 1, y = 2 and export statement export { x, y }
  • Scope Management: Properly manages Babel scope bindings and generates unique identifiers when needed for anonymous expressions
  • AST Node Creation: Uses @babel/types utilities to create properly formed AST nodes for the transformed code

Capabilities

Export Declaration Splitting

Transforms export declarations by splitting them into separate variable declarations and export statements.

/**
 * Splits export declarations into separate variable declarations and export statements
 * @param exportDeclaration - NodePath wrapping an ExportDefaultDeclaration or ExportNamedDeclaration
 * @returns NodePath of the newly created declaration that replaced the original export
 * @throws Error if input is not a valid export declaration or is an ExportAllDeclaration
 */
function splitExportDeclaration(
  exportDeclaration: NodePath<
    t.ExportDefaultDeclaration | t.ExportNamedDeclaration
  >
): NodePath<t.Declaration>;

Parameters:

  • exportDeclaration: A Babel NodePath wrapping either:
    • t.ExportDefaultDeclaration: Export default statements like export default foo()
    • t.ExportNamedDeclaration: Named export statements with declarations like export const x = 1

Return Value:

  • Returns the NodePath of the newly created declaration that replaces the original export declaration (function/class declaration or variable declaration)

Behavior:

  • For ExportDefaultDeclaration:

    • Standalone declarations (functions, classes): Converts export default function foo() {} to function foo() {} + export { foo as default }
    • Expressions: Converts export default someExpression to var _default = someExpression + export { _default as default }
    • Handles anonymous expressions by generating unique identifiers using scope.generateUidIdentifier()
    • Properly manages scope bindings and registers new bindings when identifiers are generated
    • Handles edge cases like shadowed bindings in export expressions
  • For ExportNamedDeclaration (with declaration, no specifiers):

    • Extracts all binding identifiers from the declaration using getOuterBindingIdentifiers()
    • Converts export const x = 1, y = 2 to const x = 1, y = 2 + export { x, y }
    • Creates appropriate export specifiers for each binding identifier
    • Preserves original declaration semantics while enabling separate export processing

Error Conditions:

  • Throws Error("Only default and named export declarations can be split.") if the input is not an export declaration or is an ExportAllDeclaration
  • Throws Error("It doesn't make sense to split exported specifiers.") if the ExportNamedDeclaration already has specifiers (e.g., export { x, y } or export { x } from "module")

Types

// Types from @babel/types
interface ExportDefaultDeclaration {
  type: "ExportDefaultDeclaration";
  declaration: Declaration | Expression;
}

interface ExportNamedDeclaration {
  type: "ExportNamedDeclaration";  
  declaration: Declaration | null;
  specifiers: ExportSpecifier[];
  source: StringLiteral | null;
}

interface ExportSpecifier {
  type: "ExportSpecifier";
  local: Identifier;
  exported: Identifier | StringLiteral;
}

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

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

// Types from @babel/traverse
interface NodePath<T = Node> {
  node: T;
  scope: Scope;
  get(key: string): NodePath;
  isExportDeclaration(): boolean;
  isExportAllDeclaration(): boolean;
  isExportDefaultDeclaration(): this is NodePath<ExportDefaultDeclaration>;
  isFunctionDeclaration(): boolean;
  isClassDeclaration(): boolean;
  insertAfter(nodes: Node | Node[]): void;
  replaceWith(replacement: Node): void;
  getOuterBindingIdentifiers(): { [key: string]: Identifier };
}

interface Scope {
  generateUidIdentifier(name?: string): Identifier;
  hasBinding(name: string): boolean;
  registerDeclaration(path: NodePath): void;
}