@vitejs/plugin-react 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +10 -4
- package/package.json +4 -4
- package/src/jsx-runtime/restore-jsx.spec.ts +55 -0
- package/src/jsx-runtime/restore-jsx.ts +26 -16
package/dist/index.js
CHANGED
@@ -292,16 +292,22 @@ async function restoreJSX(babel2, code, filename) {
|
|
292
292
|
if (!reactAlias) {
|
293
293
|
return jsxNotFound;
|
294
294
|
}
|
295
|
-
const reactJsxRE = new RegExp("\\b" + reactAlias + "\\.(createElement|Fragment)\\b", "g");
|
296
295
|
let hasCompiledJsx = false;
|
297
|
-
|
296
|
+
const fragmentPattern = `\\b${reactAlias}\\.Fragment\\b`;
|
297
|
+
const createElementPattern = `\\b${reactAlias}\\.createElement\\(\\s*([A-Z"'][\\w$.]*["']?)`;
|
298
|
+
code = code.replace(new RegExp(fragmentPattern, "g"), () => {
|
298
299
|
hasCompiledJsx = true;
|
299
|
-
return "React."
|
300
|
+
return "React.Fragment";
|
301
|
+
}).replace(new RegExp(createElementPattern, "g"), (original, component) => {
|
302
|
+
if (/^[a-z][\w$]*$/.test(component)) {
|
303
|
+
return original;
|
304
|
+
}
|
305
|
+
hasCompiledJsx = true;
|
306
|
+
return "React.createElement(" + (component === "Fragment" ? "React.Fragment" : component);
|
300
307
|
});
|
301
308
|
if (!hasCompiledJsx) {
|
302
309
|
return jsxNotFound;
|
303
310
|
}
|
304
|
-
code = code.replace(/createElement\(Fragment,/g, "createElement(React.Fragment,");
|
305
311
|
babelRestoreJSX || (babelRestoreJSX = Promise.resolve().then(() => (init_babel_restore_jsx(), babel_restore_jsx_exports)));
|
306
312
|
const result = await babel2.transformAsync(code, {
|
307
313
|
babelrc: false,
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitejs/plugin-react",
|
3
|
-
"version": "1.3.
|
3
|
+
"version": "1.3.2",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Evan You",
|
6
6
|
"contributors": [
|
@@ -33,13 +33,13 @@
|
|
33
33
|
},
|
34
34
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme",
|
35
35
|
"dependencies": {
|
36
|
-
"@babel/core": "^7.17.
|
36
|
+
"@babel/core": "^7.17.10",
|
37
37
|
"@babel/plugin-transform-react-jsx": "^7.17.3",
|
38
38
|
"@babel/plugin-transform-react-jsx-development": "^7.16.7",
|
39
39
|
"@babel/plugin-transform-react-jsx-self": "^7.16.7",
|
40
40
|
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
|
41
|
-
"@rollup/pluginutils": "^4.2.
|
42
|
-
"react-refresh": "^0.
|
41
|
+
"@rollup/pluginutils": "^4.2.1",
|
42
|
+
"react-refresh": "^0.13.0",
|
43
43
|
"resolve": "^1.22.0"
|
44
44
|
}
|
45
45
|
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { restoreJSX } from './restore-jsx'
|
2
|
+
import * as babel from '@babel/core'
|
3
|
+
|
4
|
+
async function jsx(sourceCode: string) {
|
5
|
+
const [ast] = await restoreJSX(babel, sourceCode, 'test.js')
|
6
|
+
if (ast === null) {
|
7
|
+
return ast
|
8
|
+
}
|
9
|
+
const { code } = await babel.transformFromAstAsync(ast, null, {
|
10
|
+
configFile: false
|
11
|
+
})
|
12
|
+
return code
|
13
|
+
}
|
14
|
+
// jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
15
|
+
// React__default.createElement(Foo)`)
|
16
|
+
// Tests adapted from: https://github.com/flying-sheep/babel-plugin-transform-react-createelement-to-jsx/blob/63137b6/test/index.js
|
17
|
+
describe('restore-jsx', () => {
|
18
|
+
it('should trans to ', async () => {
|
19
|
+
expect(
|
20
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
21
|
+
React__default.createElement(foo)`)
|
22
|
+
).toBeNull()
|
23
|
+
expect(
|
24
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
25
|
+
React__default.createElement("h1")`)
|
26
|
+
).toMatch(`<h1 />;`)
|
27
|
+
expect(
|
28
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
29
|
+
React__default.createElement(Foo)`)
|
30
|
+
).toMatch(`<Foo />;`)
|
31
|
+
expect(
|
32
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
33
|
+
React__default.createElement(Foo.Bar)`)
|
34
|
+
).toMatch(`<Foo.Bar />;`)
|
35
|
+
expect(
|
36
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
37
|
+
React__default.createElement(Foo.Bar.Baz)`)
|
38
|
+
).toMatch(`<Foo.Bar.Baz />;`)
|
39
|
+
})
|
40
|
+
|
41
|
+
it('should handle props', async () => {
|
42
|
+
expect(
|
43
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
44
|
+
React__default.createElement(foo, {hi: there})`)
|
45
|
+
).toBeNull()
|
46
|
+
expect(
|
47
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
48
|
+
React__default.createElement("h1", {hi: there})`)
|
49
|
+
).toMatch(`<h1 hi={there} />;`)
|
50
|
+
expect(
|
51
|
+
await jsx(`import React__default, { PureComponent, Component, forwardRef, memo, createElement } from 'react';
|
52
|
+
React__default.createElement(Foo, {hi: there})`)
|
53
|
+
).toMatch(`<Foo hi={there} />;`)
|
54
|
+
})
|
55
|
+
})
|
@@ -20,32 +20,42 @@ export async function restoreJSX(
|
|
20
20
|
}
|
21
21
|
|
22
22
|
const [reactAlias, isCommonJS] = parseReactAlias(code)
|
23
|
+
|
23
24
|
if (!reactAlias) {
|
24
25
|
return jsxNotFound
|
25
26
|
}
|
26
27
|
|
27
|
-
const reactJsxRE = new RegExp(
|
28
|
-
'\\b' + reactAlias + '\\.(createElement|Fragment)\\b',
|
29
|
-
'g'
|
30
|
-
)
|
31
|
-
|
32
28
|
let hasCompiledJsx = false
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
|
30
|
+
const fragmentPattern = `\\b${reactAlias}\\.Fragment\\b`
|
31
|
+
const createElementPattern = `\\b${reactAlias}\\.createElement\\(\\s*([A-Z"'][\\w$.]*["']?)`
|
32
|
+
|
33
|
+
// Replace the alias with "React" so JSX can be reverse compiled.
|
34
|
+
code = code
|
35
|
+
.replace(new RegExp(fragmentPattern, 'g'), () => {
|
36
|
+
hasCompiledJsx = true
|
37
|
+
return 'React.Fragment'
|
38
|
+
})
|
39
|
+
.replace(new RegExp(createElementPattern, 'g'), (original, component) => {
|
40
|
+
if (/^[a-z][\w$]*$/.test(component)) {
|
41
|
+
// Take care not to replace the alias for `createElement` calls whose
|
42
|
+
// component is a lowercased variable, since the `restoreJSX` Babel
|
43
|
+
// plugin leaves them untouched.
|
44
|
+
return original
|
45
|
+
}
|
46
|
+
hasCompiledJsx = true
|
47
|
+
return (
|
48
|
+
'React.createElement(' +
|
49
|
+
// Assume `Fragment` is equivalent to `React.Fragment` so modules
|
50
|
+
// that use `import {Fragment} from 'react'` are reverse compiled.
|
51
|
+
(component === 'Fragment' ? 'React.Fragment' : component)
|
52
|
+
)
|
53
|
+
})
|
38
54
|
|
39
55
|
if (!hasCompiledJsx) {
|
40
56
|
return jsxNotFound
|
41
57
|
}
|
42
58
|
|
43
|
-
// Support modules that use `import {Fragment} from 'react'`
|
44
|
-
code = code.replace(
|
45
|
-
/createElement\(Fragment,/g,
|
46
|
-
'createElement(React.Fragment,'
|
47
|
-
)
|
48
|
-
|
49
59
|
babelRestoreJSX ||= import('./babel-restore-jsx')
|
50
60
|
|
51
61
|
const result = await babel.transformAsync(code, {
|