How to Add Native Keyword Aliases to Babel
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!
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!
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.