Build your own Babel-Plugin from scratch
Tags: javascript, babel, react, css
Published: 2019-06-21 10:12:06

## A brief introduction

First of all, let's talk about Babel, Babel is a transpiler which converts code from JavaScript to JavaScript, maybe you are a little bit confused, but let's take the classic JSX example. When you code a React application you are not writing standard JS, and Babel is the one who translates all that beautiful code into some JS that your browser can understand.

![How a transpiler works](https://cdn-images-1.medium.com/max/1600/1*pbiJh2DzpQQRcIUOyhcp-g.png)
<figcaption>How a transpiler works</figcaption>

Well, all of this is pretty cool, now it's time to talk about how does it works, it's really simple, to be honest, it's just a visitor pattern which is applied in every AST (AST is the Abstract Syntax Tree generated after processing your input code) node. This pattern allows us to effectuate some actions like modify this AST before generating the new code.

![A classic visitor pattern](https://cdn-images-1.medium.com/max/1600/1*wqnxXkczjdcP1Pw3hFhIOw.png)
<figcaption>A classic visitor pattern</figcaption>

## A simple example

Nowadays is really common to hear about CSS-in-JS tools, like Styled-Components, or Styled-JSX. So let's create a simple CSS extractor, as requirements we are gonna make the assumption that all the styles must be declared in a function called `componentStyle` if we are talking about a non-stateless component.
The way we are gonna implement it is by creating custom JSX-tags that are gonna be listed as variables inside this function and associated to an object containing the desired style, here we have a simple example of a component defining the tags and their associated styles, as convention to make it easier the tags are going to be called `STYLED_<HTML tag>`.

{% gist https://gist.github.com/MFCo/690397a0eb0514c5b06f7b370babf307 %}

Now that we have decided our example to follow we need to make it works as expected, our goal is to:

1. Extract CSS from JS
2. Generate CSS files
3. Replace tags from JS to standard tags and associate them to CSS styles

First of all let's define our visitor function, as a plugin we are required to exports default a function that returns an object with the field visitor in which we have defined the callbacks associated to each AST node we want to modify or to effectuate any action on it. In the next code, we can appreciate the visitor that we are going to apply and a little description of what are we going to do in each case.

{% gist https://gist.github.com/MFCo/9a92e6c64230fd289e786e690429094a %}

I'm not going to write all the logic needed in each case because it's really simple, you can check the final work [HERE](https://github.com/MFCo/babel-plugin-css-generator-react-components). But basically that's how we create a new plugin that extracts the CSS from JS, and allows us to use custom tags, I've also added in that repo an implementation to stateless components where you take the styles from the parameters when you call the function, so there is another hook on the visitor over the `CallExpression` node.

Now you just need to hook it as any other plugin on your .babelrc and you will be processing your code with your own plugin, allowing you to create new syntax and to create a whole new world, or a whole new set of problems, haha.

## Conclusions

- You don't need to be an expert to create a new Babel plugin and make your own syntax extension.
- Things are not so magical as they seem to be, is important to know how Babel, Webpack, and other tools work. A funny way to do it is by creating a plugin for example.