Build your own Babel-Plugin from scratch
A brief introduction
Well, all of this is pretty cool, now it's time to talk about how 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 modifying this AST before generating the new code.
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 with an object containing the desired style, here we have a simple example of a component defining the tags and their associated styles, as a convention to make it easier the tags are going to be called <STYLED_>+<HTML tag>.
Now that we have decided on our example to follow we need to make it works as expected, our goal is to:
- Extract CSS from JS
- Generate CSS files
- Replace tags from JS with standard tags and associate them with CSS styles
First of all let's define our visitor function, as a plugin we are required to export a default function that returns an object with the field visitor in which we have defined the callbacks associated with 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.
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. 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 a whole new world, or a whole new set of problems, haha.
- 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, it's just knowing how Babel, Webpack, and other tools work. A funny way to do it is by creating a plugin for example.