Skip to content

Commit 3c29ab3

Browse files
authored
feat: use Babel Generator to extract code (#6)
This fixes an issue where `console.log(e)` would get additional code from Babel, which executed a runtime exception.
1 parent fa9845b commit 3c29ab3

5 files changed

Lines changed: 91 additions & 19 deletions

File tree

__mocks__/Examples.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,15 @@ export const MockText = () => {
6969
</ComponentBox>
7070
)
7171
}
72+
73+
export const MockEvents = () => {
74+
return (
75+
<ComponentBox data-test="id">
76+
<DemoComponent
77+
onChange={(e) => {
78+
console.log(e)
79+
}}
80+
/>
81+
</ComponentBox>
82+
)
83+
}

__tests__/babelPluginReactLive.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,23 @@ it('babelPluginReactLive', async () => {
9494
text
9595
{'text'}
9696
97+
\`}</ComponentBox>
98+
)
99+
}
100+
export const MockEvents = () => {
101+
return (
102+
<ComponentBox data-test="id">{\`<DemoComponent
103+
onChange={(e) => {
104+
console.log(e)
105+
}}
106+
/>
97107
\`}</ComponentBox>
98108
)
99109
}
100110
"
101111
`)
102112

103113
expect(formattedCode.match(/noInline/g)).toHaveLength(2)
104-
expect(formattedCode.match(/\{`/g)).toHaveLength(6)
105-
expect(formattedCode.match(/`\}/g)).toHaveLength(6)
114+
expect(formattedCode.match(/\{`/g)).toHaveLength(7)
115+
expect(formattedCode.match(/`\}/g)).toHaveLength(7)
106116
})

babelPluginReactLive.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const fs = require('fs')
22
const prettier = require('prettier')
3+
const { default: generate } = require('@babel/generator')
34

45
function babelPluginReactLive(babel, options) {
56
const { types: t } = babel
@@ -26,6 +27,7 @@ function babelPluginReactLive(babel, options) {
2627
// And we also escape `
2728
code = code.replace(/^;/, '').replace(/`/g, '\\`')
2829

30+
// Remove fragments we added in the first place
2931
if (children.length > 1) {
3032
code = code.replace(/^<>|<\/>$|^\s{2}/gm, '')
3133
}
@@ -65,24 +67,21 @@ function babelPluginReactLive(babel, options) {
6567
path.traverse({
6668
ReturnStatement(path) {
6769
if (currentReturnStatement === path.node) {
68-
const code = path
69-
.getSource()
70-
.replace(/return ((.|\n|\r)*)/, 'render($1)')
70+
const code = astToCode(path.node)
7171

72-
const node = t.identifier(code)
72+
const node = t.identifier(
73+
code.replace(/return ((.|\n|\r)*)/, 'render($1)')
74+
)
7375
path.replaceWith(node)
7476

7577
path.stop()
7678
}
7779
},
7880
})
7981

80-
const code = path
81-
.toString()
82-
.replace(/^\{/, '')
83-
.replace(/\}$/, '')
82+
const code = astToCode(path.node)
8483

85-
children.push(code)
84+
children.push(code.replace(/^\{/, '').replace(/\}$/, ''))
8685

8786
path.stop()
8887

@@ -91,21 +90,21 @@ function babelPluginReactLive(babel, options) {
9190
},
9291
JSXElement(path) {
9392
if (rootPath === path.parentPath) {
94-
const code = path.getSource()
93+
const code = astToCode(path.node)
9594

9695
children.push(code)
9796
}
9897
},
9998
JSXFragment(path) {
10099
if (rootPath === path.parentPath) {
101-
const code = path.getSource()
100+
const code = astToCode(path.node)
102101

103102
children.push(code)
104103
}
105104
},
106105
JSXText(path) {
107106
if (rootPath === path.parentPath) {
108-
const code = path.getSource()
107+
const code = astToCode(path.node)
109108

110109
if (code.trim().length) {
111110
children.push(code)
@@ -117,7 +116,7 @@ function babelPluginReactLive(babel, options) {
117116
rootPath === path.parentPath &&
118117
path.node.expression.type !== 'ArrowFunctionExpression'
119118
) {
120-
const code = path.getSource()
119+
const code = astToCode(path.node)
121120

122121
if (code.length) {
123122
children.push(code)
@@ -140,7 +139,8 @@ function babelPluginReactLive(babel, options) {
140139

141140
path.node.children = [convertCodeToJSX(children)]
142141

143-
path.replaceWith(t.identifier(path.toString()))
142+
const code = astToCode(path.node)
143+
path.replaceWith(t.identifier(code))
144144
}
145145
}
146146
},
@@ -161,4 +161,10 @@ function babelPluginReactLive(babel, options) {
161161
}
162162
}
163163

164+
function astToCode(ast) {
165+
const { code } = generate(ast)
166+
167+
return code.replace(/;$/, '')
168+
}
169+
164170
module.exports = babelPluginReactLive

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,24 @@
1313
"type": "git",
1414
"url": "https://github.com/dnbexperience/eufemia.git"
1515
},
16-
"version": "1.3.0",
16+
"version": "1.4.0",
1717
"main": "babelPluginReactLive.js",
1818
"scripts": {
1919
"test": "jest",
2020
"test:watch": "jest --watch"
2121
},
22+
"dependencies": {
23+
"@babel/generator": "7.21.5",
24+
"prettier": "2.8.0"
25+
},
2226
"devDependencies": {
2327
"@babel/core": "7.20.5",
2428
"@babel/preset-env": "7.20.2",
2529
"@babel/preset-react": "7.18.6",
2630
"@babel/preset-typescript": "7.18.6",
2731
"@types/jest": "29.2.3",
2832
"babel-jest": "29.3.1",
29-
"jest": "29.3.1",
30-
"prettier": "2.8.0"
33+
"jest": "29.3.1"
3134
},
3235
"publishConfig": {
3336
"access": "public"

yarn.lock

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ __metadata:
5454
languageName: node
5555
linkType: hard
5656

57+
"@babel/generator@npm:7.21.5":
58+
version: 7.21.5
59+
resolution: "@babel/generator@npm:7.21.5"
60+
dependencies:
61+
"@babel/types": ^7.21.5
62+
"@jridgewell/gen-mapping": ^0.3.2
63+
"@jridgewell/trace-mapping": ^0.3.17
64+
jsesc: ^2.5.1
65+
checksum: 78af737b9dd701d4c657f9731880430fa1c177767b562f4e8a330a7fe72a4abe857e3d24de4e6d9dafc1f6a11f894162d27e523d7e5948ff9e3925a0ce9867c4
66+
languageName: node
67+
linkType: hard
68+
5769
"@babel/generator@npm:^7.20.5, @babel/generator@npm:^7.7.2":
5870
version: 7.20.5
5971
resolution: "@babel/generator@npm:7.20.5"
@@ -289,6 +301,13 @@ __metadata:
289301
languageName: node
290302
linkType: hard
291303

304+
"@babel/helper-string-parser@npm:^7.21.5":
305+
version: 7.21.5
306+
resolution: "@babel/helper-string-parser@npm:7.21.5"
307+
checksum: 36c0ded452f3858e67634b81960d4bde1d1cd2a56b82f4ba2926e97864816021c885f111a7cf81de88a0ed025f49d84a393256700e9acbca2d99462d648705d8
308+
languageName: node
309+
linkType: hard
310+
292311
"@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1":
293312
version: 7.19.1
294313
resolution: "@babel/helper-validator-identifier@npm:7.19.1"
@@ -1386,6 +1405,17 @@ __metadata:
13861405
languageName: node
13871406
linkType: hard
13881407

1408+
"@babel/types@npm:^7.21.5":
1409+
version: 7.21.5
1410+
resolution: "@babel/types@npm:7.21.5"
1411+
dependencies:
1412+
"@babel/helper-string-parser": ^7.21.5
1413+
"@babel/helper-validator-identifier": ^7.19.1
1414+
to-fast-properties: ^2.0.0
1415+
checksum: 43242a99c612d13285ee4af46cc0f1066bcb6ffd38307daef7a76e8c70f36cfc3255eb9e75c8e768b40e761176c313aec4d5c0b9d97a21e494d49d5fd123a9f7
1416+
languageName: node
1417+
linkType: hard
1418+
13891419
"@bcoe/v8-coverage@npm:^0.2.3":
13901420
version: 0.2.3
13911421
resolution: "@bcoe/v8-coverage@npm:0.2.3"
@@ -1702,6 +1732,16 @@ __metadata:
17021732
languageName: node
17031733
linkType: hard
17041734

1735+
"@jridgewell/trace-mapping@npm:^0.3.17":
1736+
version: 0.3.18
1737+
resolution: "@jridgewell/trace-mapping@npm:0.3.18"
1738+
dependencies:
1739+
"@jridgewell/resolve-uri": 3.1.0
1740+
"@jridgewell/sourcemap-codec": 1.4.14
1741+
checksum: 0572669f855260808c16fe8f78f5f1b4356463b11d3f2c7c0b5580c8ba1cbf4ae53efe9f627595830856e57dbac2325ac17eb0c3dd0ec42102e6f227cc289c02
1742+
languageName: node
1743+
linkType: hard
1744+
17051745
"@npmcli/fs@npm:^2.1.0":
17061746
version: 2.1.2
17071747
resolution: "@npmcli/fs@npm:2.1.2"
@@ -2073,6 +2113,7 @@ __metadata:
20732113
resolution: "babel-plugin-react-live@workspace:."
20742114
dependencies:
20752115
"@babel/core": 7.20.5
2116+
"@babel/generator": 7.21.5
20762117
"@babel/preset-env": 7.20.2
20772118
"@babel/preset-react": 7.18.6
20782119
"@babel/preset-typescript": 7.18.6

0 commit comments

Comments
 (0)