Generating a JavaScript AST
Exploring tools to convert (or parse) JavaScript into a real AST
Now that we have an understanding of what abstract syntax trees are, we can start generating ASTs from source code, and programmatically traverse through the different nodes in the tree.
Babel#
When previously looking at AST Explorer, the parser option was set to @babel/parser
. This is a package available on npm, which means it can be installed and used to parse any source code string into an AST.
If you've worked with a frontend build pipeline, it's likely you've worked with babel in some fashion. At a high level, babel is a JavaScript compiler, commonly used to transpile modern JavaScript syntax to compatible, but older JavaScript syntax. This allows early adoption of new syntax and features before there is sufficient browser support.
It has a robust plugin system that can be used to add support for many different syntaxes, for example:
babel-plugin-proposal-optional-chaining
: adds support for optional chaining, which is new syntax that isn't widely supported by browsers yet. This will transpile this new syntax into equivalent older syntax.babel-plugin-transform-react-jsx
: adds support for JSX, which is XML-like, and not intended to be implemented by browsers. This plugin transpiles this syntax to an equivalent and supported syntax (functions and objects) before it can be run in the browser.babel-plugin-transform-typescript
: adds support for TypeScript, which adds static types. This plugin strips the types and does other transformations to transpile to valid JavaScript.
Babel performs these transpilations by converting the source code into an AST, manipulates the nodes, and converts the manipulated AST back into source code. These plugins can extend and modify the parsing and generation of the AST.
The @babel/core
package wraps up most of this functionality in a single package with minimal configuration. Babel also exposes the different internal operations and functionality in a series of packages. Some of the packages, which we'll use and further explore in this lesson, include:
@babel/parser
: parse a source code string into an AST.@babel/traverse
: traverse different types of nodes within an AST.@babel/generator
: convert an AST back into a source code string.@babel/types
: create new nodes to add (or replace existing nodes) in an AST.
These lower-level packages can be used to create flexible, custom scripts to parse, generate, and manipulate ASTs.
Parsing source code#
To get started, we'll use the @babel/parser
package to parse the previous code snippet into an AST.
2 + (4 * 10)
First, create a directory, initialize a new package.json
file, and add the @babel/parser
dependency.
# Create a new directory for the parser script
mkdir babel-parser-demo
# Change into the new directory
cd babel-parser-demo
# Initialize a new package.json file using the defaults
npm init -y
# Install the @babel/parser package as a dependency
npm i @babel/parser
Next, create a parser.js
file to execute the parser on the source code.
const { parse } = require("@babel/parser");
const code = "2 + (4 * 10)";
const ast = parse(code);
console.log(ast);
This page is a preview of Practical Abstract Syntax Trees