Template builders are the core functionality that creates AST generators from string templates or template literals. They provide both immediate AST generation and deferred template functions.
The main template export that combines all formatter capabilities in a single interface.
/**
* Default template builder that provides smart formatting and access to all formatters
* Uses smart formatter by default (returns single statement or array based on content)
*/
declare const template: DefaultTemplateBuilder;
interface DefaultTemplateBuilder extends TemplateBuilder<t.Statement | t.Statement[]> {
smart: typeof smart;
statement: typeof statement;
statements: typeof statements;
expression: typeof expression;
program: typeof program;
ast: typeof smart.ast;
}Usage Examples:
import template from "@babel/template";
import * as t from "@babel/types";
// Using default (smart) formatter
const buildRequire = template("const %%name%% = require(%%source%%);");
const requireAst = buildRequire({
name: t.identifier("lodash"),
source: t.stringLiteral("lodash")
});
// Using specific formatter through default export
const buildExpr = template.expression("%%left%% + %%right%%");
const exprAst = buildExpr({
left: t.identifier("a"),
right: t.identifier("b")
});
// Direct AST generation
const directAst = template.ast("const x = %%value%%;", {
value: t.numericLiteral(42)
});The core interface implemented by all template builders.
interface TemplateBuilder<T> {
/**
* Create new builder with merged options
* @param opts - Template options to merge
* @returns New template builder with combined options
*/
(opts: PublicOpts): TemplateBuilder<T>;
/**
* Create template function from string
* @param tpl - Template string with placeholders
* @param opts - Optional template processing options
* @returns Function that accepts replacements and returns AST
*/
(tpl: string, opts?: PublicOpts): (replacements?: PublicReplacements) => T;
/**
* Create template function from template literal
* @param tpl - Template strings array from template literal
* @param args - Placeholder arguments from template literal
* @returns Function that accepts replacements and returns AST
*/
(
tpl: TemplateStringsArray,
...args: Array<unknown>
): (replacements?: PublicReplacements) => T;
/**
* Direct AST generation methods (no intermediate function)
*/
ast: {
/**
* Generate AST directly from string template
* @param tpl - Template string
* @param opts - Optional template options
* @returns Generated AST of type T
*/
(tpl: string, opts?: PublicOpts): T;
/**
* Generate AST directly from template literal
* @param tpl - Template strings array
* @param args - Placeholder arguments
* @returns Generated AST of type T
*/
(tpl: TemplateStringsArray, ...args: Array<unknown>): T;
};
}Each formatter provides its own template builder with specific output guarantees.
/**
* Smart formatter template builder
* Returns single statement if template has one statement, array if multiple
*/
declare const smart: TemplateBuilder<t.Statement | t.Statement[]>;
/**
* Statement formatter template builder
* Enforces exactly one statement, throws error for zero or multiple statements
*/
declare const statement: TemplateBuilder<t.Statement>;
/**
* Statements formatter template builder
* Always returns array of statements
*/
declare const statements: TemplateBuilder<t.Statement[]>;
/**
* Expression formatter template builder
* Returns expression node, validates template contains valid expression
*/
declare const expression: TemplateBuilder<t.Expression>;
/**
* Program formatter template builder
* Returns program node containing all statements
*/
declare const program: TemplateBuilder<t.Program>;Usage Examples:
import { statement, expression, statements } from "@babel/template";
import * as t from "@babel/types";
// Statement builder - must produce exactly one statement
const buildIf = statement("if (%%test%%) { %%consequent%% }");
const ifAst = buildIf({
test: t.identifier("condition"),
consequent: t.blockStatement([t.returnStatement(t.booleanLiteral(true))])
});
// Expression builder - must produce valid expression
const buildBinary = expression("%%left%% %%operator%% %%right%%");
const binaryAst = buildBinary({
left: t.identifier("a"),
operator: "+", // This will be parsed as part of the template
right: t.identifier("b")
});
// Statements builder - always returns array
const buildModule = statements(`
const %%name%% = require(%%source%%);
module.exports = %%name%%;
`);
const moduleAsts = buildModule({
name: t.identifier("utils"),
source: t.stringLiteral("./utils")
});Template builders support ES6 template literal syntax for embedding values directly.
/**
* Template literal with embedded values
* Values are automatically converted to placeholder names and replaced
*/
type TemplateLiteralCall<T> = (
tpl: TemplateStringsArray,
...args: Array<unknown>
) => (replacements?: PublicReplacements) => T;Usage Examples:
import template from "@babel/template";
import * as t from "@babel/types";
// Template literal with embedded AST nodes
const buildFunction = template`
function ${t.identifier("add")}(${t.identifier("a")}, ${t.identifier("b")}) {
return ${t.binaryExpression("+", t.identifier("a"), t.identifier("b"))};
}
`;
const functionAst = buildFunction();
// Direct AST generation with template literal
const directFunction = template.ast`
const ${t.identifier("result")} = ${t.callExpression(
t.identifier("calculate"),
[t.numericLiteral(5)]
)};
`;
// Mixed template literal and replacement object
const buildClass = template`
class ${t.identifier("MyClass")} {
constructor() {
this.%%prop%% = %%value%%;
}
}
`;
const classAst = buildClass({
prop: t.identifier("data"),
value: t.arrayExpression([])
});