-
Notifications
You must be signed in to change notification settings - Fork 109
/
rm-requires.js
60 lines (52 loc) · 1.67 KB
/
rm-requires.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
module.exports = (file, api, options) => {
const j = api.jscodeshift;
const printOptions = options.printOptions || {quote: 'single'};
const root = j(file.source);
const requires = {};
const filterAndTransformRequires = path => {
const varName = path.value.id.name;
const requireName = path.value.init.arguments[0].value;
const scopeNode = path.scope.node;
// Check if we already have a require for this, if we do just use
// that one.
if (
requires[requireName] &&
requires[requireName].scopeNode === scopeNode
) {
j(path).renameTo(requires[requireName].varName);
j(path).remove();
return true;
}
// We need this to make sure the JSX transform can use `React`
if (requireName === 'React') {
return false;
}
// Remove required vars that aren't used.
const usages = j(path)
.closestScope()
.find(j.Identifier, {name: varName})
// Ignore require vars
.filter(identifierPath => identifierPath.value !== path.value.id)
// Ignore properties in MemberExpressions
.filter(identifierPath => {
const parent = identifierPath.parent.value;
return !(
j.MemberExpression.check(parent) &&
parent.property === identifierPath.value
);
});
if (!usages.size()) {
j(path).remove();
return true;
}
requires[requireName] = {scopeNode, varName};
};
const didTransform = root
.find(j.VariableDeclarator, {
id: {type: 'Identifier'},
init: {callee: {name: 'require'}},
})
.filter(filterAndTransformRequires)
.size() > 0;
return didTransform ? root.toSource(printOptions) : null;
};