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

Incredible Demos

  • By
    background-size Matters

    It's something that makes all men live in fear, and are often uncertain of. It's never spoken, but the curiosity is always there. Nine out of ten women agree in the affirmative. Advertisers do their best to make us feel inadequate but...

  • By
    Detect Vendor Prefix with JavaScript

    Regardless of our position on vendor prefixes, we have to live with them and occasionally use them to make things work.  These prefixes can be used in two formats:  the CSS format (-moz-, as in -moz-element) and the JS format (navigator.mozApps).  The awesome X-Tag project has...

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!