CtrlK
BlogDocsLog inGet started
Tessl Logo

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.

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/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;
}

docs

index.md

tile.json