Large-scale refactoring with codemods
Edd Yerburgh
@eddyerburgh
Refactoring...
import { flatten } from 'lodash'
const flattenedArray = flatten(arr)
arr.flatten()
arr.flat()
import { flatten } from 'lodash' // =>
flatten(arr) // => arr.flat()
Manually
π ββοΈ
codemod -m -d src --extensions js,jsx \
'flatten\((.*)\)' \
'\1.flat()'
flatten([
a,
...flatten([
getC(),
flatten([d, e])
]),
f
])
Using regex
π ββοΈ
import {
flatten,
mergeDeep
} from 'lodash'
JSCodeshift
- CLI tool
- Modify JS by editing AST
AST
Abstract Syntax Tree
Tree representation of the syntactic structure of source code
function sum(a, b) {
return a + b
}
sum(1,2)
Program
Function
Declaration
Expression
Statement
Block
Statement
Return
Statement
{
type: 'Program',
body: [
{
type: 'FunctionDeclaration',
body: [
{
type: 'BlockStatement',
body: [{ type: 'ReturnStatement' }]
}
]
},
{
type: 'ExpressionStatement'
}
]
}
{
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "sum"
},
params: [
{
type: "Identifier",
name: "a"
}
// ..
],
async: false,
generator: false,
body: [
// ..
]
}
{
type: "FunctionDeclaration",
id: {
type: "Identifier",
name: "sum"
},
params: [
{
type: "Identifier",
name: "arg1"
}
// ..
],
async: true,
generator: false,
body: [
// ..
]
}
github.com/estree/estree
Libraries that use ASTs
Source code
AST
Β New AST
Source code
Parse
Transform
JSCodeshift transform
const update = path => {
const arr = path.value.arguments[0]
path.replace(
j.callExpression(
j.memberExpression(
arr,
j.identifier("flat")
),
[]
)
)
}
root
.find(j.CallExpression, {
callee: { name: 'flatten' }
})
.forEach(update)
The transform
// __tests__/flatten.spec.js
const testUtils = require('jscodeshift/dist/testUtils')
const defineTest = testUtils.defineTest
defineTest(__dirname, 'flatten')
Testing
// __testFixtures__/flatten.input.js
import { flatten, someUtil } from "@bbc/utils";
flatten([arr, flatten(createArr())])
// __testFixtures__/flatten.output.js
import { someUtil } from "lodash";
[arr, createArr().flat()].flat()
Uses
- Internal refactoring
- Improve migration path
- Learning ASTs!
Thankyou
Resources
github.com/facebook/jscodeshift
astexplorer.net/
github.com/estree/estree
github.com/benjamn/ast-types
Β
Refactoring with codemods
By Edd Yerburgh
Refactoring with codemods
Perform large-sale refactoring with codemods
- 1,957