The Art of Crafting Codemods

About me

twitter/rajasegar_c

Front-end Developer @ Freshworks

github/rajasegar

hangaroundtheweb.com

We are hiring!

pradeep.naik@freshworks.com

The Problem(s)

1. Making changes in code

Let's start with a small change

Replace variable "hello" with "world"

let hello = "world";
function hello() {
  console.log("hello world")
}
$ sed 's/hello/world' input.js
$ sed 's/hello/world' project1/app/**/*.js project2/app/**/*.js
let world = "world";
function world() {
  console.log("world world")
}
let hello = "world";
function hello() {
  console.log("hello world")
}

Change with(in) a context

Replace only the variable name "hello" with "world"

Replace variable "hello" with "world"

The Context

  • Which one is a variable name?

  • Which one is a function name?

  • Which one is a string literal?

2. Upgrading Code-base

Types of Upgrade

  • Upgrade to new language syntax / features
  • Upgrade a lib / framework to a newer version

Upgrade to new language syntax / features

mounted() {
    var self = this
    window.addEventListener('scroll', function() {
        self.scrolled = true
    })
}
mounted() {
    window.addEventListener('scroll', () => {
        this.scrolled = true
    })
}

Arrow functions

Upgrade a lib / framework to a newer version

attached: function () {
  doSomething()
}
mounted: function () {
  this.$nextTick(function () {
    doSomething()
  })
}

Vue 1.x to 2.0

Making Changes to code

  • Not just find/replace
  • Remove code
  • Add code
  • And much more...

What is a Codemod

Code to rewrite code

  • Partial Automation
  • Human oversight
  • Occasional intervention

What codemods can do?

  • Update source code to fit a team’s coding conventions

  • Make widespread changes when an API is modified

  • Automate large-scale refactoring tasks

  • Easily update your code to take advantage of newer language features

Code Transformations

What is an AST?

A Tree representation of the abstract syntactic structure of source code written in a programming language.

An AST is basically a DOM for your code.

How Compilers create Abstract Syntax Trees?

Scanner

( Lexical Analyzer )

function helloWorld() {
    console.log('hello world');
}

Parser

( Syntax Analyzer )

function helloWorld() {
    console.log('hello world');
}
{
  "type": "Program",
  "start": 0,
  "end": 44,
  "body": [
    {
      "type": "FunctionDeclaration",
      "start": 0,
      "end": 44,
      "id": {
        "type": "Identifier",
        "start": 9,
        "end": 14,
        "name": "hello"
      },
      "expression": false,
      "generator": false,
      "params": [],
      "body": {
        "type": "BlockStatement",
        "start": 17,
        "end": 44,
        "body": [
          {
            "type": "ExpressionStatement",
            "start": 21,
            "end": 42,
            "expression": {
              "type": "CallExpression",
              "start": 21,
              "end": 41,
              "callee": {
                "type": "MemberExpression",
                "start": 21,
                "end": 32,
                "object": {
                  "type": "Identifier",
                  "start": 21,
                  "end": 28,
                  "name": "console"
                },
                "property": {
                  "type": "Identifier",
                  "start": 29,
                  "end": 32,
                  "name": "log"
                },
                "computed": false
              },
              "arguments": [
                {
                  "type": "Literal",
                  "start": 33,
                  "end": 40,
                  "value": "hello",
                  "raw": "'hello'"
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "sourceType": "module"
}

AST

Where is it used?

  • Syntax Highlighting
  • Code Completion
  • Static Analysis (aka ESLint, etc.,)
  • Code Coverage
  • Minification
  • JIT Compilation
  • Source Maps
  • Compiling to JS languages
  • Code Refactoring & Migrations
  • And much more ...

Codemods

jscodeshift

A JavaScript codemod toolkit.

RUNNER

WRAPPER

jscodeshift

RUNNER

WRAPPER

jscodeshift

( CLI )

( recast )

RUNNER

jscodeshift

( CLI )

recast

esprima

ast-types

AST => DOM

jscodeshift  =>   jQuery

recast

const recast = require('recast');
const code = fs.readFileSync('code.js','utf-8');
const ast = recast.parse(code);
const faster = transform(ast);
const output = recast.print(faster).code;
/**
 * This replaces every occurrence of variable "foo".
 */
module.exports = function(fileInfo, api) {
  return api.jscodeshift(fileInfo.source)
    .findVariableDeclarators('foo')
    .renameTo('bar')
    .toSource();
}

jscodeshift

Let's create a Codemod!

Reference Videos

  1. https://www.youtube.com/watch?v=d0pOgY8__JM
  2. https://www.youtube.com/watch?v=1X9p-RUUkak
  3. https://www.youtube.com/watch?v=8r_sXUDoPYo
  4. https://www.youtube.com/watch?v=mkg3NWcloOw&list=LLVxvrINFNKL9kCbakNFjstg&index=9&t=0s
  5. https://frontendmasters.com/courses/linting-asts/introducing-codemods-and-ast/
  6. https://www.youtube.com/watch?v=C06MohLG_3s

Blog Posts

  1. https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb
  2. https://benmccormick.org/2018/06/18/codemod-survival/
  3. https://www.sitepoint.com/getting-started-with-codemods/
  4. https://www.toptal.com/javascript/write-code-to-rewrite-your-code
  5. http://hangaroundtheweb.com/2019/03/codemods-the-new-age-saviors-for-js-developers/

Codemod tooling

  1. https://github.com/facebook/jscodeshift
  2. https://github.com/benjamn/recast
  3. https://github.com/benjamn/ast-types
  4. https://rajasegar.github.io/ast-builder/
  5. https://astexplorer.net
  6. https://github.com/rajasegar/awesome-codemods

Vue codemods

Take aways

#1

The idea is to not break things and to build transformation tools that we can be confident in.

#2

Tool-assisted code modification is set to profoundly transform the way people evolve and maintain very large scale codebases.

Questions?

Thank you

The Art of Crafting Codemods

By Rajasegar Chandiran

The Art of Crafting Codemods

A presentation about Codemods in Vue Hyderabad meetup #2

  • 2,192