Using jscodeshift
Using jscodeshift to make the same code transformations with less boilerplate
In order to create a codemod, we needed to install several dependencies, and boilerplate code for reading, parsing, and writing files.
This is where a more specialized tool like jscodeshift
becomes useful. It's a toolkit for running codemods. It takes care of all the dependencies, and boilerplate for finding, reading, parsing, and writing back to files. It also has some other nice features for working in large codebases, like running a transform in parallel on multiple files, as well as a summary of how many files were changed.
Getting started#
Let's get started by creating a new directory and installing the dependencies.
# Create a new directory for the transform script
mkdir jscodeshift
# Change into the new jscodeshift directory
cd jscodeshift
# Initialize a new package.json file
npm init -y
# Add the necessary dependencies
npm i jscodeshift prettier
npm i -D @types/jscodeshift @types/prettier
The only required dependency is jscodeshift
. Prettier was installed again to consistently format code, but that's a "nice to have." The types were also installed since we're using TypeScript.
Creating the transform#
Next, create a new transform.ts
file with the transform boilerplate to work with jscodeshift.
import { Transform } from "jscodeshift";
// Define a transform function that adheres to the jscodeshift API.
// The function accepts three arguments:
// - fileInfo: info about the current file
// - api: jscodeshift library and helper functions
// - options: all options passed to the runner via the CLI
const transform: Transform = (fileInfo, api) => {
// Alias the jscodeshift API for ease of use.
const j = api.jscodeshift;
// Convert the file source into an AST.
const root = j(fileInfo.source);
// TODO: make desired transformations.
// Convert the AST back to a string. In this case,
// nothing changed so `null` could be returned and
// jscodeshift wouldn't do anything.
return root.toSource();
};
// The transform function then needs to be the default export.
// This will then be executed by jscodeshift for every file.
export default transform;
This transform function follows the jscodeshift API, which is a function that is the default export that accepts three arguments. It also supports transforms written in TypeScript with no additional setup (notice we didn't have to install anything except jscodeshift and its types).
Now, this can be executed with the jscodeshift CLI. It has a number of options. The only required option is the path to the files to run the transform on.
npx jscodeshift --transform ./transform.ts ../flash-cards/src/
The Flash app is a basic setup, so the defaults work well.
The default jscodeshift parser is babel
. The other options are: babylon
, flow
, ts
, or tsx
. This can be somewhat confusing, because babylon
was the previous name of @babel/parser
.
This page is a preview of Practical Abstract Syntax Trees