How to Add Native Keyword Aliases to Babel

By  on  

Those of you who follow this blog know that not every blog post is an endorsement of a technique but simply a tutorial how to accomplish something. Sometimes the technique described is probably not something you should do. This is one of those blog posts.

The Babel parser is an essential tool in the web stack these days. Babel helps us to use JavaScript patterns before they hit the browser (optional chaining) as well as JSX for React. This got me to thinking: how easy would it be to write a Babel extension to allow us to use keyword alias, like fn instead of function? Let's have a look!

Creating a keyword alias with Babel is both easier and more difficult than you would probably think. On the simple side, it's essentially just one line of code. On the negative side, you need to modify Babel's core parser code.

As our example, let's says we want to alias fn for JavaScript's function keyword. An example code snippet would look like:

// Named function
fn myFunction() {
    return true;
}

// Function as variable
const myOtherFunction = fn() {

}

// Instantly executing function
(fn() {

})();

After parsing we'd want all instances of fn to be replaced with function. To create this alias, we'd need to modify the createKeyword following file in

// File: packages/babel-parser/src/tokenizer/types.js
// We'll be adding one line
// ...
function createKeyword(name: string, options: TokenOptions = {}): TokenType {
  options.keyword = name;
  const token = new TokenType(name, options);
  keywords.set(name, token);

  // ADD THIS LINE:
  if (name === "function") keywords.set("fn", token);

  return token;
}
// ...

To parse a sample file, I can run:

node packages/babel-parser/bin/babel-parser.js /path/to/sample-file.js

The parser will provide the following when it encounters an instance of fn:

{
        "type": "FunctionDeclaration",
        "start": 0,
        "end": 36,
        "loc": {
          "start": {
            "line": 1,
            "column": 0
          },
          "end": {
            "line": 3,
            "column": 1
          }
        },
        "id": {
          "type": "Identifier",
          "start": 3,
          "end": 13,
          "loc": {
            "start": {
              "line": 1,
              "column": 3
            },
            "end": {
              "line": 1,
              "column": 13
            },
            "identifierName": "myFunction"
          },
          "name": "myFunction"
        }
// ...

You're probably asking yourself "why would I ever do that?!" Well, you probably wouldn't -- modifying a source library for your own use is a maintenance nightmare and using rogue keywords in your source....is also a maintenance nightmare.

All that being said, if you're looking to experiment with adding your own keyword aliases, modifying the Babel source is your best bet. I'd love if there were a way to write an extension to accomplish this. A big thank you to Logan Smyth for helping me navigate the Babel source!

Recent Features

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

Incredible Demos

Discussion

  1. It does seem like something I probably shouldn’t do but would definitely do just to learn. This is the reason your blog is one of the best ones out there. You give advice even for people like me who are looking to try anything just for fun and learning. Thank you!

  2. Good post. Indeed,the beauty of Babel is that it is not tied to React but rather provides a general purpose transpiler that could just as easily convert JSX to Vue.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!