Turbocharged JavaScript refactoring with codemods — Airbnb Engineering & Data Science

By Joe Lencioni

It is fun to plant and harvest new crops in my garden, but I’ll eventually wake up to a mess if I don’t regularly weed. While each weed isn’t a problem by itself, they combine forces to choke the system. Working in a weed-free garden is a productive pleasure. Codebases are like this too.

I also don’t enjoy weeding, so I forget to and end up in trouble. Thankfully, in coding, we have great tools like ESLint and SCSS-Lint to ensure that we weed as we go. However, if we find large chunks of legacy code that deserve attention, we can be overwhelmed by the thought of manually tweaking a million spaces here and a gazillion dangling commas there.

Millions of lines of JavaScript have been checked into source control at Airbnb over the past 8 years; meanwhile, frontend Web development has evolved dramatically. Features, frameworks, and even JavaScript itself are moving targets — although following a good style guide from the get-go will help minimize this kind of pain, it is easy to end up with a codebase that no longer follows current “best practices”. Each small inconsistency is like a little weed, waiting to be plucked to make room for something beneficial and pave the way for a more productive team. Look at the shape our garden was in:

Before codemods

I’m obsessed with making the team faster and know that consistent code and information from linters tightens up feedback loops and reduces communication overhead. We recently started a weeding project to prepare a lot of old JavaScript to follow our style guide and enable our linters in more places. Doing all of the work by hand is pretty tedious and time-consuming, so we looked for tools to automate some of it. Although eslint —fix is a great starting point, it is currently limited in what it can fix. They’ve recently started accepting pull requests for auto fixing any rule, and efforts are underway to implement a Concrete Syntax Tree (CST) for JavaScript, but it will take some time before that is well-integrated. Thankfully, we found Facebook’s jscodeshift, which is a toolkit for codemods (codemods are tools that assist large-scale, partially automatable codebase refactoring). If a codebase is a garden, jscodeshift is a robo gardener.

This tool parses JavaScript into an Abstract Syntax Tree (AST), applies transformations, and writes out the modified JavaScript while matching local coding style. The transformations themselves are written in JavaScript, which makes this tool pretty accessible for our team. Finding or inventing the transformations we need accelerates mundane refactoring, which helps our team focus on more meaningful work.

After running a few codemods, our garden looks a little better:

After codemods

Tactics

Since most codemods take less than a minute with thousands of files, I find that codemodding is a great side-task while I wait for something on my main thread (e.g. code review). This helps maximize my productivity while making progress on bigger or more important projects.

The main challenges I’ve run into while working on large-scale refactorings usually revolve around the 4 C’s: Communication, Correctness, Code reviews, and (merge) Conflicts. I’ve used some of the following tactics to help minimize these challenges.
...

Read more @ Medium