react-monaco-editor
Version:
Monaco Editor for React
319 lines (276 loc) • 16.4 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Home</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Home</h1>
<h3> </h3>
<section>
<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.
It provides:</p>
<ul>
<li>A runner, which executes the provided transform for each file passed to it.
It also outputs a summary of how many files have (not) been transformed.</li>
<li>A wrapper around <a href="https://github.com/benjamn/recast">recast</a>, providing a different API. Recast is an
AST-to-AST transform tool and also tries to preserve the style of original code
as much as possible.</li>
</ul>
<h2>Install</h2><p>Get jscodeshift from <a href="https://www.npmjs.com/">npm</a>:</p>
<pre class="prettyprint source"><code>$ npm install -g jscodeshift</code></pre><p>This will install the runner as <code>jscodeshift</code>.</p>
<h2>Usage (CLI)</h2><p>The CLI provides the following options:</p>
<pre class="prettyprint source lang-text"><code>$ jscodeshift --help
Usage: jscodeshift <path>... [options]
path Files or directory to transform
Options:
-t FILE, --transform FILE Path to the transform file. Can be either a local path or url [./transform.js]
-c, --cpus (all by default) Determines the number of processes started.
-v, --verbose Show more information about the transform process [0]
-d, --dry Dry run (no changes are made to files)
-p, --print Print output, useful for development
--babel Apply Babel to transform files [true]
--extensions File extensions the transform file should be applied to [js]
--ignore-pattern Ignore files that match a provided glob expression
--ignore-config FILE Ignore files if they match patterns sourced from a configuration file (e.g., a .gitignore)
--run-in-band Run serially in the current process [false]
-s, --silent No output [false]
--parser The parser to use for parsing your source files (babel | babylon | flow) [babel]
--version print version and exit</code></pre><p>This passes the source of all passed through the transform module specified
with <code>-t</code> or <code>--transform</code> (defaults to <code>transform.js</code> in the current
directory). The next section explains the structure of the transform module.</p>
<h2>Transform module</h2><p>The transform is simply a module that exports a function of the form:</p>
<pre class="prettyprint source lang-js"><code>module.exports = function(fileInfo, api, options) {
// transform `fileInfo.source` here
// ...
// return changed source
return source;
};</code></pre><h3>Arguments</h3><h4><code>fileInfo</code></h4><p>Holds information about the currently processed file.</p>
<table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>path</td>
<td>File path</td>
</tr>
<tr>
<td>source</td>
<td>File content</td>
</tr>
</tbody>
</table>
<h4><code>api</code></h4><p>This object exposes the <code>jscodeshift</code> library and helper functions from the
runner.</p>
<table>
<thead>
<tr>
<th>Property</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>jscodeshift</td>
<td>A reference to the jscodeshift library</td>
</tr>
<tr>
<td>stats</td>
<td>A function to collect statistics during <code>--dry</code> runs</td>
</tr>
</tbody>
</table>
<p><code>jscodeshift</code> is a reference to the wrapper around recast and provides a
jQuery-like API to navigate and transform the AST. Here is a quick example,
a more detailed description can be found below.</p>
<pre class="prettyprint source lang-js"><code>/**
* This replaces every occurence of variable "foo".
*/
module.exports = function(fileInfo, api) {
return api.jscodeshift(fileInfo.source)
.findVariableDeclarators('foo')
.renameTo('bar')
.toSource();
}</code></pre><p><strong>Note:</strong> This api is exposed for convenience, but you don't have to use it.
You can use any tool to modify the source.</p>
<p><code>stats</code> is a function that only works when the <code>--dry</code> options is set. It accepts
a string, and will simply count how often it was called with that value.</p>
<p>At the end, the CLI will report those values. This can be useful while
developing the transform, e.g. to find out how often a certain construct
appears in the source(s).</p>
<h4><code>options</code></h4><p>Contains all options that have been passed to runner. This allows you to pass
additional options to the transform. For example, if the CLI is called with</p>
<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
command line options.</p>
<h3>Return value</h3><p>The return value of the function determines the status of the transformation:</p>
<ul>
<li>If a string is returned and it is different from passed source, the
transform is considered to be successful.</li>
<li>If a string is returned but it's the same as the source, the transform
is considered to be unsuccessful.</li>
<li>If nothing is returned, the file is not supposed to be transformed (which is
ok).</li>
</ul>
<p>The CLI provides a summary of the transformation at the end. You can get more
detailed information by setting the <code>-v</code> option to <code>1</code> or <code>2</code>.</p>
<p>You can collect even more stats via the <code>stats</code> function as explained above.</p>
<h3>Parser</h3><p>The transform can let jscodeshift know with which parser to parse the source
files (and features like templates).</p>
<p>To do that, the transform module can export <code>parser</code>, which can either be one
of the strings <code>"babel"</code>, <code>"babylon"</code>, or <code>"flow"</code>, or it can be a parser
object that is compatible with with recast.</p>
<p>For example:</p>
<pre class="prettyprint source lang-js"><code>module.exports.parser = 'flow'; // use the flow parser
// or
module.exports.parser = {
parse: function(source) {
// return estree compatible AST
},
};</code></pre><h3>Example output</h3><pre class="prettyprint source lang-text"><code>$ jscodeshift -t myTransform.js src
Processing 10 files...
Spawning 2 workers with 5 files each...
All workers done.
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>.
In order to properly use the jscodeshift API, one has to understand the basic
building blocks of recast (and ASTs) as well.</p>
<h3>Core Concepts</h3><h4>AST nodes</h4><p>An AST node is a plain JavaScript object with a specific set of fields, in
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
is via their <code>type</code>.</p>
<p>For example, string literals are represented via <code>Literal</code> nodes, which
have the structure</p>
<pre class="prettyprint source lang-js"><code>// "foo"
{
type: 'Literal',
value: 'foo',
raw: '"foo"'
}</code></pre><p>It's OK to not know the structure of every AST node type.
The <a href="http://astexplorer.net/">(esprima) AST explorer</a> is an online tool to inspect the AST
for a given piece of JS code.</p>
<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
the AST, access node fields and build new nodes. ast-types wraps every AST node
into a <em>path object</em>. Paths contain meta-information and helper methods to
process AST nodes.</p>
<p>For example, the child-parent relationship between two nodes is not explicitly
defined. Given a plain AST node, it is not possible to traverse the tree <em>up</em>.
Given a path object however, the parent can be traversed to via <code>path.parent</code>.</p>
<p>For more information about the path object API, please have a look at
<a href="https://github.com/benjamn/ast-types">ast-types</a>.</p>
<h4>Builders</h4><p>To make creating AST nodes a bit simpler and "safer", ast-types defines a couple
of <em>builder methods</em>, which are also exposed on <code>jscodeshift</code>.</p>
<p>For example, the following creates an AST equivalent to <code>foo(bar)</code>:</p>
<pre class="prettyprint source lang-js"><code>// inside a module transform
var j = jscodeshift;
// foo(bar);
var ast = j.callExpression(
j.identifier('foo'),
[j.identifier('bar')]
);</code></pre><p>The signature of each builder function is best learned by having a look at the
<a href="https://github.com/benjamn/ast-types/blob/master/def/">definition files</a>.</p>
<h3>Collections and Traversal</h3><p>In order to transform the AST, you have to traverse it and find the nodes that
need to be changed. jscodeshift is built around the idea of <strong>collections</strong> of
paths and thus provides a different way of processing an AST than recast or
ast-types.</p>
<p>A collection has methods to process the nodes inside a collection, often
resulting in a new collection. This results in a fluent interface, which can
make the transform more readable.</p>
<p>Collections are "typed" which means that the type of a collection is the
"lowest" type all AST nodes in the collection have in common. That means you
cannot call a method for a <code>FunctionExpression</code> collection on an <code>Identifier</code>
collection.</p>
<p>Here is an example of how one would find/traverse all <code>Identifier</code> nodes with
jscodeshift and with recast:</p>
<pre class="prettyprint source lang-js"><code>// recast
var ast = recast.parse(src);
recast.visit(ast, {
visitIdentifier: function(path) {
// do something with path
return false;
}
});
// jscodeshift
jscodeshift(src)
.find(jscodeshift.Identifier)
.forEach(function(path) {
// do something with path
});</code></pre><p>To learn about the provided methods, have a look at the
<a href="src/Collection.js">Collection.js</a> and its <a href="src/collections/">extensions</a>.</p>
<h3>Extensibility</h3><p>jscodeshift provides an API to extend collections. By moving common operators
into helper functions (which can be stored separately in other modules), a
transform can be made more readable.</p>
<p>There are two types of extensions: generic extensions and type-specific
extensions. <strong>Generic extensions</strong> are applicable to all collections. As such,
they typically don't access specific node data, but rather traverse the AST from
the nodes in the collection. <strong>Type-specific</strong> extensions work only on specific
node types and are not callable on differently typed collections.</p>
<h4>Examples</h4><pre class="prettyprint source lang-js"><code>// Adding a method to all Identifiers
jscodeshift.registerMethods({
logNames: function() {
return this.forEach(function(path) {
console.log(path.node.name);
});
}
}, jscodeshift.Identifier);
// Adding a method to all collections
jscodeshift.registerMethods({
findIdentifiers: function() {
return this.find(jscodeshift.Identifier);
}
});
jscodeshift(ast).findIdentifiers().logNames();
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>"</code>).
This can be done by passing config options to <a href="https://github.com/benjamn/recast">recast</a>.</p>
<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
jscodeshift as second argument:</p>
<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>
<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>
<ul>
<li>The test is located in a subdirectory under the directory the transform itself is located in (eg. <code>__tests__</code>)</li>
<li>Test fixtures are located in a <code>__testfixtures__</code> directory</li>
</ul>
<p>This results in a directory structure like this:</p>
<pre class="prettyprint source"><code>/MyTransform.js
/__tests__/MyTransform-test.js
/__testfixtures__/MyTransform.input.js
/__testfixtures__/MyTransform.output.js</code></pre><p>To define a test, use <code>defineTest</code> from the <code>testUtils</code> module:</p>
<pre class="prettyprint source lang-js"><code>jest.autoMockOff();
const defineTest = require('jscodeshift/dist/testUtils').defineTest;
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>
<pre class="prettyprint source lang-js"><code>defineTest(__dirname, 'MyTransform', null, 'FirstFixture');
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>
<p>A simple example is bundled in the <a href="sample">sample directory</a>.</p>
<h3>Example Codemods</h3><ul>
<li><a href="https://github.com/reactjs/react-codemod">react-codemod</a> - React codemod scripts to update React APIs.</li>
<li><a href="https://github.com/cpojer/js-codemod/">js-codemod</a> - Codemod scripts to transform code to next generation JS.</li>
<li><a href="https://github.com/jhgg/js-transforms">js-transforms</a> - Some documented codemod experiments to help you learn.</li>
</ul>
<h3>Recipes</h3><ul>
<li><a href="recipes/retain-first-comment.md">Retain leading comment(s) in file when replacing/removing first statement</a></li>
</ul>
<h3>Support</h3><ul>
<li>Discord - <a href="https://discordapp.com/channels/102860784329052160/103748721107292160">#codemod</a> on <a href="http://www.reactiflux.com/">Reactiflux</a></li>
</ul></article>
</section>
</div>
<nav>
<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>
</nav>
<br class="clear">
<footer>
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)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>