Skip to content

Instantly share code, notes, and snippets.

@lelandrichardson
Last active May 12, 2017 15:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lelandrichardson/c7a68950ec10576e174543413bb6e711 to your computer and use it in GitHub Desktop.
Save lelandrichardson/c7a68950ec10576e174543413bb6e711 to your computer and use it in GitHub Desktop.
Find RN Imports
const walk = require('babylon-walk');
const babylon = require('babylon');
const glob = require('glob');
const fs = require('fs');
const path = require('path');
const zip = (a, b, fn) => a.forEach((el, i) => fn(el, b[i], i));
const promisify = fn => new Promise((res, rej) => {
const done = (err, val) => (err ? rej(err) : res(val));
fn(done);
});
const getFile = fpath => promisify(cb => fs.readFile(fpath, 'utf8', cb));
const getFiles = fpath => promisify(cb => fs.readdir(fpath, cb));
const getGlobbedFiles = (g, opts) => promisify(cb => glob(g, opts, cb));
function getAST(data, file) {
let tree;
try {
tree = babylon.parse(data, {
sourceType: 'module',
plugins: [
'jsx',
'flow',
'objectRestSpread',
'exportExtensions',
'classProperties',
],
});
return tree;
} catch (e) {
console.error(file, e);
return null;
}
}
function getReactNativeImports(tree, collector) {
walk.simple(tree, {
ImportDeclaration: (node) => {
if (node.source.value === 'react-native') {
const names = node.specifiers
.filter(spec => spec.type === 'ImportSpecifier')
.map(spec => spec.imported.name);
collector.push(...names);
}
},
});
return collector;
}
function getReactNativeImportsFromPath(file, collector) {
return getFile(file)
.then(str => getAST(str, file))
.then(tree => getReactNativeImports(tree, collector));
}
const results = [];
getGlobbedFiles(process.argv[2], { dot: false, absolute: true })
.then(files => Promise.all(files.map(f => getReactNativeImportsFromPath(f, results))))
.then(() => {
const amounts = {};
results.forEach(name => {
if (!amounts[name]) {
amounts[name] = 0;
}
amounts[name] += 1;
});
process.stdout.write(`name\tcount\n`);
Object.keys(amounts).forEach(key => {
process.stdout.write(`${key}\t${amounts[key]}\n`);
});
});

To run this, you will first need to install the following npm packages:

npm i babylon babylon-walk glob

Then, with the script in the current directory in find-rn-imports.js, you would want to run it, passing in a glob pattern to hit all of the source code files in your repo. For instance I ran something like:

node ./find-rn-imports.js '!(node_modules|test)/**/*.js'

The output of that script will indicate which react native APIs you are importing and how many times in your code base (though this assumes you are using import and not require).

@sahrens
Copy link

sahrens commented May 8, 2017

I had to break up the Promise.all into multiple batches to get it to finish, but here are our numbers:

 { globFiles: 11540, filesProcessed: 11540 }
name	count
StyleSheet	3110
View	3045
Text	1507
Image	962
Platform	725
NativeModules	543
TouchableOpacity	431
TouchableHighlight	314
ScrollView	284
Dimensions	200
ListView	184
TouchableWithoutFeedback	181
Animated	163
PixelRatio	153
TextInput	137
Alert	89
LayoutAnimation	87
Modal	81
Linking	80
AppRegistry	67
Navigator	53
UIManager	44
ActivityIndicator	34
StatusBar	34
AsyncStorage	32
AlertIOS	31
TouchableNativeFeedback	31
FlatList	28
KeyboardAvoidingView	28
Keyboard	28
WebView	26
Easing	26
Switch	25
PanResponder	22
ToastAndroid	19
ActionSheetIOS	17
InteractionManager	15
RefreshControl	15
AppState	15
SectionList	14
Clipboard	14
PushNotificationIOS	12
Picker	12
PermissionsAndroid	9
NetInfo	7
NativeEventEmitter	7
Slider	4
RecyclerViewBackedScrollView	2

@sahrens
Copy link

sahrens commented May 8, 2017

I also had to change the matcher to handle our requires since we still haven't switched, so I used a whitelist on the module names, so might have missed some.

@sahrens
Copy link

sahrens commented May 12, 2017

Also note with our numbers up there we have some different internal implementations, e.g. for Image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment