@vitejs/plugin-react 1.1.0 → 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 +37 -0
- package/README.md +10 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +40 -30
- package/package.json +8 -8
- package/src/fast-refresh.ts +7 -7
- 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 +4 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,40 @@
|
|
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
|
+
|
16
|
+
## [1.1.3](https://github.com/vitejs/vite/compare/plugin-react@1.1.2...plugin-react@1.1.3) (2021-12-13)
|
17
|
+
|
18
|
+
|
19
|
+
### Bug Fixes
|
20
|
+
|
21
|
+
* **plugin-react:** only detect preamble in hmr context ([#6096](https://github.com/vitejs/vite/issues/6096)) ([8735294](https://github.com/vitejs/vite/commit/8735294055ce16308a6b8302eba4538f4a2931d0))
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
## [1.1.2](https://github.com/vitejs/vite/compare/plugin-react@1.1.1...plugin-react@1.1.2) (2021-12-13)
|
26
|
+
|
27
|
+
|
28
|
+
### Bug Fixes
|
29
|
+
|
30
|
+
* ignore babel config when running restore-jsx ([#6047](https://github.com/vitejs/vite/issues/6047)) ([9c2843c](https://github.com/vitejs/vite/commit/9c2843cf0506844ee32f042a04c22c440434df2a))
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
## [1.1.1](https://github.com/vitejs/vite/compare/plugin-react@1.1.0...plugin-react@1.1.1) (2021-12-07)
|
35
|
+
|
36
|
+
|
37
|
+
|
1
38
|
# [1.1.0](https://github.com/vitejs/vite/compare/plugin-react@1.1.0-beta.1...plugin-react@1.1.0) (2021-11-22)
|
2
39
|
|
3
40
|
|
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)) {
|
@@ -207,14 +207,14 @@ import RefreshRuntime from "${runtimePublicPath}";
|
|
207
207
|
let prevRefreshReg;
|
208
208
|
let prevRefreshSig;
|
209
209
|
|
210
|
-
if (!window.__vite_plugin_react_preamble_installed__) {
|
211
|
-
throw new Error(
|
212
|
-
"@vitejs/plugin-react can't detect preamble. Something is wrong. " +
|
213
|
-
"See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201"
|
214
|
-
);
|
215
|
-
}
|
216
|
-
|
217
210
|
if (import.meta.hot) {
|
211
|
+
if (!window.__vite_plugin_react_preamble_installed__) {
|
212
|
+
throw new Error(
|
213
|
+
"@vitejs/plugin-react can't detect preamble. Something is wrong. " +
|
214
|
+
"See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201"
|
215
|
+
);
|
216
|
+
}
|
217
|
+
|
218
218
|
prevRefreshReg = window.$RefreshReg$;
|
219
219
|
prevRefreshSig = window.$RefreshSig$;
|
220
220
|
window.$RefreshReg$ = (type, id) => {
|
@@ -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) {
|
@@ -304,6 +302,8 @@ async function restoreJSX(babel2, code, filename) {
|
|
304
302
|
code = code.replace(/createElement\(Fragment,/g, "createElement(React.Fragment,");
|
305
303
|
babelRestoreJSX || (babelRestoreJSX = Promise.resolve().then(() => (init_babel_restore_jsx(), babel_restore_jsx_exports)));
|
306
304
|
const result = await babel2.transformAsync(code, {
|
305
|
+
babelrc: false,
|
306
|
+
configFile: false,
|
307
307
|
ast: true,
|
308
308
|
code: false,
|
309
309
|
filename,
|
@@ -328,7 +328,7 @@ function parseReactAlias(code) {
|
|
328
328
|
|
329
329
|
// src/index.ts
|
330
330
|
function viteReact(opts = {}) {
|
331
|
-
var _a
|
331
|
+
var _a;
|
332
332
|
let base = "/";
|
333
333
|
let filter = (0, import_pluginutils.createFilter)(opts.include, opts.exclude);
|
334
334
|
let isProduction = true;
|
@@ -336,8 +336,14 @@ function viteReact(opts = {}) {
|
|
336
336
|
let skipFastRefresh = opts.fastRefresh === false;
|
337
337
|
let skipReactImport = false;
|
338
338
|
const useAutomaticRuntime = opts.jsxRuntime !== "classic";
|
339
|
-
const
|
340
|
-
|
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 || []);
|
341
347
|
const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/;
|
342
348
|
const fileExtensionRE = /\.[^\/\s\?]+$/;
|
343
349
|
const viteBabel = {
|
@@ -356,10 +362,17 @@ function viteReact(opts = {}) {
|
|
356
362
|
skipReactImport = true;
|
357
363
|
config.logger.warn("[@vitejs/plugin-react] This plugin imports React for you automatically, so you can stop using `esbuild.jsxInject` for that purpose.");
|
358
364
|
}
|
359
|
-
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
|
+
});
|
360
374
|
},
|
361
375
|
async transform(code, id, options) {
|
362
|
-
var _a2, _b2, _c2, _d;
|
363
376
|
const ssr = typeof options === "boolean" ? options : (options == null ? void 0 : options.ssr) === true;
|
364
377
|
const [filepath, querystring = ""] = id.split("?");
|
365
378
|
const [extension = ""] = querystring.match(fileExtensionRE) || filepath.match(fileExtensionRE) || [];
|
@@ -367,10 +380,10 @@ function viteReact(opts = {}) {
|
|
367
380
|
const isJSX = extension.endsWith("x");
|
368
381
|
const isNodeModules = id.includes("/node_modules/");
|
369
382
|
const isProjectFile = !isNodeModules && (id[0] === "\0" || id.startsWith(projectRoot + "/"));
|
370
|
-
const plugins = isProjectFile ? [...
|
383
|
+
const plugins = isProjectFile ? [...babelOptions.plugins] : [];
|
371
384
|
let useFastRefresh = false;
|
372
385
|
if (!skipFastRefresh && !ssr && !isNodeModules) {
|
373
|
-
const isReactModule = isJSX ||
|
386
|
+
const isReactModule = isJSX || importReactRE.test(code);
|
374
387
|
if (isReactModule && filter(id)) {
|
375
388
|
useFastRefresh = true;
|
376
389
|
plugins.push([
|
@@ -404,12 +417,12 @@ function viteReact(opts = {}) {
|
|
404
417
|
}
|
405
418
|
}
|
406
419
|
}
|
407
|
-
const shouldSkip = !plugins.length && !
|
420
|
+
const shouldSkip = !plugins.length && !babelOptions.configFile && !(isProjectFile && babelOptions.babelrc);
|
408
421
|
if (shouldSkip) {
|
409
422
|
return;
|
410
423
|
}
|
411
424
|
const parserPlugins = [
|
412
|
-
...
|
425
|
+
...babelOptions.parserOpts.plugins,
|
413
426
|
"importMeta",
|
414
427
|
"topLevelAwait",
|
415
428
|
"classProperties",
|
@@ -422,28 +435,25 @@ function viteReact(opts = {}) {
|
|
422
435
|
if (/\.tsx?$/.test(extension)) {
|
423
436
|
parserPlugins.push("typescript");
|
424
437
|
}
|
438
|
+
const transformAsync2 = ast ? babel.transformFromAstAsync.bind(babel, ast, code) : babel.transformAsync.bind(babel, code);
|
425
439
|
const isReasonReact = extension.endsWith(".bs.js");
|
426
|
-
const
|
427
|
-
babelrc: false,
|
428
|
-
configFile: false
|
429
|
-
}, opts.babel), {
|
440
|
+
const result = await transformAsync2(__spreadProps(__spreadValues({}, babelOptions), {
|
430
441
|
ast: !isReasonReact,
|
431
442
|
root: projectRoot,
|
432
443
|
filename: id,
|
433
444
|
sourceFileName: filepath,
|
434
|
-
parserOpts: __spreadProps(__spreadValues({},
|
445
|
+
parserOpts: __spreadProps(__spreadValues({}, babelOptions.parserOpts), {
|
435
446
|
sourceType: "module",
|
436
447
|
allowAwaitOutsideFunction: true,
|
437
448
|
plugins: parserPlugins
|
438
449
|
}),
|
439
|
-
generatorOpts: __spreadProps(__spreadValues({},
|
450
|
+
generatorOpts: __spreadProps(__spreadValues({}, babelOptions.generatorOpts), {
|
440
451
|
decoratorsBeforeExport: true
|
441
452
|
}),
|
442
453
|
plugins,
|
443
454
|
sourceMaps: true,
|
444
455
|
inputSourceMap: false
|
445
|
-
});
|
446
|
-
const result = ast ? await babel.transformFromAstAsync(ast, code, babelOpts) : await babel.transformAsync(code, babelOpts);
|
456
|
+
}));
|
447
457
|
if (result) {
|
448
458
|
let code2 = result.code;
|
449
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/fast-refresh.ts
CHANGED
@@ -35,14 +35,14 @@ import RefreshRuntime from "${runtimePublicPath}";
|
|
35
35
|
let prevRefreshReg;
|
36
36
|
let prevRefreshSig;
|
37
37
|
|
38
|
-
if (!window.__vite_plugin_react_preamble_installed__) {
|
39
|
-
throw new Error(
|
40
|
-
"@vitejs/plugin-react can't detect preamble. Something is wrong. " +
|
41
|
-
"See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201"
|
42
|
-
);
|
43
|
-
}
|
44
|
-
|
45
38
|
if (import.meta.hot) {
|
39
|
+
if (!window.__vite_plugin_react_preamble_installed__) {
|
40
|
+
throw new Error(
|
41
|
+
"@vitejs/plugin-react can't detect preamble. Something is wrong. " +
|
42
|
+
"See https://github.com/vitejs/vite-plugin-react/pull/11#discussion_r430879201"
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
46
|
prevRefreshReg = window.$RefreshReg$;
|
47
47
|
prevRefreshSig = window.$RefreshSig$;
|
48
48
|
window.$RefreshReg$ = (type, id) => {
|
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> {
|
@@ -48,6 +49,8 @@ export async function restoreJSX(
|
|
48
49
|
babelRestoreJSX ||= import('./babel-restore-jsx')
|
49
50
|
|
50
51
|
const result = await babel.transformAsync(code, {
|
52
|
+
babelrc: false,
|
53
|
+
configFile: false,
|
51
54
|
ast: true,
|
52
55
|
code: false,
|
53
56
|
filename,
|