-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathreact-to-preact.js
124 lines (107 loc) · 3.23 KB
/
react-to-preact.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
123
124
module.exports = ({ types: t }) => {
const imports = {};
console.log(t);
return {
name: 'test',
visitor: {
// Remap React -> Preact imports
ImportDeclaration: {
enter: function (path, state) {
const filename = state.file.opts.sourceFileName;
if (!imports[filename]) {
imports[filename] = {};
}
const fileImports = imports[filename];
if (path.node.source.value !== 'react') {
return;
}
const specifiers = {
preact: [],
'preact/hooks': [],
};
path.node.specifiers.forEach((spec) => {
if (/^use.*/.test(spec.imported.name)) {
specifiers['preact/hooks'].push(spec);
return;
}
if (spec.imported.name === 'FC') {
spec.imported.name = 'FunctionalComponent';
}
if (spec.imported.name === 'MutableRefObject') {
spec.imported.name = 'RefObject';
}
specifiers.preact.push(spec);
});
const replacements = [];
Object.keys(specifiers).forEach((key) => {
if (specifiers[key].length === 0) {
return;
}
if (fileImports[key] === undefined) {
fileImports[key] = t.importDeclaration(
specifiers[key],
t.stringLiteral(key)
);
replacements.push(fileImports[key]);
return;
}
fileImports[key].specifiers.concat(specifiers[key]);
});
if (!replacements.length) {
path.remove();
return;
}
path.replaceWithMultiple(replacements);
},
},
// Add onInput to useField type
TSPropertySignature: {
enter: function (path) {
if (path.node.key.name === 'onChange') {
const copy = t.cloneNode(path.node);
copy.key.name = 'onInput';
path.insertBefore(copy);
}
},
},
// Add onInput to useField body
VariableDeclaration: {
enter: function (path) {
const firstDec = path.node.declarations[0];
if (!firstDec || firstDec.id.name !== 'onChange') {
return;
}
const onInput = t.variableDeclaration('const', [
t.variableDeclarator(t.identifier('onInput'), firstDec.id),
]);
path.insertAfter(onInput);
},
},
// Add onInput to useField memoised deps
ArrayExpression: {
enter: function (path) {
if (
path.node.elements.find(
(i) => t.isIdentifier(i) && i.name === 'onChange'
)
) {
path.node.elements.push(t.identifier('onInput'));
}
},
},
ObjectExpression: {
enter: function (path) {
if (
path.node.properties.find(
(i) => t.isObjectProperty(i) && i.key.name === 'onChange'
)
) {
path.node.properties.push(
t.objectProperty(t.identifier('onInput'), t.identifier('onInput'))
);
}
},
},
},
};
};