@vitejs/plugin-react 1.1.3 → 1.1.4
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/CHANGELOG.md +15 -0
- package/README.md +10 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +31 -23
- package/package.json +8 -8
- package/src/index.ts +72 -29
- package/src/jsx-runtime/babel-import-to-require.ts +2 -3
- package/src/jsx-runtime/babel-restore-jsx.spec.ts +6 -0
- package/src/jsx-runtime/babel-restore-jsx.ts +4 -4
- package/src/jsx-runtime/restore-jsx.ts +2 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## [1.1.4](https://github.com/vitejs/vite/compare/plugin-react@1.1.3...plugin-react@1.1.4) (2022-01-04)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* **plugin-react:** check for import React statement in .js files ([#6320](https://github.com/vitejs/vite/issues/6320)) ([bd9e97b](https://github.com/vitejs/vite/commit/bd9e97bd1b9156059b78b531871a12f6f47c04b1)), closes [#6148](https://github.com/vitejs/vite/issues/6148) [#6148](https://github.com/vitejs/vite/issues/6148)
|
7
|
+
* **plugin-react:** restore-jsx bug when component name is lowercase ([#6110](https://github.com/vitejs/vite/issues/6110)) ([ce65c56](https://github.com/vitejs/vite/commit/ce65c567a64fad3be4209cbd1132e62e905fe349))
|
8
|
+
|
9
|
+
|
10
|
+
### Features
|
11
|
+
|
12
|
+
* **plugin-react:** check for `api.reactBabel` on other plugins ([#5454](https://github.com/vitejs/vite/issues/5454)) ([2ab41b3](https://github.com/vitejs/vite/commit/2ab41b3184d2452be4fa0b427f05c791311644aa))
|
13
|
+
|
14
|
+
|
15
|
+
|
1
16
|
## [1.1.3](https://github.com/vitejs/vite/compare/plugin-react@1.1.2...plugin-react@1.1.3) (2021-12-13)
|
2
17
|
|
3
18
|
|
package/README.md
CHANGED
@@ -33,6 +33,16 @@ react({
|
|
33
33
|
})
|
34
34
|
```
|
35
35
|
|
36
|
+
## Opting out of the automatic JSX runtime
|
37
|
+
|
38
|
+
By default, the plugin uses the [automatic JSX runtime](https://github.com/alloc/vite-react-jsx#faq). However, if you encounter any issues, you may opt out using the `jsxRuntime` option.
|
39
|
+
|
40
|
+
```js
|
41
|
+
react({
|
42
|
+
jsxRuntime: 'classic'
|
43
|
+
})
|
44
|
+
```
|
45
|
+
|
36
46
|
## Babel configuration
|
37
47
|
|
38
48
|
The `babel` option lets you add plugins, presets, and [other configuration](https://babeljs.io/docs/en/options) to the Babel transformation performed on each JSX/TSX file.
|
package/dist/index.d.ts
CHANGED
@@ -2,6 +2,8 @@ import type { ParserOptions } from '@babel/core';
|
|
2
2
|
import type { PluginOption } from 'vite';
|
3
3
|
import type { TransformOptions } from '@babel/core';
|
4
4
|
|
5
|
+
export declare type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
|
6
|
+
|
5
7
|
export declare interface Options {
|
6
8
|
include?: string | RegExp | Array<string | RegExp>;
|
7
9
|
exclude?: string | RegExp | Array<string | RegExp>;
|
@@ -24,13 +26,25 @@ export declare interface Options {
|
|
24
26
|
/**
|
25
27
|
* Babel configuration applied in both dev and prod.
|
26
28
|
*/
|
27
|
-
babel?:
|
29
|
+
babel?: BabelOptions;
|
28
30
|
/**
|
29
31
|
* @deprecated Use `babel.parserOpts.plugins` instead
|
30
32
|
*/
|
31
33
|
parserPlugins?: ParserOptions['plugins'];
|
32
34
|
}
|
33
35
|
|
36
|
+
/**
|
37
|
+
* The object type used by the `options` passed to plugins with
|
38
|
+
* an `api.reactBabel` method.
|
39
|
+
*/
|
40
|
+
export declare interface ReactBabelOptions extends BabelOptions {
|
41
|
+
plugins: Extract<BabelOptions['plugins'], any[]>;
|
42
|
+
presets: Extract<BabelOptions['presets'], any[]>;
|
43
|
+
parserOpts: ParserOptions & {
|
44
|
+
plugins: Extract<ParserOptions['plugins'], any[]>;
|
45
|
+
};
|
46
|
+
}
|
47
|
+
|
34
48
|
declare function viteReact(opts?: Options): PluginOption[];
|
35
49
|
|
36
50
|
declare namespace viteReact {
|
package/dist/index.js
CHANGED
@@ -78,7 +78,7 @@ function babel_restore_jsx_default({ types: t }) {
|
|
78
78
|
if (node == null) {
|
79
79
|
return null;
|
80
80
|
}
|
81
|
-
const name = getJSXIdentifier(node);
|
81
|
+
const name = getJSXIdentifier(node, true);
|
82
82
|
if (name != null) {
|
83
83
|
return name;
|
84
84
|
}
|
@@ -128,8 +128,8 @@ function babel_restore_jsx_default({ types: t }) {
|
|
128
128
|
}
|
129
129
|
return children;
|
130
130
|
}
|
131
|
-
function getJSXIdentifier(node) {
|
132
|
-
if (t.isIdentifier(node)) {
|
131
|
+
function getJSXIdentifier(node, tag = false) {
|
132
|
+
if (t.isIdentifier(node) && (!tag || node.name.match(/^[A-Z]/))) {
|
133
133
|
return t.jsxIdentifier(node.name);
|
134
134
|
}
|
135
135
|
if (t.isStringLiteral(node)) {
|
@@ -265,9 +265,7 @@ function isComponentLikeName(name) {
|
|
265
265
|
}
|
266
266
|
|
267
267
|
// src/jsx-runtime/babel-import-to-require.ts
|
268
|
-
function babelImportToRequire({
|
269
|
-
types: t
|
270
|
-
}) {
|
268
|
+
function babelImportToRequire({ types: t }) {
|
271
269
|
return {
|
272
270
|
visitor: {
|
273
271
|
ImportDeclaration(path) {
|
@@ -330,7 +328,7 @@ function parseReactAlias(code) {
|
|
330
328
|
|
331
329
|
// src/index.ts
|
332
330
|
function viteReact(opts = {}) {
|
333
|
-
var _a
|
331
|
+
var _a;
|
334
332
|
let base = "/";
|
335
333
|
let filter = (0, import_pluginutils.createFilter)(opts.include, opts.exclude);
|
336
334
|
let isProduction = true;
|
@@ -338,8 +336,14 @@ function viteReact(opts = {}) {
|
|
338
336
|
let skipFastRefresh = opts.fastRefresh === false;
|
339
337
|
let skipReactImport = false;
|
340
338
|
const useAutomaticRuntime = opts.jsxRuntime !== "classic";
|
341
|
-
const
|
342
|
-
|
339
|
+
const babelOptions = __spreadValues({
|
340
|
+
babelrc: false,
|
341
|
+
configFile: false
|
342
|
+
}, opts.babel);
|
343
|
+
babelOptions.plugins || (babelOptions.plugins = []);
|
344
|
+
babelOptions.presets || (babelOptions.presets = []);
|
345
|
+
babelOptions.parserOpts || (babelOptions.parserOpts = {});
|
346
|
+
(_a = babelOptions.parserOpts).plugins || (_a.plugins = opts.parserPlugins || []);
|
343
347
|
const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/;
|
344
348
|
const fileExtensionRE = /\.[^\/\s\?]+$/;
|
345
349
|
const viteBabel = {
|
@@ -358,10 +362,17 @@ function viteReact(opts = {}) {
|
|
358
362
|
skipReactImport = true;
|
359
363
|
config.logger.warn("[@vitejs/plugin-react] This plugin imports React for you automatically, so you can stop using `esbuild.jsxInject` for that purpose.");
|
360
364
|
}
|
361
|
-
config.plugins.forEach((plugin) =>
|
365
|
+
config.plugins.forEach((plugin) => {
|
366
|
+
var _a2;
|
367
|
+
const hasConflict = plugin.name === "react-refresh" || plugin !== viteReactJsx && plugin.name === "vite:react-jsx";
|
368
|
+
if (hasConflict)
|
369
|
+
return config.logger.warn(`[@vitejs/plugin-react] You should stop using "${plugin.name}" since this plugin conflicts with it.`);
|
370
|
+
if ((_a2 = plugin.api) == null ? void 0 : _a2.reactBabel) {
|
371
|
+
plugin.api.reactBabel(babelOptions, config);
|
372
|
+
}
|
373
|
+
});
|
362
374
|
},
|
363
375
|
async transform(code, id, options) {
|
364
|
-
var _a2, _b2, _c2, _d;
|
365
376
|
const ssr = typeof options === "boolean" ? options : (options == null ? void 0 : options.ssr) === true;
|
366
377
|
const [filepath, querystring = ""] = id.split("?");
|
367
378
|
const [extension = ""] = querystring.match(fileExtensionRE) || filepath.match(fileExtensionRE) || [];
|
@@ -369,10 +380,10 @@ function viteReact(opts = {}) {
|
|
369
380
|
const isJSX = extension.endsWith("x");
|
370
381
|
const isNodeModules = id.includes("/node_modules/");
|
371
382
|
const isProjectFile = !isNodeModules && (id[0] === "\0" || id.startsWith(projectRoot + "/"));
|
372
|
-
const plugins = isProjectFile ? [...
|
383
|
+
const plugins = isProjectFile ? [...babelOptions.plugins] : [];
|
373
384
|
let useFastRefresh = false;
|
374
385
|
if (!skipFastRefresh && !ssr && !isNodeModules) {
|
375
|
-
const isReactModule = isJSX ||
|
386
|
+
const isReactModule = isJSX || importReactRE.test(code);
|
376
387
|
if (isReactModule && filter(id)) {
|
377
388
|
useFastRefresh = true;
|
378
389
|
plugins.push([
|
@@ -406,12 +417,12 @@ function viteReact(opts = {}) {
|
|
406
417
|
}
|
407
418
|
}
|
408
419
|
}
|
409
|
-
const shouldSkip = !plugins.length && !
|
420
|
+
const shouldSkip = !plugins.length && !babelOptions.configFile && !(isProjectFile && babelOptions.babelrc);
|
410
421
|
if (shouldSkip) {
|
411
422
|
return;
|
412
423
|
}
|
413
424
|
const parserPlugins = [
|
414
|
-
...
|
425
|
+
...babelOptions.parserOpts.plugins,
|
415
426
|
"importMeta",
|
416
427
|
"topLevelAwait",
|
417
428
|
"classProperties",
|
@@ -424,28 +435,25 @@ function viteReact(opts = {}) {
|
|
424
435
|
if (/\.tsx?$/.test(extension)) {
|
425
436
|
parserPlugins.push("typescript");
|
426
437
|
}
|
438
|
+
const transformAsync2 = ast ? babel.transformFromAstAsync.bind(babel, ast, code) : babel.transformAsync.bind(babel, code);
|
427
439
|
const isReasonReact = extension.endsWith(".bs.js");
|
428
|
-
const
|
429
|
-
babelrc: false,
|
430
|
-
configFile: false
|
431
|
-
}, opts.babel), {
|
440
|
+
const result = await transformAsync2(__spreadProps(__spreadValues({}, babelOptions), {
|
432
441
|
ast: !isReasonReact,
|
433
442
|
root: projectRoot,
|
434
443
|
filename: id,
|
435
444
|
sourceFileName: filepath,
|
436
|
-
parserOpts: __spreadProps(__spreadValues({},
|
445
|
+
parserOpts: __spreadProps(__spreadValues({}, babelOptions.parserOpts), {
|
437
446
|
sourceType: "module",
|
438
447
|
allowAwaitOutsideFunction: true,
|
439
448
|
plugins: parserPlugins
|
440
449
|
}),
|
441
|
-
generatorOpts: __spreadProps(__spreadValues({},
|
450
|
+
generatorOpts: __spreadProps(__spreadValues({}, babelOptions.generatorOpts), {
|
442
451
|
decoratorsBeforeExport: true
|
443
452
|
}),
|
444
453
|
plugins,
|
445
454
|
sourceMaps: true,
|
446
455
|
inputSourceMap: false
|
447
|
-
});
|
448
|
-
const result = ast ? await babel.transformFromAstAsync(ast, code, babelOpts) : await babel.transformAsync(code, babelOpts);
|
456
|
+
}));
|
449
457
|
if (result) {
|
450
458
|
let code2 = result.code;
|
451
459
|
if (useFastRefresh && /\$RefreshReg\$\(/.test(code2)) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitejs/plugin-react",
|
3
|
-
"version": "1.1.
|
3
|
+
"version": "1.1.4",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Evan You",
|
6
6
|
"contributors": [
|
@@ -18,7 +18,7 @@
|
|
18
18
|
"build-bundle": "esbuild src/index.ts --bundle --platform=node --target=node12 --external:@babel/* --external:@rollup/* --external:resolve --external:react-refresh/* --outfile=dist/index.js",
|
19
19
|
"build-types": "tsc -p . --emitDeclarationOnly --outDir temp && api-extractor run && rimraf temp",
|
20
20
|
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s --commit-path . --lerna-package plugin-react",
|
21
|
-
"release": "node ../../scripts/release.
|
21
|
+
"release": "ts-node ../../scripts/release.ts"
|
22
22
|
},
|
23
23
|
"engines": {
|
24
24
|
"node": ">=12.0.0"
|
@@ -33,12 +33,12 @@
|
|
33
33
|
},
|
34
34
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme",
|
35
35
|
"dependencies": {
|
36
|
-
"@babel/core": "^7.16.
|
37
|
-
"@babel/plugin-transform-react-jsx": "^7.16.
|
38
|
-
"@babel/plugin-transform-react-jsx-development": "^7.16.
|
39
|
-
"@babel/plugin-transform-react-jsx-self": "^7.16.
|
40
|
-
"@babel/plugin-transform-react-jsx-source": "^7.16.
|
41
|
-
"@rollup/pluginutils": "^4.1.
|
36
|
+
"@babel/core": "^7.16.5",
|
37
|
+
"@babel/plugin-transform-react-jsx": "^7.16.5",
|
38
|
+
"@babel/plugin-transform-react-jsx-development": "^7.16.5",
|
39
|
+
"@babel/plugin-transform-react-jsx-self": "^7.16.5",
|
40
|
+
"@babel/plugin-transform-react-jsx-source": "^7.16.5",
|
41
|
+
"@rollup/pluginutils": "^4.1.2",
|
42
42
|
"react-refresh": "^0.11.0",
|
43
43
|
"resolve": "^1.20.0"
|
44
44
|
}
|
package/src/index.ts
CHANGED
@@ -36,13 +36,46 @@ export interface Options {
|
|
36
36
|
/**
|
37
37
|
* Babel configuration applied in both dev and prod.
|
38
38
|
*/
|
39
|
-
babel?:
|
39
|
+
babel?: BabelOptions
|
40
40
|
/**
|
41
41
|
* @deprecated Use `babel.parserOpts.plugins` instead
|
42
42
|
*/
|
43
43
|
parserPlugins?: ParserOptions['plugins']
|
44
44
|
}
|
45
45
|
|
46
|
+
export type BabelOptions = Omit<
|
47
|
+
TransformOptions,
|
48
|
+
| 'ast'
|
49
|
+
| 'filename'
|
50
|
+
| 'root'
|
51
|
+
| 'sourceFileName'
|
52
|
+
| 'sourceMaps'
|
53
|
+
| 'inputSourceMap'
|
54
|
+
>
|
55
|
+
|
56
|
+
/**
|
57
|
+
* The object type used by the `options` passed to plugins with
|
58
|
+
* an `api.reactBabel` method.
|
59
|
+
*/
|
60
|
+
export interface ReactBabelOptions extends BabelOptions {
|
61
|
+
plugins: Extract<BabelOptions['plugins'], any[]>
|
62
|
+
presets: Extract<BabelOptions['presets'], any[]>
|
63
|
+
parserOpts: ParserOptions & {
|
64
|
+
plugins: Extract<ParserOptions['plugins'], any[]>
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
declare module 'vite' {
|
69
|
+
export interface Plugin {
|
70
|
+
api?: {
|
71
|
+
/**
|
72
|
+
* Manipulate the Babel options of `@vitejs/plugin-react`
|
73
|
+
*/
|
74
|
+
reactBabel?: (options: ReactBabelOptions, config: ResolvedConfig) => void
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
46
79
|
export default function viteReact(opts: Options = {}): PluginOption[] {
|
47
80
|
// Provide default values for Rollup compat.
|
48
81
|
let base = '/'
|
@@ -54,11 +87,18 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
54
87
|
|
55
88
|
const useAutomaticRuntime = opts.jsxRuntime !== 'classic'
|
56
89
|
|
57
|
-
const
|
58
|
-
|
59
|
-
|
90
|
+
const babelOptions = {
|
91
|
+
babelrc: false,
|
92
|
+
configFile: false,
|
93
|
+
...opts.babel
|
94
|
+
} as ReactBabelOptions
|
60
95
|
|
61
|
-
|
96
|
+
babelOptions.plugins ||= []
|
97
|
+
babelOptions.presets ||= []
|
98
|
+
babelOptions.parserOpts ||= {} as any
|
99
|
+
babelOptions.parserOpts.plugins ||= opts.parserPlugins || []
|
100
|
+
|
101
|
+
// Support patterns like:
|
62
102
|
// - import * as React from 'react';
|
63
103
|
// - import React from 'react';
|
64
104
|
// - import React, {useEffect} from 'react';
|
@@ -88,15 +128,21 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
88
128
|
)
|
89
129
|
}
|
90
130
|
|
91
|
-
config.plugins.forEach(
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
131
|
+
config.plugins.forEach((plugin) => {
|
132
|
+
const hasConflict =
|
133
|
+
plugin.name === 'react-refresh' ||
|
134
|
+
(plugin !== viteReactJsx && plugin.name === 'vite:react-jsx')
|
135
|
+
|
136
|
+
if (hasConflict)
|
137
|
+
return config.logger.warn(
|
96
138
|
`[@vitejs/plugin-react] You should stop using "${plugin.name}" ` +
|
97
139
|
`since this plugin conflicts with it.`
|
98
140
|
)
|
99
|
-
|
141
|
+
|
142
|
+
if (plugin.api?.reactBabel) {
|
143
|
+
plugin.api.reactBabel(babelOptions, config)
|
144
|
+
}
|
145
|
+
})
|
100
146
|
},
|
101
147
|
async transform(code, id, options) {
|
102
148
|
const ssr = typeof options === 'boolean' ? options : options?.ssr === true
|
@@ -113,12 +159,12 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
113
159
|
const isProjectFile =
|
114
160
|
!isNodeModules && (id[0] === '\0' || id.startsWith(projectRoot + '/'))
|
115
161
|
|
116
|
-
const plugins = isProjectFile ? [...
|
162
|
+
const plugins = isProjectFile ? [...babelOptions.plugins] : []
|
117
163
|
|
118
164
|
let useFastRefresh = false
|
119
165
|
if (!skipFastRefresh && !ssr && !isNodeModules) {
|
120
166
|
// Modules with .js or .ts extension must import React.
|
121
|
-
const isReactModule = isJSX ||
|
167
|
+
const isReactModule = isJSX || importReactRE.test(code)
|
122
168
|
if (isReactModule && filter(id)) {
|
123
169
|
useFastRefresh = true
|
124
170
|
plugins.push([
|
@@ -179,15 +225,15 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
179
225
|
// module, including node_modules and linked packages.
|
180
226
|
const shouldSkip =
|
181
227
|
!plugins.length &&
|
182
|
-
!
|
183
|
-
!(isProjectFile &&
|
228
|
+
!babelOptions.configFile &&
|
229
|
+
!(isProjectFile && babelOptions.babelrc)
|
184
230
|
|
185
231
|
if (shouldSkip) {
|
186
232
|
return // Avoid parsing if no plugins exist.
|
187
233
|
}
|
188
234
|
|
189
|
-
const parserPlugins: typeof
|
190
|
-
...
|
235
|
+
const parserPlugins: typeof babelOptions.parserOpts.plugins = [
|
236
|
+
...babelOptions.parserOpts.plugins,
|
191
237
|
'importMeta',
|
192
238
|
// This plugin is applied before esbuild transforms the code,
|
193
239
|
// so we need to enable some stage 3 syntax that is supported in
|
@@ -206,35 +252,32 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
206
252
|
parserPlugins.push('typescript')
|
207
253
|
}
|
208
254
|
|
209
|
-
const
|
255
|
+
const transformAsync = ast
|
256
|
+
? babel.transformFromAstAsync.bind(babel, ast, code)
|
257
|
+
: babel.transformAsync.bind(babel, code)
|
210
258
|
|
211
|
-
const
|
212
|
-
|
213
|
-
|
214
|
-
...opts.babel,
|
259
|
+
const isReasonReact = extension.endsWith('.bs.js')
|
260
|
+
const result = await transformAsync({
|
261
|
+
...babelOptions,
|
215
262
|
ast: !isReasonReact,
|
216
263
|
root: projectRoot,
|
217
264
|
filename: id,
|
218
265
|
sourceFileName: filepath,
|
219
266
|
parserOpts: {
|
220
|
-
...
|
267
|
+
...babelOptions.parserOpts,
|
221
268
|
sourceType: 'module',
|
222
269
|
allowAwaitOutsideFunction: true,
|
223
270
|
plugins: parserPlugins
|
224
271
|
},
|
225
272
|
generatorOpts: {
|
226
|
-
...
|
273
|
+
...babelOptions.generatorOpts,
|
227
274
|
decoratorsBeforeExport: true
|
228
275
|
},
|
229
276
|
plugins,
|
230
277
|
sourceMaps: true,
|
231
278
|
// Vite handles sourcemap flattening
|
232
279
|
inputSourceMap: false as any
|
233
|
-
}
|
234
|
-
|
235
|
-
const result = ast
|
236
|
-
? await babel.transformFromAstAsync(ast, code, babelOpts)
|
237
|
-
: await babel.transformAsync(code, babelOpts)
|
280
|
+
})
|
238
281
|
|
239
282
|
if (result) {
|
240
283
|
let code = result.code!
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type * as babelCore from '@babel/core'
|
1
2
|
import type { types as t, Visitor } from '@babel/core'
|
2
3
|
|
3
4
|
/**
|
@@ -9,9 +10,7 @@ import type { types as t, Visitor } from '@babel/core'
|
|
9
10
|
*
|
10
11
|
* var _jsx = require("react/jsx-runtime").jsx
|
11
12
|
*/
|
12
|
-
export function babelImportToRequire({
|
13
|
-
types: t
|
14
|
-
}: typeof import('@babel/core')): {
|
13
|
+
export function babelImportToRequire({ types: t }: typeof babelCore): {
|
15
14
|
visitor: Visitor
|
16
15
|
} {
|
17
16
|
return {
|
@@ -108,4 +108,10 @@ describe('babel-restore-jsx', () => {
|
|
108
108
|
)
|
109
109
|
).toMatchInlineSnapshot(`"<h1>{foo ? <p /> : null}</h1>;"`)
|
110
110
|
})
|
111
|
+
|
112
|
+
it('should handle lowercase component names', () => {
|
113
|
+
expect(jsx('React.createElement(aaa)')).toMatchInlineSnapshot(
|
114
|
+
`"React.createElement(aaa);"`
|
115
|
+
)
|
116
|
+
})
|
111
117
|
})
|
@@ -2,7 +2,7 @@
|
|
2
2
|
* https://github.com/flying-sheep/babel-plugin-transform-react-createelement-to-jsx
|
3
3
|
* @license GNU General Public License v3.0
|
4
4
|
*/
|
5
|
-
import * as babel from '@babel/core'
|
5
|
+
import type * as babel from '@babel/core'
|
6
6
|
|
7
7
|
/**
|
8
8
|
* Visitor factory for babel, converting React.createElement(...) to <jsx ...>...</jsx>
|
@@ -76,7 +76,7 @@ export default function ({ types: t }: typeof babel): babel.PluginObj {
|
|
76
76
|
return null
|
77
77
|
}
|
78
78
|
|
79
|
-
const name = getJSXIdentifier(node)
|
79
|
+
const name = getJSXIdentifier(node, true)
|
80
80
|
if (name != null) {
|
81
81
|
return name
|
82
82
|
}
|
@@ -152,9 +152,9 @@ export default function ({ types: t }: typeof babel): babel.PluginObj {
|
|
152
152
|
return children
|
153
153
|
}
|
154
154
|
|
155
|
-
function getJSXIdentifier(node: any) {
|
155
|
+
function getJSXIdentifier(node: any, tag = false) {
|
156
156
|
//TODO: JSXNamespacedName
|
157
|
-
if (t.isIdentifier(node)) {
|
157
|
+
if (t.isIdentifier(node) && (!tag || node.name.match(/^[A-Z]/))) {
|
158
158
|
return t.jsxIdentifier(node.name)
|
159
159
|
}
|
160
160
|
if (t.isStringLiteral(node)) {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type * as babelCore from '@babel/core'
|
1
2
|
import type { PluginItem, types as t } from '@babel/core'
|
2
3
|
|
3
4
|
type RestoredJSX = [result: t.File | null | undefined, isCommonJS: boolean]
|
@@ -8,7 +9,7 @@ const jsxNotFound: RestoredJSX = [null, false]
|
|
8
9
|
|
9
10
|
/** Restore JSX from `React.createElement` calls */
|
10
11
|
export async function restoreJSX(
|
11
|
-
babel: typeof
|
12
|
+
babel: typeof babelCore,
|
12
13
|
code: string,
|
13
14
|
filename: string
|
14
15
|
): Promise<RestoredJSX> {
|