-
Notifications
You must be signed in to change notification settings - Fork 802
/
babel.prod.js
122 lines (106 loc) · 3.47 KB
/
babel.prod.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const RHLPackage = 'react-hot-loader';
const RHLRootPackage = 'react-hot-loader/root';
const RHLPackages = [RHLPackage, RHLRootPackage];
function isImportedFromRHL(path, name) {
const binding = path.scope.getBinding(name);
const bindingType = binding && binding.path.node.type;
if (bindingType === 'ImportSpecifier' || bindingType === 'ImportNamespaceSpecifier') {
const bindingParent = binding.path.parent;
return RHLPackages.includes(bindingParent.source.value);
}
return false;
}
function getRHLContext(file) {
const context = [];
const { body } = file.ast.program;
for (let i = 0; i < body.length; i++) {
const bodyItem = body[i];
const { source, specifiers } = bodyItem;
if (bodyItem.type !== 'ImportDeclaration' || !RHLPackages.includes(source.value)) {
continue;
}
for (let j = 0; j < specifiers.length; j++) {
const specifier = specifiers[j];
if (specifier.type === 'ImportNamespaceSpecifier') {
context.push({
kind: 'namespace',
local: specifier.local.name,
});
} else if (specifier.type === 'ImportSpecifier') {
const specifierData = {
kind: 'named',
local: specifier.local.name,
};
if (specifier.imported.name === 'hot') {
context.push(specifierData);
}
}
}
}
return context.length ? context : null;
}
export default function plugin() {
function handleCall(path) {
if (this.cancel) {
return;
}
for (let i = 0; i < this.rhlContext.length; i++) {
const specifier = this.rhlContext[i];
if (specifier.kind === 'named') {
// replaces hot(module)(App)
if (
path.node.callee.name === specifier.local &&
// ensure that this is `hot` from RHL
isImportedFromRHL(path, specifier.local) &&
path.parent.type === 'CallExpression' &&
path.parent.arguments[0] &&
path.parent.arguments[0].type === 'Identifier'
) {
path.parentPath.replaceWith(path.parent.arguments[0]);
break;
}
// replaces hot(App)
if (
path.node.callee.name === specifier.local &&
// ensure that this is `hot` from RHL
isImportedFromRHL(path, specifier.local) &&
path.type === 'CallExpression' &&
path.node.arguments[0] &&
path.node.arguments[0].type === 'Identifier'
) {
path.replaceWith(path.node.arguments[0]);
break;
}
} else if (specifier.kind === 'namespace') {
// replaces RHL.hot(module)(App)
if (
path.node.callee.callee &&
path.node.callee.callee.type === 'MemberExpression' &&
path.node.callee.callee.object.type === 'Identifier' &&
path.node.callee.callee.object.name === specifier.local &&
// ensure that this is from RHL
isImportedFromRHL(path, specifier.local) &&
path.node.callee.callee.property.type === 'Identifier' &&
path.node.callee.callee.property.name === 'hot' &&
path.node.arguments[0] &&
path.node.arguments[0].type === 'Identifier'
) {
path.replaceWith(path.node.arguments[0]);
break;
}
}
}
}
return {
pre() {
// ignore files that do not use RHL
this.rhlContext = getRHLContext(this.file);
if (!this.rhlContext) {
this.cancel = true;
}
},
visitor: {
CallExpression: handleCall,
},
};
}