This repository has been archived by the owner on Feb 18, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvisit-cjs-deps.js
102 lines (93 loc) · 3.29 KB
/
visit-cjs-deps.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const t = require('babel-types');
// given a string literal expression
// partially resolve the leading part if a string literal
function partialResolve (expr, state) {
let resolveModule;
if (t.isStringLiteral(expr))
resolveModule = expr.value;
else if (t.isTemplateLiteral(expr))
resolveModule = expr.quasis[0].value.cooked;
else if (t.isBinaryExpression(expr) && expr.operator === '+' && t.isStringLiteral(expr.left))
resolveModule = expr.left.value;
if (resolveModule && state.resolves.includes(resolveModule) === false)
state.resolves.push(resolveModule);
}
function addDependency (depModuleArg, state) {
let depModule;
if (t.isStringLiteral(depModuleArg)) {
depModule = depModuleArg.value;
}
else if (t.isTemplateLiteral(depModuleArg)) {
if (depModuleArg.expressions.length !== 0)
return;
depModule = depModuleArg.quasis[0].value.cooked;
}
else {
// no support for dynamic require currently
// just becomes a "null" module
return;
}
if (state.deps.includes(depModule) === false)
state.deps.push(depModule);
}
module.exports = function (state) {
let hasProcess = false;
let hasBuffer = false;
return {
Program: {
enter (path) {
if (!state.deps)
throw new Error('opts.deps must be set for the transform-cjs-deps Babel plugin.');
if (!state.resolves)
state.resolves = [];
},
exit (path) {
if (hasProcess && !state.deps.includes('process'))
state.deps.push('process');
if (hasBuffer && !state.deps.includes('buffer'))
state.deps.push('buffer');
}
},
/*
* require()
*/
CallExpression (path) {
if (t.isIdentifier(path.node.callee, { name: 'require' }))
addDependency(path.node.arguments[0], state);
},
/*
* require.resolve()
*/
MemberExpression (path) {
if (t.isIdentifier(path.node.object, { name: 'require' }) && !path.scope.hasBinding('require')) {
let name = path.node.computed ? path.node.property.value : path.node.property.name;
if (name === 'resolve') {
if (t.isCallExpression(path.parent) && path.parent.callee === path.node &&
path.parent.arguments.length === 1) {
const resolveArgPath = path.parentPath.get('arguments.0');
partialResolve(resolveArgPath.node, state);
}
}
}
},
/*
* module.require()
*/
ReferencedIdentifier (path) {
const identifierName = path.node.name;
if (!hasProcess && identifierName === 'process' && !path.scope.hasBinding('process'))
hasProcess = true;
if (!hasBuffer && identifierName === 'Buffer' && !path.scope.hasBinding('Buffer'))
hasBuffer = true;
if (identifierName === 'module' && !path.scope.hasBinding('module')) {
const parentPath = path.parentPath;
const parentNode = path.parentPath.node;
if (t.isMemberExpression(parentNode) && parentNode.object === path.node) {
const name = parentNode.computed ? parentNode.property.value : parentNode.property.name;
if (name === 'require' && t.isCallExpression(parentPath.parent) && parentPath.parent.callee === parentPath.node)
addDependency(parentPath.parent.arguments[0], state);
}
}
}
};
}