@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 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
- code = code.replace(reactJsxRE, (_, prop) => {
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." + prop;
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.1",
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.9",
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.0",
42
- "react-refresh": "^0.12.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
- code = code.replace(reactJsxRE, (_, prop) => {
34
- hasCompiledJsx = true
35
- // Replace with "React" so JSX can be reverse compiled.
36
- return 'React.' + prop
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, {