index.html 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Home</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Home</h1>
  17. <h3> </h3>
  18. <section>
  19. <article><h1>jscodeshift <a href="https://travis-ci.org/facebook/jscodeshift"><img src="https://travis-ci.org/facebook/jscodeshift.svg?branch=master" alt="Build Status"></a></h1><p>jscodeshift is a toolkit for running codemods over multiple JS files.
  20. It provides:</p>
  21. <ul>
  22. <li>A runner, which executes the provided transform for each file passed to it.
  23. It also outputs a summary of how many files have (not) been transformed.</li>
  24. <li>A wrapper around <a href="https://github.com/benjamn/recast">recast</a>, providing a different API. Recast is an
  25. AST-to-AST transform tool and also tries to preserve the style of original code
  26. as much as possible.</li>
  27. </ul>
  28. <h2>Install</h2><p>Get jscodeshift from <a href="https://www.npmjs.com/">npm</a>:</p>
  29. <pre class="prettyprint source"><code>$ npm install -g jscodeshift</code></pre><p>This will install the runner as <code>jscodeshift</code>.</p>
  30. <h2>Usage (CLI)</h2><p>The CLI provides the following options:</p>
  31. <pre class="prettyprint source lang-text"><code>$ jscodeshift --help
  32. Usage: jscodeshift &lt;path>... [options]
  33. path Files or directory to transform
  34. Options:
  35. -t FILE, --transform FILE Path to the transform file. Can be either a local path or url [./transform.js]
  36. -c, --cpus (all by default) Determines the number of processes started.
  37. -v, --verbose Show more information about the transform process [0]
  38. -d, --dry Dry run (no changes are made to files)
  39. -p, --print Print output, useful for development
  40. --babel Apply Babel to transform files [true]
  41. --extensions File extensions the transform file should be applied to [js]
  42. --ignore-pattern Ignore files that match a provided glob expression
  43. --ignore-config FILE Ignore files if they match patterns sourced from a configuration file (e.g., a .gitignore)
  44. --run-in-band Run serially in the current process [false]
  45. -s, --silent No output [false]
  46. --parser The parser to use for parsing your source files (babel | babylon | flow) [babel]
  47. --version print version and exit</code></pre><p>This passes the source of all passed through the transform module specified
  48. with <code>-t</code> or <code>--transform</code> (defaults to <code>transform.js</code> in the current
  49. directory). The next section explains the structure of the transform module.</p>
  50. <h2>Transform module</h2><p>The transform is simply a module that exports a function of the form:</p>
  51. <pre class="prettyprint source lang-js"><code>module.exports = function(fileInfo, api, options) {
  52. // transform `fileInfo.source` here
  53. // ...
  54. // return changed source
  55. return source;
  56. };</code></pre><h3>Arguments</h3><h4><code>fileInfo</code></h4><p>Holds information about the currently processed file.</p>
  57. <table>
  58. <thead>
  59. <tr>
  60. <th>Property</th>
  61. <th>Description</th>
  62. </tr>
  63. </thead>
  64. <tbody>
  65. <tr>
  66. <td>path</td>
  67. <td>File path</td>
  68. </tr>
  69. <tr>
  70. <td>source</td>
  71. <td>File content</td>
  72. </tr>
  73. </tbody>
  74. </table>
  75. <h4><code>api</code></h4><p>This object exposes the <code>jscodeshift</code> library and helper functions from the
  76. runner.</p>
  77. <table>
  78. <thead>
  79. <tr>
  80. <th>Property</th>
  81. <th>Description</th>
  82. </tr>
  83. </thead>
  84. <tbody>
  85. <tr>
  86. <td>jscodeshift</td>
  87. <td>A reference to the jscodeshift library</td>
  88. </tr>
  89. <tr>
  90. <td>stats</td>
  91. <td>A function to collect statistics during <code>--dry</code> runs</td>
  92. </tr>
  93. </tbody>
  94. </table>
  95. <p><code>jscodeshift</code> is a reference to the wrapper around recast and provides a
  96. jQuery-like API to navigate and transform the AST. Here is a quick example,
  97. a more detailed description can be found below.</p>
  98. <pre class="prettyprint source lang-js"><code>/**
  99. * This replaces every occurence of variable &quot;foo&quot;.
  100. */
  101. module.exports = function(fileInfo, api) {
  102. return api.jscodeshift(fileInfo.source)
  103. .findVariableDeclarators('foo')
  104. .renameTo('bar')
  105. .toSource();
  106. }</code></pre><p><strong>Note:</strong> This api is exposed for convenience, but you don't have to use it.
  107. You can use any tool to modify the source.</p>
  108. <p><code>stats</code> is a function that only works when the <code>--dry</code> options is set. It accepts
  109. a string, and will simply count how often it was called with that value.</p>
  110. <p>At the end, the CLI will report those values. This can be useful while
  111. developing the transform, e.g. to find out how often a certain construct
  112. appears in the source(s).</p>
  113. <h4><code>options</code></h4><p>Contains all options that have been passed to runner. This allows you to pass
  114. additional options to the transform. For example, if the CLI is called with</p>
  115. <pre class="prettyprint source"><code>$ jscodeshift -t myTransforms fileA fileB --foo=bar</code></pre><p><code>options</code> would contain <code>{foo: 'bar'}</code>. jscodeshift uses <a href="https://www.npmjs.com/package/nomnom">nomnom</a> to parse
  116. command line options.</p>
  117. <h3>Return value</h3><p>The return value of the function determines the status of the transformation:</p>
  118. <ul>
  119. <li>If a string is returned and it is different from passed source, the
  120. transform is considered to be successful.</li>
  121. <li>If a string is returned but it's the same as the source, the transform
  122. is considered to be unsuccessful.</li>
  123. <li>If nothing is returned, the file is not supposed to be transformed (which is
  124. ok).</li>
  125. </ul>
  126. <p>The CLI provides a summary of the transformation at the end. You can get more
  127. detailed information by setting the <code>-v</code> option to <code>1</code> or <code>2</code>.</p>
  128. <p>You can collect even more stats via the <code>stats</code> function as explained above.</p>
  129. <h3>Parser</h3><p>The transform can let jscodeshift know with which parser to parse the source
  130. files (and features like templates).</p>
  131. <p>To do that, the transform module can export <code>parser</code>, which can either be one
  132. of the strings <code>&quot;babel&quot;</code>, <code>&quot;babylon&quot;</code>, or <code>&quot;flow&quot;</code>, or it can be a parser
  133. object that is compatible with with recast.</p>
  134. <p>For example:</p>
  135. <pre class="prettyprint source lang-js"><code>module.exports.parser = 'flow'; // use the flow parser
  136. // or
  137. module.exports.parser = {
  138. parse: function(source) {
  139. // return estree compatible AST
  140. },
  141. };</code></pre><h3>Example output</h3><pre class="prettyprint source lang-text"><code>$ jscodeshift -t myTransform.js src
  142. Processing 10 files...
  143. Spawning 2 workers with 5 files each...
  144. All workers done.
  145. Results: 0 errors 2 unmodified 3 skipped 5 ok</code></pre><h2>The jscodeshift API</h2><p>As already mentioned, jscodeshift also provides a wrapper around <a href="https://github.com/benjamn/recast">recast</a>.
  146. In order to properly use the jscodeshift API, one has to understand the basic
  147. building blocks of recast (and ASTs) as well.</p>
  148. <h3>Core Concepts</h3><h4>AST nodes</h4><p>An AST node is a plain JavaScript object with a specific set of fields, in
  149. accordance with the <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API">Mozilla Parser API</a>. The primary way to identify nodes
  150. is via their <code>type</code>.</p>
  151. <p>For example, string literals are represented via <code>Literal</code> nodes, which
  152. have the structure</p>
  153. <pre class="prettyprint source lang-js"><code>// &quot;foo&quot;
  154. {
  155. type: 'Literal',
  156. value: 'foo',
  157. raw: '&quot;foo&quot;'
  158. }</code></pre><p>It's OK to not know the structure of every AST node type.
  159. The <a href="http://astexplorer.net/">(esprima) AST explorer</a> is an online tool to inspect the AST
  160. for a given piece of JS code.</p>
  161. <h4>Path objects</h4><p>Recast itself relies heavily on <a href="https://github.com/benjamn/ast-types">ast-types</a> which defines methods to traverse
  162. the AST, access node fields and build new nodes. ast-types wraps every AST node
  163. into a <em>path object</em>. Paths contain meta-information and helper methods to
  164. process AST nodes.</p>
  165. <p>For example, the child-parent relationship between two nodes is not explicitly
  166. defined. Given a plain AST node, it is not possible to traverse the tree <em>up</em>.
  167. Given a path object however, the parent can be traversed to via <code>path.parent</code>.</p>
  168. <p>For more information about the path object API, please have a look at
  169. <a href="https://github.com/benjamn/ast-types">ast-types</a>.</p>
  170. <h4>Builders</h4><p>To make creating AST nodes a bit simpler and &quot;safer&quot;, ast-types defines a couple
  171. of <em>builder methods</em>, which are also exposed on <code>jscodeshift</code>.</p>
  172. <p>For example, the following creates an AST equivalent to <code>foo(bar)</code>:</p>
  173. <pre class="prettyprint source lang-js"><code>// inside a module transform
  174. var j = jscodeshift;
  175. // foo(bar);
  176. var ast = j.callExpression(
  177. j.identifier('foo'),
  178. [j.identifier('bar')]
  179. );</code></pre><p>The signature of each builder function is best learned by having a look at the
  180. <a href="https://github.com/benjamn/ast-types/blob/master/def/">definition files</a>.</p>
  181. <h3>Collections and Traversal</h3><p>In order to transform the AST, you have to traverse it and find the nodes that
  182. need to be changed. jscodeshift is built around the idea of <strong>collections</strong> of
  183. paths and thus provides a different way of processing an AST than recast or
  184. ast-types.</p>
  185. <p>A collection has methods to process the nodes inside a collection, often
  186. resulting in a new collection. This results in a fluent interface, which can
  187. make the transform more readable.</p>
  188. <p>Collections are &quot;typed&quot; which means that the type of a collection is the
  189. &quot;lowest&quot; type all AST nodes in the collection have in common. That means you
  190. cannot call a method for a <code>FunctionExpression</code> collection on an <code>Identifier</code>
  191. collection.</p>
  192. <p>Here is an example of how one would find/traverse all <code>Identifier</code> nodes with
  193. jscodeshift and with recast:</p>
  194. <pre class="prettyprint source lang-js"><code>// recast
  195. var ast = recast.parse(src);
  196. recast.visit(ast, {
  197. visitIdentifier: function(path) {
  198. // do something with path
  199. return false;
  200. }
  201. });
  202. // jscodeshift
  203. jscodeshift(src)
  204. .find(jscodeshift.Identifier)
  205. .forEach(function(path) {
  206. // do something with path
  207. });</code></pre><p>To learn about the provided methods, have a look at the
  208. <a href="src/Collection.js">Collection.js</a> and its <a href="src/collections/">extensions</a>.</p>
  209. <h3>Extensibility</h3><p>jscodeshift provides an API to extend collections. By moving common operators
  210. into helper functions (which can be stored separately in other modules), a
  211. transform can be made more readable.</p>
  212. <p>There are two types of extensions: generic extensions and type-specific
  213. extensions. <strong>Generic extensions</strong> are applicable to all collections. As such,
  214. they typically don't access specific node data, but rather traverse the AST from
  215. the nodes in the collection. <strong>Type-specific</strong> extensions work only on specific
  216. node types and are not callable on differently typed collections.</p>
  217. <h4>Examples</h4><pre class="prettyprint source lang-js"><code>// Adding a method to all Identifiers
  218. jscodeshift.registerMethods({
  219. logNames: function() {
  220. return this.forEach(function(path) {
  221. console.log(path.node.name);
  222. });
  223. }
  224. }, jscodeshift.Identifier);
  225. // Adding a method to all collections
  226. jscodeshift.registerMethods({
  227. findIdentifiers: function() {
  228. return this.find(jscodeshift.Identifier);
  229. }
  230. });
  231. jscodeshift(ast).findIdentifiers().logNames();
  232. jscodeshift(ast).logNames(); // error, unless `ast` only consists of Identifier nodes</code></pre><h3>Passing options to <a href="https://github.com/benjamn/recast">recast</a></h3><p>You may want to change some of the output settings (like setting <code>'</code> instead of <code>&quot;</code>).
  233. This can be done by passing config options to <a href="https://github.com/benjamn/recast">recast</a>.</p>
  234. <pre class="prettyprint source lang-js"><code>.toSource({quote: 'single'}); // sets strings to use single quotes in transformed code.</code></pre><p>You can also pass options to recast's <code>parse</code> method by passing an object to
  235. jscodeshift as second argument:</p>
  236. <pre class="prettyprint source lang-js"><code>jscodeshift(source, {...})</code></pre><p>More on config options <a href="https://github.com/benjamn/recast/blob/52a7ec3eaaa37e78436841ed8afc948033a86252/lib/options.js#L61">here</a></p>
  237. <h3>Unit Testing</h3><p>jscodeshift comes with a simple utility to allow easy unit testing with <a href="https://facebook.github.io/jest/">Jest</a>, without having to write a lot of boilerplate code. This utility makes some assumptions in order to reduce the amount of configuration required:</p>
  238. <ul>
  239. <li>The test is located in a subdirectory under the directory the transform itself is located in (eg. <code>__tests__</code>)</li>
  240. <li>Test fixtures are located in a <code>__testfixtures__</code> directory</li>
  241. </ul>
  242. <p>This results in a directory structure like this:</p>
  243. <pre class="prettyprint source"><code>/MyTransform.js
  244. /__tests__/MyTransform-test.js
  245. /__testfixtures__/MyTransform.input.js
  246. /__testfixtures__/MyTransform.output.js</code></pre><p>To define a test, use <code>defineTest</code> from the <code>testUtils</code> module:</p>
  247. <pre class="prettyprint source lang-js"><code>jest.autoMockOff();
  248. const defineTest = require('jscodeshift/dist/testUtils').defineTest;
  249. defineTest(__dirname, 'MyTransform');</code></pre><p>An alternate fixture filename can be provided as the fourth argument to <code>defineTest</code>. This also means that multiple test fixtures can be provided:</p>
  250. <pre class="prettyprint source lang-js"><code>defineTest(__dirname, 'MyTransform', null, 'FirstFixture');
  251. defineTest(__dirname, 'MyTransform', null, 'SecondFixture');</code></pre><p>This will run two tests: One for <code>__testfixtures__/FirstFixture.input.js</code> and one for <code>__testfixtures__/SecondFixture.input.js</code></p>
  252. <p>A simple example is bundled in the <a href="sample">sample directory</a>.</p>
  253. <h3>Example Codemods</h3><ul>
  254. <li><a href="https://github.com/reactjs/react-codemod">react-codemod</a> - React codemod scripts to update React APIs.</li>
  255. <li><a href="https://github.com/cpojer/js-codemod/">js-codemod</a> - Codemod scripts to transform code to next generation JS.</li>
  256. <li><a href="https://github.com/jhgg/js-transforms">js-transforms</a> - Some documented codemod experiments to help you learn.</li>
  257. </ul>
  258. <h3>Recipes</h3><ul>
  259. <li><a href="recipes/retain-first-comment.md">Retain leading comment(s) in file when replacing/removing first statement</a></li>
  260. </ul>
  261. <h3>Support</h3><ul>
  262. <li>Discord - <a href="https://discordapp.com/channels/102860784329052160/103748721107292160">#codemod</a> on <a href="http://www.reactiflux.com/">Reactiflux</a></li>
  263. </ul></article>
  264. </section>
  265. </div>
  266. <nav>
  267. <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-jscodeshift.html">jscodeshift</a></li></ul><h3>Externals</h3><ul><li><a href="external-astTypes.html">astTypes</a></li></ul><h3>Classes</h3><ul><li><a href="Collection.html">Collection</a></li></ul><h3>Mixins</h3><ul><li><a href="globalMethods.html">globalMethods</a></li><li><a href="mutationMethods.html">mutationMethods</a></li><li><a href="transformMethods.html">transformMethods</a></li><li><a href="traversalMethods.html">traversalMethods</a></li></ul><h3>Global</h3><ul><li><a href="global.html#registerMethods">registerMethods</a></li></ul>
  268. </nav>
  269. <br class="clear">
  270. <footer>
  271. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.1</a> on Wed Sep 21 2016 16:53:09 GMT-0400 (EDT)
  272. </footer>
  273. <script> prettyPrint(); </script>
  274. <script src="scripts/linenumber.js"> </script>
  275. </body>
  276. </html>