Template formatters control how template code is processed and what type of AST node is returned. Each formatter provides different validation and output behavior.
Base interface that all template formatters implement.
interface Formatter<T> {
/**
* Wrap template code for parsing
* @param source - Original template string
* @returns Modified code ready for parser
*/
code: (source: string) => string;
/**
* Validate parsed AST meets formatter requirements
* @param ast - Parsed AST file node
* @throws Error if validation fails
*/
validate: (ast: t.File) => void;
/**
* Extract result from parsed AST
* @param ast - Parsed and validated AST file node
* @returns Formatted result of type T
*/
unwrap: (ast: t.File) => T;
}Intelligent formatter that returns single statement or array based on template content.
/**
* Smart formatter that adapts output based on content
* - Returns single statement if template contains exactly one statement
* - Returns array of statements if template contains multiple statements
*/
declare const smart: Formatter<t.Statement | t.Statement[]>;Usage Examples:
import { smart } from "@babel/template";
import template from "@babel/template";
// Single statement - returns Statement
const singleStmt = template("const x = 1;")();
// Type: t.Statement
// Multiple statements - returns Statement[]
const multipleStmts = template(`
const x = 1;
const y = 2;
`)();
// Type: t.Statement[]
// Smart formatter is the default
const defaultTemplate = template("if (test) { body; }");
// Uses smart formatter automaticallyStrict formatter that enforces exactly one statement.
/**
* Statement formatter that enforces exactly one statement
* @throws Error if template contains zero statements
* @throws Error if template contains multiple statements
*/
declare const statement: Formatter<t.Statement>;Usage Examples:
import { statement } from "@babel/template";
// Valid - exactly one statement
const buildIf = statement("if (%%condition%%) { %%body%% }");
const ifStmt = buildIf({
condition: t.identifier("isReady"),
body: t.blockStatement([t.returnStatement()])
});
// Invalid - would throw error for multiple statements
// const invalid = statement("const x = 1; const y = 2;"); // Error!
// Invalid - would throw error for no statements
// const empty = statement(""); // Error!Formatter that always returns array of statements.
/**
* Statements formatter that always returns array of statements
* Returns empty array if no statements, array with statements otherwise
*/
declare const statements: Formatter<t.Statement[]>;Usage Examples:
import { statements } from "@babel/template";
// Single statement - returns [Statement]
const singleInArray = statements("const x = %%value%%;");
const result1 = singleInArray({ value: t.numericLiteral(42) });
// Type: t.Statement[] - always array
// Multiple statements - returns Statement[]
const buildModule = statements(`
const %%name%% = require(%%source%%);
module.exports = { %%name%% };
`);
const moduleStmts = buildModule({
name: t.identifier("utils"),
source: t.stringLiteral("./utils")
});
// Empty template - returns []
const empty = statements("")();
// Type: t.Statement[] - empty arrayFormatter that returns expression nodes with validation.
/**
* Expression formatter that validates and returns expression nodes
* @throws Error if template contains multiple statements
* @throws Error if result includes parsing parentheses
*/
declare const expression: Formatter<t.Expression>;Usage Examples:
import { expression } from "@babel/template";
// Binary expression
const buildBinary = expression("%%left%% + %%right%%");
const binaryExpr = buildBinary({
left: t.identifier("a"),
right: t.identifier("b")
});
// Type: t.Expression (specifically t.BinaryExpression)
// Call expression
const buildCall = expression("%%callee%%(%%arg1%%, %%arg2%%)");
const callExpr = buildCall({
callee: t.identifier("Math.max"),
arg1: t.numericLiteral(10),
arg2: t.numericLiteral(20)
});
// Member expression
const buildMember = expression("%%object%%.%%property%%");
const memberExpr = buildMember({
object: t.identifier("console"),
property: t.identifier("log")
});
// Invalid - statement would cause error
// const invalid = expression("const x = 1;"); // Error!Formatter that returns program node containing all statements.
/**
* Program formatter that returns program node
* Contains all statements from template in program body
*/
declare const program: Formatter<t.Program>;Usage Examples:
import { program } from "@babel/template";
// Full program with multiple statements
const buildModule = program(`
const %%name%% = require(%%source%%);
function %%exportName%%() {
return %%name%%;
}
module.exports = %%exportName%%;
`);
const programAst = buildModule({
name: t.identifier("lodash"),
source: t.stringLiteral("lodash"),
exportName: t.identifier("getLodash")
});
// Type: t.Program with body containing all statements
// Access program properties
console.log(programAst.body.length); // Number of statements
console.log(programAst.directives); // Program directivesEach formatter modifies template code before parsing:
/* @babel/template */;\n to force statement parsing and prevent directive interpretation(\n${str}\n) to ensure expression parsingFormatters apply specific validation after parsing:
Formatters extract results from parsed AST differently: