Babel helper utility for transforming export declarations by splitting them into separate variable declarations and export statements during JavaScript/TypeScript compilation.
npx @tessl/cli install tessl/npm-babel--helper-split-export-declaration@7.24.0@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.
npm install @babel/helper-split-export-declarationimport 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");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);
});
}@babel/helper-split-export-declaration is built around a single transformation function that handles two main scenarios:
export default X into separate variable declaration and named export, handling both standalone declarations (functions, classes) and expressions with appropriate identifier generationexport const x = 1, y = 2 into separate declaration const x = 1, y = 2 and export statement export { x, y }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 = 1Return Value:
Behavior:
For ExportDefaultDeclaration:
export default function foo() {} to function foo() {} + export { foo as default }export default someExpression to var _default = someExpression + export { _default as default }scope.generateUidIdentifier()For ExportNamedDeclaration (with declaration, no specifiers):
getOuterBindingIdentifiers()export const x = 1, y = 2 to const x = 1, y = 2 + export { x, y }Error Conditions:
Error("Only default and named export declarations can be split.") if the input is not an export declaration or is an ExportAllDeclarationError("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 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;
}