-
Notifications
You must be signed in to change notification settings - Fork 11
/
pure-to-composite-component.js
61 lines (53 loc) · 1.37 KB
/
pure-to-composite-component.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
/** For when you've gone too pure and want to go back. **/
/** Converts
* let HistoryItem = (props) => {
* const {
* item
* } = props;
* return <li>{item}</li>;
* };
*
* let X = (props) => <div>foo</div>;
*
* to
*
* class HistoryItem extends Component {
* render() {
* const {
* item
* } = this.props;
* return <li>{item}</li>;
* }
* }
*
* class X extends Component {
* render() {
* return <div>foo</div>;
* }
* }
*/
module.exports = function (file, api) {
const j = api.jscodeshift;
const {statement} = j.template;
function hasJSXElement(ast) {
return j(ast).find(j.JSXElement).size() > 0;
}
return j(file.source)
.find(j.VariableDeclaration)
.filter(p => p.value.declarations.length == 1)
.replaceWith(p => {
const decl = p.value.declarations[0];
if (decl.init.type !== 'ArrowFunctionExpression' ||
(!hasJSXElement(decl.init.body) && decl.init.body.type !== "JSXElement"))
return p.value;
let body = decl.init.body;
body = body.type == "JSXElement" ? j.returnStatement(body) : body = body.body;
j(body)
.find(j.Identifier, {name: 'props'})
.replaceWith(p => j.memberExpression(j.thisExpression(), j.identifier('props')));
return statement`class ${decl.id} extends Component {
render() { ${body} }
}`;
})
.toSource();
};