Write Code to Rewrite Your Code: jscodeshift
datasciencecentral.com
datasciencecentral.com
For instance changing all calls to "calc" from taking two arguments to taking one object literal instead (eg. `calc(1, 2)` to `calc({from: 1, to: 2})`, is as easy as:
$ grasp -r -e 'calc($a, $b)' -R 'calc({from: {{a}}, to: {{b}}})' file.js
(Where the two arguments to "calc" could be any arbitrary nested expressions, which could not be safely handled by a regular expression)Yes, this is great! I'd love to be able to integrate graspjs with jscodeshift somehow. Ideally there would be multiple possible ways to find the nodes you want to change (pattern matching, tree traversal, etc), and multiple ways to specify how to replace them (e.g. a template like in your example vs a function where you can do anything you want).
Simple transforms should definitely be possible with little "code" like in your example and we certainly have to improve jscodeshift in this regard.
export const sum = (a, b) => { re
And when I copy and paste the line the rest of it is copied to the clipboard.[1]: https://www.toptal.com/javascript/write-code-to-rewrite-your...
Maybe it's a cavil, but I'm not overjoyed at the thought of doing global search and destroy on my codebases with a tool I heard about on a website that messes up something that basic.
On the other hand, apparently jscodeshift itself comes from Facebook [1], and they tend to do good work (on a technical level, at least); perhaps it'd be worthwhile to change the HN link to point to that repo, not least because the code samples aren't munged to unintelligibility there.
When I am writing jscodeshift scripts, it's a constant cycle of git checkout -> run codemod -> git checkout.
Nobody is saying you need to commit the changes: review them by hand if you will. I've never had a problem with jscodeshift itself. Publicly available transform scripts though are quite hit or miss.
For instance: import statements vs. require expressions - these need to be handled with different AST matchers. Import statements themselves have 3 different varieties of specifiers (default, named, "all") which must be accounted for. A require expression may or may not involve destructuring, it may or may not use const or let over var (each of which need to be handled explicitly, etc.)
As far as failure mode: scripts generally just won't match or work, or they might replace all of your consts with vars, etc - they can be very codebase specific depending on the complexity of the script.
Nice examples are stuff like decorators or the :: bind operator.
As for formatting, there are some options to influence the pretty printer, but not a lot [1]. It will infer things like indentation from the existing source code. I'm not sure right now how it handles long lines.
Whenever we run into issues with the printer, we just create a PR to fix it. Getting automatic code formatting right is apparently quite hard. There are dedicated tools for this, such as https://github.com/millermedeiros/esformatter .
[1]: https://github.com/benjamn/recast/blob/master/lib/options.js