Skip to content

Instantly share code, notes, and snippets.

@sibelius
Last active November 9, 2016 13:09
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sibelius/7081f68f43c2d26b4f07566022d40d26 to your computer and use it in GitHub Desktop.
Save sibelius/7081f68f43c2d26b4f07566022d40d26 to your computer and use it in GitHub Desktop.
Codemod React Native 24 imports to RN25 imports

README

Why this transform is necessary?

Until React Native 24, you import React from 'react-native' package, but this will change on RN 25, you will need to import React from 'react'. You probably have many files that does this, so I've created a codemod to save you a bunch of time

How to use this

  • Install jscodeshif
npm install -g jscodeshift
  • Download this transform
  • Run the transform
jscodeshift -t transform.js FILES

Example

import React, {
  Component,
  View,
  Text,
  StyleSheet,
  TouchableHighlight,
  TextInput,
} from 'react-native';
import NavigationBar from 'react-native-navbar';


class LoginScreen extends Component {
  render() {
    return (
      <View>
        <NavigationBar
          tintColor="#ADF8D1"
        />
      </View>
    );
  }
}

Will be transformed to:

import React, {Component} from "react";
import {View, Text, StyleSheet, TouchableHighlight, TextInput} from "react-native";
import NavigationBar from 'react-native-navbar';

class LoginScreen extends Component {
  render() {
    return (
      <View>
        <NavigationBar
          tintColor="#ADF8D1"
        />
      </View>
    );
  }
}
module.exports = function(file, api) {
var j = api.jscodeshift; // alias the jscodeshift API
var root = j(file.source); // parse JS code into an AST
// check for import React from 'react-native';
const hasReact = (value) =>
value.type === 'ImportDefaultSpecifier' && value.local.name === 'React';
// check for import { Component } from 'react-native';
const hasComponent = (value) =>
value.type === 'ImportSpecifier' && value.local.name === 'Component';
const updateImport = (path) => {
const { specifiers } = path.value;
const rnImports = path.value.specifiers.filter(value =>
!(hasReact(value) || hasComponent(value))
).map(value => {
const { name } = value.local;
const id = j.identifier(name);
if (value.type === 'ImportSpecifier') {
return j.importSpecifier(id);
} else {
return j.importDefaultSpecifier(id);
}
})
const reactImports = [];
// Check and update import React from 'react-native';
if (specifiers.filter(hasReact).length > 0) {
reactImports.push(j.importDefaultSpecifier(j.identifier('React')));
}
// Check and update import { Component } from 'react-native';
if (specifiers.filter(hasComponent).length > 0) {
reactImports.push(j.importSpecifier(j.identifier('Component')));
}
const allImports = [];
if (reactImports.length > 0) {
allImports.push(j.importDeclaration(
reactImports,
j.literal('react')
));
}
if (rnImports.length > 0) {
allImports.push(j.importDeclaration(
rnImports,
j.literal('react-native')
))
}
j(path).replaceWith(
allImports
);
}
/*
Find and update all import React, { Component } from 'react-native' to
import React, { Component } from 'react';
*/
root
.find(j.ImportDeclaration, {
source: {
value: 'react-native'
}
})
.filter(({node}) => {
// check React or { Component } from 'react-native'
return node.specifiers.filter(value =>
hasReact(value) || hasComponent(value)
).length > 0;
})
.forEach(updateImport);
// print
return root.toSource();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment