JSFoo: round the year submissions

JSFoo: round the year submissions

Submit talks on JavaScript and full stack engineering round the year

Sarup Banskota

@sarupbanskota

Writing a Babel codemod plugin

Submitted Oct 6, 2017

Often we want to mass-transform some code throughout our JS codebase - the kind where you have a formula for when to make the transformation, but it’s not as easy as doing a find/replace. Babel plugin codemods are the answer to that situation as they help you automate mundane tasks.

Recently, in the process of wanting to write a Babel plugin towards developing a new feature within Babel, I had to write a codemod. I went through the Babel-Handbook, which was a great resource to pick up more about Babel’s inner workings, but the plugin example provided in the handbook was too simple for me, a rookie.

Being new to how compilers work, ASTs, traversal etc, everything was overwhelming at first, but with some trial and error I eventually figured it out and ended up writing a codemod plugin!

I’d like to share a general idea of how Babel works, and how one could easily write codemod plugins.

Outline

  • Explain very quickly what Babel does
  • Explain concepts Babel depends on - tokens, parsing, ASTs, transforms, generation
  • Explain what we want to achieve with this plugin (more on the plugin later)
  • Walk through the process of writing the code (won’t live code, just snippets of the most important parts)
  • Run codemod on some sample input

Plugin - the plugin will do something fairly useful, but simple enough to explain code through the talk. I haven’t decided on that yet, but as an example, stealing from an Ember codebase of mine, it will convert files of the form:


import Ember from 'ember';

export default Ember.Controller.extend({ });

or

import Ember from 'ember';

export default Ember.Route.extend({ });

to

import Ember from 'ember';

const { Controller } = Ember;

export default Controller.extend({ });

and

import Ember from 'ember';

const { Route } = Ember;

export default Route.extend({ });

I know it sounds silly to write a plugin just to do that, but it starts to be productive when the codebase is larger.


** Pitch **

It’s safe to say a very, very huge number (95%?) of websites written in 2017, especially using a web framework like Ember for transpiling code from ES6 to ES5. So first off, there is curiosity element - how does it exactly work? :)

Second, compilers are generally considered to be a complex, alien piece of software only reserved for the extra terrestrials. I’ll try to explain why it’s actually not as complex as some compiler textbooks will give you the impression.

Third, understanding ASTs and writing codemods are great for productivity - with this knowledge you can move on to writing ESLint plugins and automate mundane tasks like styling code in a particular way, or sticking to a few “best practices” without having to manually make the changes in a large codebase.

Speaker bio

Although a recent one, I’m contributing to Babel and often write plugins to automate transforms in my own dayjob.

Otherwise, I lead frontend engineering for Mesitis and do JavaScript consulting for Ticketsolve.

Comments

{{ gettext('Login to leave a comment') }}

{{ gettext('Post a comment…') }}
{{ gettext('New comment') }}
{{ formTitle }}

{{ errorMsg }}

{{ gettext('No comments posted yet') }}

Hosted by

JSFoo is a forum for discussing UI engineering; fullstack development; web applications engineering, performance, security and design; accessibility; and latest developments in #JavaScript. Follow JSFoo on Twitter more