Computer, refactor my code!
@naugtur, Grill.js, 2019
Let's start with a case study
## Refactor a large project
- UI at Egnyte - a 10+yo company
- no more rewrites
# (∩°-°)⊃━☆゚.*・。゚
Computer, refactor my code!
![](mr.png)
![](diff1.png)
I could do that with RegExp, if I tried hard...
## What RegExp can't
`if`
## Live demo of React Codemods
[https://github.com/reactjs/react-codemod](https://github.com/reactjs/react-codemod)
```
npx react-codemod class example.jsx
npx react-codemod React-PropTypes-to-prop-types example.jsx
```
## Look behind the curtains
## Abstract Syntax Tree
![](ast.png)
## You already rely on it
- Babel
- Pretier
- ESLint
- Uglify
- Most build-time tooling
### ESLint
#### parse > traverse > complain
### Prettier / Uglify
#### parse > generate
*That's theory, they transform the code too.*
### Babel
#### parse > transform > generate
### Code Mods
#### parse > traverse > transform > generate
## Code Mods?
recast https://github.com/benjamn/recast
`recast.visit()` is hard
## jscodeshift
## the jQuery of AST traversal
https://github.com/facebook/jscodeshift
### Let's learn how to
### (∩°-°)⊃━☆゚.*・。゚
## Resources
[https://ASTexplorer.net](https://astexplorer.net)
- docs: in the repo or hosted on a fork: https://danielruf.github.io/jscodeshift/
- traversing methods: https://github.com/facebook/jscodeshift/blob/master/src/collections/Node.js
- building AST: https://github.com/benjamn/ast-types/blob/master/def/
- use autocomplete for constructors instead of docs
## Recipe
1. get a good example snippet
2. traverse to the right Node
3. check if you don't need to go up for successful replacement
4. build replacement
5. replace!
### Debug your traversal
```js
export default function transformer(file, api) {
const j = api.jscodeshift;
return j(file.source)
.find(j.Identifier, {name: "foo"})
.forEach(path => {
j(path).replaceWith("HERE");
})
.toSource();
}
```
# thx!
@naugtur https://naugtur.pl
![](../../qr-naugtur-training.png)
https://naugtur.pl/training