Skip to content

Commit 003dd92

Browse files
committed
feat: add in some jscodeshift examples
1 parent be236fc commit 003dd92

File tree

2 files changed

+139
-16
lines changed

2 files changed

+139
-16
lines changed

public/content/.obsidian/workspace

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@
44
"type": "split",
55
"children": [
66
{
7-
"id": "655bd9bac7b6ddd1",
7+
"id": "9f3f14eb2c6e343e",
88
"type": "leaf",
99
"state": {
10-
"type": "markdown",
11-
"state": {
12-
"file": "design/Mastering-The-Design-Process-Course.md",
13-
"mode": "source",
14-
"source": false
15-
}
10+
"type": "empty",
11+
"state": {}
1612
}
1713
}
1814
],
@@ -69,7 +65,6 @@
6965
"state": {
7066
"type": "backlink",
7167
"state": {
72-
"file": "design/Mastering-The-Design-Process-Course.md",
7368
"collapseAll": false,
7469
"extraContext": false,
7570
"sortOrder": "alphabetical",
@@ -86,7 +81,6 @@
8681
"state": {
8782
"type": "outgoing-link",
8883
"state": {
89-
"file": "design/Mastering-The-Design-Process-Course.md",
9084
"linksCollapsed": false,
9185
"unlinkedCollapsed": true
9286
}
@@ -108,9 +102,7 @@
108102
"type": "leaf",
109103
"state": {
110104
"type": "outline",
111-
"state": {
112-
"file": "design/Mastering-The-Design-Process-Course.md"
113-
}
105+
"state": {}
114106
}
115107
}
116108
]
@@ -120,17 +112,17 @@
120112
"width": 300,
121113
"collapsed": true
122114
},
123-
"active": "655bd9bac7b6ddd1",
115+
"active": "9f3f14eb2c6e343e",
124116
"lastOpenFiles": [
117+
"Untitled.md",
118+
"design/Mastering-The-Design-Process-Course.md",
125119
"customer-success/CX-For-Growth-Talk.md",
126120
"books/intercom-on-product-management.md",
127121
"ruby/Debugging-in-VScode.md",
128122
"ableton/Your-First-Arel-Query.md",
129123
"system-design/interviews.md",
130124
"system-design/distributed-data.md",
131125
"system-design/data-systems.md",
132-
"system-design/System-Design.md",
133-
"comp3520-os/2-process-description-and-control.md",
134-
"typescript/Noted-To-Merge.md"
126+
"system-design/System-Design.md"
135127
]
136128
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# JSCodeShift Examples
2+
3+
Input:
4+
5+
```tsx
6+
function logToScreen(value) {
7+
console.log(value)
8+
return value
9+
}
10+
11+
function add(x, y) {
12+
return logToScreen(x + y)
13+
}
14+
15+
function subtract(x, y) {
16+
return logToScreen(x - y)
17+
}
18+
19+
function multiply(x, y) {
20+
return logToScreen(x * y)
21+
}
22+
23+
function divide(x, y) {
24+
return logToScreen(x / y)
25+
}
26+
```
27+
28+
AST Explorer parser code:
29+
30+
```tsx
31+
// jscodeshift can take a parser, like "babel", "babylon", "flow", "ts", or "tsx"
32+
// Read more: https://github.com/facebook/jscodeshift#parser
33+
export const parser = 'babel'
34+
35+
const isImpliedReturn = (body) => body.type !== 'BlockStatement'
36+
37+
/* Implied body could be more than just an identifier,
38+
* but interrop between the overlapping jscodeshift/
39+
* ast-types types is an absolute PITA. */
40+
const buildBlockStatement = (jscodeshift, impliedBody) =>
41+
jscodeshift.blockStatement([jscodeshift.returnStatement(impliedBody)])
42+
43+
function removeLogToScreenFn(j, source) {
44+
return (
45+
j(source)
46+
.find(j.FunctionDeclaration)
47+
// Target a particular function declaration
48+
.filter(
49+
({ node: functionDeclaration }) =>
50+
functionDeclaration.id.name === 'logToScreen'
51+
)
52+
.remove()
53+
.toSource()
54+
)
55+
}
56+
57+
function removeLogToScreenInvocations(j, source) {
58+
return (
59+
j(source)
60+
.find(j.Identifier)
61+
// Target a particular function declaration
62+
.filter(({ node: identifier }) => identifier.name === 'logToScreen')
63+
.replaceWith((p) => {
64+
return ''
65+
})
66+
.toSource()
67+
)
68+
}
69+
70+
function convertArrowFns(j, source) {
71+
return j(source)
72+
.find(j.VariableDeclaration)
73+
.filter(
74+
(n) => n.value.declarations[0].init.type === 'ArrowFunctionExpression'
75+
)
76+
.replaceWith((n) => {
77+
const declarator = n.value.declarations[0]
78+
const { params, body: rawBody, generator, async } = declarator.init
79+
80+
const body = isImpliedReturn(rawBody)
81+
? buildBlockStatement(j, rawBody)
82+
: rawBody
83+
84+
const declaration = j.functionDeclaration(
85+
j.identifier(declarator.id.name),
86+
params,
87+
body,
88+
generator
89+
)
90+
91+
/* There doesn't seem to be a parameter
92+
* for functionDeclaration() to create
93+
* async functions :/ */
94+
declaration.async = async
95+
96+
return declaration
97+
})
98+
.toSource()
99+
}
100+
101+
// Press ctrl+space for code completion
102+
export default function transformer(file, api) {
103+
const j = api.jscodeshift
104+
105+
const withoutFn = removeLogToScreenFn(j, file.source)
106+
const withoutInvocations = removeLogToScreenInvocations(j, withoutFn)
107+
const converted = convertArrowFns(j, withoutInvocations)
108+
109+
return converted
110+
}
111+
```
112+
113+
Finally, the output looks like the following (if also run through a Prettier formatter):
114+
115+
```tsx
116+
function add(x, y) {
117+
return x + y
118+
}
119+
120+
function subtract(x, y) {
121+
return x - y
122+
}
123+
124+
function multiply(x, y) {
125+
return x * y
126+
}
127+
128+
function divide(x, y) {
129+
return x / y
130+
}
131+
```

0 commit comments

Comments
 (0)