Codemod

We have tens of thousands of JavaScript modules at Design System. When a developer makes breaking API changes to any of the design components (say Toggle), then consumer needs to transform/deprecate/update all of their JavaScript to consume that change. To deprecate and remove legacy APIs Felix Kling and Christoph Nakazawa developed a tool called jscodeshift for doing AST-to-AST transforms for JavaScript.

We could have built this using regexes, or by IDE or simple search and replace but, given the number of changes we had to make, and the subtle code style variations in different modules and products, it seemed like a bad idea.

As an example:

import toggle
Import Toggle form ‘/.toggle.js’
//Rename it as component TConst T = Toggle;//Use as component T<T isDefaultChecked=true>

So you can’t exactly figure out how this Toggle component is being used.

This is where jscodeshift comes in — instead of making string-to-string transforms it can transform a JavaScript AST (Abstract Syntax Tree) and then pretty-print the output and preserve code style.

Tool Box:

jscodeshift is a toolbox. It brings together:

  1. babel’s parser (currently called babylon)
  2. Ast-types by Ben Newman, for node creation and
  3. Recast for pretty-printing

jscodeshift wraps these tools up nicely and provides a unified API to find, filter, map and replace AST nodes.It also comes with a runner/worker feature that can apply transforms to thousands of files in parallel.

Modules:

  1. Transform Module
module.exports = function(fileInfo, api, options) {
// transform `fileInfo.source` here
// ...
// return changed source
return source;
};

An example in typescript how you can create a transformer:

const createTransformer = (component: string,migrates: { (j: core.JSCodeshift, source: any): void }[],) => (fileInfo: FileInfo, { jscodeshift: j }: API, options: Options) => {const source = j(fileInfo.source);migrates.forEach(tf => tf(j, source));return source.toSource(options.printOptions);};export createTransformer;

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store