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(); } ```
## DEMO!
# thx! @naugtur https://naugtur.pl ![](../../qr-naugtur-training.png) https://naugtur.pl/training