https://medium.com/the-guild/this-is-how-i-build-babel-plug-ins-b0a13dcd0352

The idea of writing such article popped into my mind while working on my Webflow/React transpiler. All I wanted to do was to take a JS code string and transform it in such way that globals won’t be redefined if already so:

At the beginning I thought I could do that with some help from a regular expression; but boy was I wrong.

A regular expression is simply not enough because it ignores the concept of scoped variables completely and works on a string as if it was a plain text. To determine a global variable, what we need to ask ourselves is: Is this variable already declared in the current scope or one of its parent scopes?

The way to go with such question would be breaking down the code into nodes, where each node represents a part in our code and all the nodes are connected with each other in a relational manner. This whole node formation is called AST — abstract syntax tree, which can be used to easily lookup scopes and variables and other elements which are related to our code.

An example AST may look like so:

Obviously, breaking down our code into nodes is not a walk in the park. Luckily, we have a tool called Babel which already does that.

Babel is a project which originally started to transform the latest es20XX syntax into es5 syntax for better browser compatibility. As the Ecmascript committee keeps updating the standards of the Ecmascript language, plug-ins provide an excellent and maintainable solution to easily update the Babel compiler’s behavior.

Babel is made out of numerous components which work together to bring the latest Ecmascript syntax to life. Specifically the code transformation flow works with the following components and following relations:

Now you have a better understanding of Babel and you can actually understand what’s happening when you build a plug-in; and speaking of which, how do we do that?

First of all I would like us to understand Babel’s generated AST as this is essential for building the plug-in, because the plug-in’s gonna manipulate the AST and therefore we need to understand it. If you’ll go to astexplorer.net you’ll find an amazing compiler that will transform code into AST. Let’s take the code foo = "foo" as an example. The generated AST should look like so:

As you can see, each node in the tree represents a part of the code, and it’s recursive. The assignment expression foo = "foo" uses the operator =, the operand on the left is an identifier named foo and the operand on the right is a literal with the value "foo". So that’s how it goes, each part of the code can be presented as a node which is made out of other nodes, each node has a type and additional properties based on its type.

Now let’s say that we would like to change the value "foo" to "bar", hypothetically speaking what we will have to do would be grab the corresponding literal node and change its value from "foo", to "bar". Let’s take this simple example and turn it into a plug-in.