Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
react-codemod
Advanced tools
This repository contains a collection of codemod scripts for use with JSCodeshift that help update React APIs.
npx react-codemod <transform> <path> [...options]
transform
- name of transform, see available transforms below.path
- files or directory to transform--dry
option for a dry-run and use --print
to print the output for comparisonThis will start an interactive wizard, and then run the specified transform.
create-element-to-jsx
Converts calls to React.createElement
into JSX elements.
npx react-codemod create-element-to-jsx <path>
error-boundaries
Renames the experimental unstable_handleError
lifecycle hook to componentDidCatch
.
npx react-codemod error-boundaries <path>
findDOMNode
Updates this.getDOMNode()
or this.refs.foo.getDOMNode()
calls inside of
React.createClass
components to React.findDOMNode(foo)
. Note that it will
only look at code inside of React.createClass
calls and only update calls on
the component instance or its refs. You can use this script to update most calls
to getDOMNode
and then manually go through the remaining calls.
npx react-codemod findDOMNode <path>
manual-bind-to-arrow
Converts manual function bindings in a class (e.g., this.f = this.f.bind(this)
) to arrow property initializer functions (e.g., f = () => {}
).
npx react-codemod manual-bind-to-arrow <path>
pure-component
Converts ES6 classes that only have a render method, only have safe properties (statics and props), and do not have refs to Functional Components.
The wizard will ask for 2 options -
function
by default.npx react-codemod pure-component <path>
pure-render-mixin
Removes PureRenderMixin
and inlines shouldComponentUpdate
so that the ES2015
class transform can pick up the React component and turn it into an ES2015
class. NOTE: This currently only works if you are using the master version
(>0.13.1) of React as it is using React.addons.shallowCompare
npx react-codemod pure-render-mixin <path>
mixin-name
, and look for it
instead of PureRenderMixin
. Note that it is not possible to use a
namespaced name for the mixin. mixins: [React.addons.PureRenderMixin]
will
not currently work.React-PropTypes-to-prop-types
Replaces React.PropTypes
references with prop-types
and adds the appropriate import
or require
statement. This codemod is intended for React 15.5+.
npx react-codemod React-PropTypes-to-prop-types <path>
prop-types
NPM package.rename-unsafe-lifecycles
Adds UNSAFE_
prefix for deprecated lifecycle hooks. (For more information about this codemod, see React RFC #6)
npx react-codemod rename-unsafe-lifecycles <path>
react-to-react-dom
Updates code for the split of the react
and react-dom
packages (e.g.,
React.render
to ReactDOM.render
). It looks for require('react')
and
replaces the appropriate property accesses using require('react-dom')
. It does
not support ES6 modules or other non-CommonJS systems. We recommend performing
the findDOMNode
conversion first.
npx react-codemod react-to-react-dom <path>
codemod.py -m -d src --extensions js '(var React\s*=\s*require\(.react.\);)\n\n(\s*var ReactDOM)' '\1\n\2'
using
https://github.com/facebook/codemod.React-DOM-to-react-dom-factories
Converts calls like React.DOM.div(...)
to React.createElement('div', ...)
.
npx react-codemod React-DOM-to-react-dom-factories <path>
ReactNative-View-propTypes
Replaces View.propTypes
references with ViewPropTypes
and adds the appropriate import
or require
statement. This codemod is intended for ReactNative 44+.
npx react-codemod ReactNative-View-propTypes <path>
sort-comp
Reorders React component methods to match the ESLint react/sort-comp rule. (Defaults to ordering of the Airbnb style guide.
npx react-codemod sort-comp <path>
update-react-imports
As of Babel 7.9.0, when using runtime: automatic
in @babel/preset-react
or @babel/plugin-transform-react-jsx
, you will not need to explicitly import React for compiling jsx. This codemod removes the redundant import statements. It also converts default imports (import React from 'react'
) to named imports (e.g. import { useState } from 'react'
).
The wizard will ask for 1 option -
import * as React
will also be converted. By default, it's false, so only default imports (import React
) are converted.npx react-codemod update-react-imports <path>
createClass
call to an ES6 class component when:options['pure-component']
is true, the mixins
property is an array and it only contains pure render mixin (the specific module name can be specified using options['mixin-module-name']
, which defaults to react-addons-pure-render-mixin
)isMounted
, getDOMNode
, replaceProps
, replaceState
or setProps
it will skip the componentthis.getInitialState()
and/or this.getDefaultProps()
since an ES6 class component will no longer have these methodsarguments
in methods since arrow functions don't have arguments
. Also please notice that arguments
should be very carefully used and it's generally better to switch to spread (...args
) insteadgetInitialState()
. Specifically if you have variable declarations like var props = ...
and the right hand side is not this.props
then we can't inline the state initialization in the constructor
due to variable shadowing issuesfoo: getStuff()
) in the class specvar A = React.createClass(spec)
with class A extends React.Component {spec}
. If a component uses pure render mixin and passes the mixins test (as described above), it will extend React.PureComponent
instead
- Remove the require
/import
statement that imports pure render mixin when it's no longer being referencedstatics
plus the few special cased statics like childContextTypes
, contextTypes
, displayName
, getDefaultProps()
, and propTypes
and transform them to static
properties (static propTypes = {...};
)
- If getDefaultProps()
is simple (i.e. it only contains a return statement that returns something) it will be converted to a simple assignment (static defaultProps = ...;
). Otherwise an IIFE (immediately-invoked function expression) will be created (static defaultProps = function() { ... }();
). Note that this means that the function will be executed only a single time per app-lifetime. In practice this hasn't caused any issues — getDefaultProps
should not contain any side-effectsgetInitialState()
- If there's no getInitialState()
or the getInitialState()
function is simple (i.e., it only contains a return statement that returns something) then we don't need a constructor; state
will be lifted to a property initializer (state = ...;
)
return
contains references to this
other than this.props
and/or this.context
, we can't be sure about what you'll need from this
. We need to ensure that our property initializers' evaluation order is safe, so we defer state
's initialization by moving it all the way down until all other property initializers have been initialized
- If getInitialState()
is not simple, we create a constructor
and convert getInitialState()
to an assignment to this.state
constructor
always have props
as the first parametercontext
as the second parameter when (one of) the following things happen in getInitialState()
:
this.context
, orthis.x()
, orthis
is referenced alonethis.props
to props
and accesses to this.context
to context
since the values will be passed as constructor
arguments
var props = this.props;
and var context = this.context
return {...};
) to this.state = {...}
return;
after the assignment when the return statement is part of a control flow statement (not a direct child of getInitialState()
's body) and not in an inner function declarationonClick = () => {};
). All your Flow annotations will be preserved
- It's actually not necessary to transform all methods to arrow functions (i.e., to bind them), but this behavior is the same as createClass()
and we can make sure that we won't accidentally break stuffpropTypes
and put it on the class (this only happens when there's /* @flow */
in your code and options['flow']
is true
)propTypes
in createClass
calls but not ES6 class components. Here the transformation logic is identical to how Flow treats propTypes
foo: React.PropTypes.number
is valid when you pass {}
, {foo: null}
, or {foo: undefined}
as props at runtime. However, when Flow infers type from a createClass
call, only {}
and {foo: undefined}
are valid; {foo: null}
is not. Thus the equivalent type annotation in Flow is actually {foo?: number}
. The question mark on the left hand side indicates {}
and {foo: undefined}
are fine, but when foo
is present it must be a number
propTypes
fields that can't be recognized by Flow, $FlowFixMe
will be usedReact.createClass
is no longer present in React 16. So, if a createClass
call cannot be converted to a plain class, the script will fallback to using the create-react-class
package.React.createClass
with ReactCreateClass
.require
or import
statement for create-react-class
. The import style is inferred from the import style of the react
import. The default module name can be overridden with the --create-class-module-name
option.react
import if there are no more references to it.npx react-codemod class <path>
To pass more options directly to jscodeshift, use --jscodeshift="..."
. For example:
npx react-codemod --jscodeshift="--run-in-band --verbose=2"
See all available options here.
Options to recast's printer can be provided
through jscodeshift's printOptions
command line argument
npx react-codemod <transform> <path> --jscodeshift="--printOptions='{\"quote\":\"double\"}'"
explicit-require=false
If you're not explicitly importing React in your files (eg: if you're loading React with a script tag), you should add --explicit-require=false
.
The scripts in this repository are provided in the hope that they are useful, but they are not officially maintained, and we generally will not fix community-reported issues. They are a collection of scripts that were previously used internally within Facebook or were contributed by the community, and we rely on community contributions to fix any issues discovered or make any improvements. If you want to contribute, you're welcome to submit a pull request.
react-codemod is MIT licensed.
FAQs
React codemod scripts
We found that react-codemod demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.