- API" level="1">API
babel-parser
" level="2">id="toc-babel-parser"babel-parser
babel-traverse
" level="2">id="toc-babel-traverse"babel-traverse
babel-types
" level="2">id="toc-babel-types"babel-types
babel-generator
" level="2">id="toc-babel-generator"babel-generator
babel-template
" level="2">id="toc-babel-template"babel-template
API" class="reference-link">API
Babel is actually a collection of modules. In this section we’ll walk through the major ones, explaining what they do and how to use them.
Note: This is not a replacement for detailed API documentation, which is available here.
babel-parser
" class="reference-link">babel-parser
Started as a fork of Acorn, the Babel Parser is fast, simple to use, has plugin-based architecture for non-standard features (as well as future standards).
First, let’s install it.
$ npm install --save @babel/parser
Let’s start by simply parsing a string of code:
import parser from "@babel/parser";
const code = `function square(n) {
return n * n;
}`;
parser.parse(code);
// Node {
// type: "File",
// start: 0,
// end: 38,
// loc: SourceLocation {...},
// program: Node {...},
// comments: [],
// tokens: [...]
// }
We can also pass options to parse()
like so:
parser.parse(code, {
sourceType: "module", // default: "script"
plugins: ["jsx"] // default: []
});
sourceType
can either be "module"
or "script"
which is the mode that
the Babel Parser should parse in. "module"
will parse in strict mode and allow module
declarations, "script"
will not.
Note:
sourceType
defaults to"script"
and will error when it findsimport
orexport
. PasssourceType: "module"
to get rid of these errors.
Since the Babel Parser is built with a plugin-based architecture, there is also a
plugins
option which will enable the internal plugins. Note that the Babel Parser has
not yet opened this API to external plugins, although may do so in the future.
To see a full list of plugins, see the Babel parser docs.
babel-traverse
" class="reference-link">babel-traverse
The Babel Traverse module maintains the overall tree state, and is responsible for replacing, removing, and adding nodes.
Install it by running:
$ npm install --save @babel/traverse
We can use it alongside to traverse and update nodes:
import parser from "@babel/parser";
import traverse from "@babel/traverse";
const code = `function square(n) {
return n * n;
}`;
const ast = parser.parse(code);
traverse(ast, {
enter(path) {
if (
path.node.type === "Identifier" &&
path.node.name === "n"
) {
path.node.name = "x";
}
}
});
babel-types
" class="reference-link">babel-types
Babel Types is a Lodash-esque utility library for AST nodes. It contains methods for building, validating, and converting AST nodes. It’s useful for cleaning up AST logic with well thought out utility methods.
You can install it by running:
$ npm install --save @babel/types
Then start using it:
import traverse from "@babel/traverse";
import * as t from "@babel/types";
traverse(ast, {
enter(path) {
if (t.isIdentifier(path.node, { name: "n" })) {
path.node.name = "x";
}
}
});
Definitions" class="reference-link">Definitions
Babel Types has definitions for every single type of node, with information on what properties belong where, what values are valid, how to build that node, how the node should be traversed, and aliases of the Node.
A single node type definition looks like this:
defineType("BinaryExpression", {
builder: ["operator", "left", "right"],
fields: {
operator: {
validate: assertValueType("string")
},
left: {
validate: assertNodeType("Expression")
},
right: {
validate: assertNodeType("Expression")
}
},
visitor: ["left", "right"],
aliases: ["Binary", "Expression"]
});
Builders" class="reference-link">Builders
You’ll notice the above definition for BinaryExpression
has a field for a
builder
.
builder: ["operator", "left", "right"]
This is because each node type gets a builder method, which when used looks like this:
t.binaryExpression("*", t.identifier("a"), t.identifier("b"));
Which creates an AST like this:
{
type: "BinaryExpression",
operator: "*",
left: {
type: "Identifier",
name: "a"
},
right: {
type: "Identifier",
name: "b"
}
}
Which when printed looks like this:
a * b
Builders will also validate the nodes they are creating and throw descriptive errors if used improperly. Which leads into the next type of method.
Validators" class="reference-link">Validators
The definition for BinaryExpression
also includes information on the fields
of a node and how to validate them.
fields: {
operator: {
validate: assertValueType("string")
},
left: {
validate: assertNodeType("Expression")
},
right: {
validate: assertNodeType("Expression")
}
}
This is used to create two types of validating methods. The first of which is
isX
.
t.isBinaryExpression(maybeBinaryExpressionNode);
This tests to make sure that the node is a binary expression, but you can also pass a second parameter to ensure that the node contains certain properties and values.
t.isBinaryExpression(maybeBinaryExpressionNode, { operator: "*" });
There is also the more, ehem, assertive version of these methods, which will
throw errors instead of returning true
or false
.
t.assertBinaryExpression(maybeBinaryExpressionNode);
t.assertBinaryExpression(maybeBinaryExpressionNode, { operator: "*" });
// Error: Expected type "BinaryExpression" with option { "operator": "*" }
Converters" class="reference-link">Converters
[WIP]
babel-generator
" class="reference-link">babel-generator
Babel Generator is the code generator for Babel. It takes an AST and turns it into code with sourcemaps.
Run the following to install it:
$ npm install --save @babel/generator
Then use it
import parser from "@babel/parser";
import generate from "@babel/generator";
const code = `function square(n) {
return n * n;
}`;
const ast = parser.parse(code);
generate(ast, {}, code);
// {
// code: "...",
// map: "..."
// }
You can also pass options to generate()
.
generate(ast, {
retainLines: false,
compact: "auto",
concise: false,
quotes: "double",
// ...
}, code);
babel-template
" class="reference-link">babel-template
Babel Template is another tiny but incredibly useful module. It allows you to write strings of code with placeholders that you can use instead of manually building up a massive AST. In computer science, this capability is called quasiquotes.
$ npm install --save @babel/template
import template from "@babel/template";
import generate from "@babel/generator";
import * as t from "@babel/types";
const buildRequire = template(`
var IMPORT_NAME = require(SOURCE);
`);
const ast = buildRequire({
IMPORT_NAME: t.identifier("myModule"),
SOURCE: t.stringLiteral("my-module")
});
console.log(generate(ast).code);
var myModule = require("my-module");