@vitejs/plugin-react 2.0.0-alpha.2 → 2.0.0-beta.1
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.cjs +59 -18
- package/dist/index.mjs +57 -16
- package/package.json +10 -12
- package/src/fast-refresh.ts +3 -3
- package/src/index.ts +58 -32
- package/src/jsx-runtime/restore-jsx.spec.ts +62 -1
- package/src/jsx-runtime/restore-jsx.ts +3 -3
package/dist/index.cjs
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
const path = require('path');
|
3
|
+
const path = require('node:path');
|
4
4
|
const babel = require('@babel/core');
|
5
|
-
const pluginutils = require('@rollup/pluginutils');
|
6
5
|
const vite = require('vite');
|
7
|
-
const fs = require('fs');
|
8
|
-
const
|
6
|
+
const fs = require('node:fs');
|
7
|
+
const node_module = require('node:module');
|
9
8
|
|
10
9
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
11
10
|
|
@@ -26,7 +25,7 @@ const babel__namespace = /*#__PURE__*/_interopNamespace(babel);
|
|
26
25
|
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
27
26
|
|
28
27
|
const runtimePublicPath = "/@react-refresh";
|
29
|
-
const _require =
|
28
|
+
const _require = node_module.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
|
30
29
|
const reactRefreshDir = path__default.dirname(_require.resolve("react-refresh/package.json"));
|
31
30
|
const runtimeFilePath = path__default.join(reactRefreshDir, "cjs/react-refresh-runtime.development.js");
|
32
31
|
const runtimeCode = `
|
@@ -173,11 +172,11 @@ async function restoreJSX(babel, code, filename) {
|
|
173
172
|
return [result?.ast, isCommonJS];
|
174
173
|
}
|
175
174
|
function parseReactAlias(code) {
|
176
|
-
let match = code.match(/\b(var|let|const)
|
175
|
+
let match = code.match(/\b(var|let|const)\s+([^=\{\s]+)\s*=\s*require\(["']react["']\)/);
|
177
176
|
if (match) {
|
178
177
|
return [match[2], true];
|
179
178
|
}
|
180
|
-
match = code.match(/^import
|
179
|
+
match = code.match(/^import\s+(?:\*\s+as\s+)?(\w+).+?\bfrom\s*["']react["']/m);
|
181
180
|
if (match) {
|
182
181
|
return [match[1], false];
|
183
182
|
}
|
@@ -185,9 +184,9 @@ function parseReactAlias(code) {
|
|
185
184
|
}
|
186
185
|
|
187
186
|
function viteReact(opts = {}) {
|
188
|
-
let
|
187
|
+
let devBase = "/";
|
189
188
|
let resolvedCacheDir;
|
190
|
-
let filter =
|
189
|
+
let filter = vite.createFilter(opts.include, opts.exclude);
|
191
190
|
let isProduction = true;
|
192
191
|
let projectRoot = process.cwd();
|
193
192
|
let skipFastRefresh = opts.fastRefresh === false;
|
@@ -200,11 +199,22 @@ function viteReact(opts = {}) {
|
|
200
199
|
const viteBabel = {
|
201
200
|
name: "vite:react-babel",
|
202
201
|
enforce: "pre",
|
202
|
+
config() {
|
203
|
+
if (opts.jsxRuntime === "classic") {
|
204
|
+
return {
|
205
|
+
esbuild: {
|
206
|
+
logOverride: {
|
207
|
+
"this-is-undefined-in-esm": "silent"
|
208
|
+
}
|
209
|
+
}
|
210
|
+
};
|
211
|
+
}
|
212
|
+
},
|
203
213
|
configResolved(config) {
|
204
|
-
|
214
|
+
devBase = config.base;
|
205
215
|
projectRoot = config.root;
|
206
216
|
resolvedCacheDir = vite.normalizePath(path__default.resolve(config.cacheDir));
|
207
|
-
filter =
|
217
|
+
filter = vite.createFilter(opts.include, opts.exclude, {
|
208
218
|
resolve: projectRoot
|
209
219
|
});
|
210
220
|
isProduction = config.isProduction;
|
@@ -222,17 +232,17 @@ function viteReact(opts = {}) {
|
|
222
232
|
runPluginOverrides = (babelOptions, context) => {
|
223
233
|
const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(Boolean);
|
224
234
|
if (hooks.length > 0) {
|
225
|
-
return (runPluginOverrides = (babelOptions2) => {
|
226
|
-
hooks.forEach((hook) => hook(babelOptions2,
|
235
|
+
return (runPluginOverrides = (babelOptions2, context2) => {
|
236
|
+
hooks.forEach((hook) => hook(babelOptions2, context2, config));
|
227
237
|
return true;
|
228
|
-
})(babelOptions);
|
238
|
+
})(babelOptions, context);
|
229
239
|
}
|
230
240
|
runPluginOverrides = () => false;
|
231
241
|
return false;
|
232
242
|
};
|
233
243
|
},
|
234
244
|
async transform(code, id, options) {
|
235
|
-
const ssr =
|
245
|
+
const ssr = options?.ssr === true;
|
236
246
|
const [filepath, querystring = ""] = id.split("?");
|
237
247
|
const [extension = ""] = querystring.match(fileExtensionRE) || filepath.match(fileExtensionRE) || [];
|
238
248
|
if (/\.(mjs|[tj]sx?)$/.test(extension)) {
|
@@ -291,7 +301,9 @@ function viteReact(opts = {}) {
|
|
291
301
|
}
|
292
302
|
const shouldSkip = !plugins.length && !babelOptions.configFile && !(isProjectFile && babelOptions.babelrc);
|
293
303
|
if (shouldSkip) {
|
294
|
-
return
|
304
|
+
return {
|
305
|
+
code
|
306
|
+
};
|
295
307
|
}
|
296
308
|
const parserPlugins = [
|
297
309
|
...babelOptions.parserOpts.plugins,
|
@@ -367,20 +379,49 @@ function viteReact(opts = {}) {
|
|
367
379
|
{
|
368
380
|
tag: "script",
|
369
381
|
attrs: { type: "module" },
|
370
|
-
children: preambleCode.replace(`__BASE__`,
|
382
|
+
children: preambleCode.replace(`__BASE__`, devBase)
|
371
383
|
}
|
372
384
|
];
|
373
385
|
}
|
374
386
|
};
|
387
|
+
const reactJsxRuntimeId = "react/jsx-runtime";
|
388
|
+
const reactJsxDevRuntimeId = "react/jsx-dev-runtime";
|
389
|
+
const virtualReactJsxRuntimeId = "\0" + reactJsxRuntimeId;
|
390
|
+
const virtualReactJsxDevRuntimeId = "\0" + reactJsxDevRuntimeId;
|
375
391
|
const viteReactJsx = {
|
376
392
|
name: "vite:react-jsx",
|
377
393
|
enforce: "pre",
|
378
394
|
config() {
|
379
395
|
return {
|
380
396
|
optimizeDeps: {
|
381
|
-
include: [
|
397
|
+
include: [reactJsxRuntimeId, reactJsxDevRuntimeId]
|
382
398
|
}
|
383
399
|
};
|
400
|
+
},
|
401
|
+
resolveId(id, importer) {
|
402
|
+
if (id === reactJsxRuntimeId && importer !== virtualReactJsxRuntimeId) {
|
403
|
+
return virtualReactJsxRuntimeId;
|
404
|
+
}
|
405
|
+
if (id === reactJsxDevRuntimeId && importer !== virtualReactJsxDevRuntimeId) {
|
406
|
+
return virtualReactJsxDevRuntimeId;
|
407
|
+
}
|
408
|
+
},
|
409
|
+
load(id) {
|
410
|
+
if (id === virtualReactJsxRuntimeId) {
|
411
|
+
return [
|
412
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxRuntimeId)}`,
|
413
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
414
|
+
`export const jsx = jsxRuntime.jsx`,
|
415
|
+
`export const jsxs = jsxRuntime.jsxs`
|
416
|
+
].join("\n");
|
417
|
+
}
|
418
|
+
if (id === virtualReactJsxDevRuntimeId) {
|
419
|
+
return [
|
420
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxDevRuntimeId)}`,
|
421
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
422
|
+
`export const jsxDEV = jsxRuntime.jsxDEV`
|
423
|
+
].join("\n");
|
424
|
+
}
|
384
425
|
}
|
385
426
|
};
|
386
427
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx];
|
package/dist/index.mjs
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
import path from 'path';
|
1
|
+
import path from 'node:path';
|
2
2
|
import * as babel from '@babel/core';
|
3
|
-
import { createFilter } from '
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import { createRequire } from 'module';
|
3
|
+
import { createFilter, normalizePath } from 'vite';
|
4
|
+
import fs from 'node:fs';
|
5
|
+
import { createRequire } from 'node:module';
|
7
6
|
|
8
7
|
const runtimePublicPath = "/@react-refresh";
|
9
8
|
const _require = createRequire(import.meta.url);
|
@@ -153,11 +152,11 @@ async function restoreJSX(babel, code, filename) {
|
|
153
152
|
return [result?.ast, isCommonJS];
|
154
153
|
}
|
155
154
|
function parseReactAlias(code) {
|
156
|
-
let match = code.match(/\b(var|let|const)
|
155
|
+
let match = code.match(/\b(var|let|const)\s+([^=\{\s]+)\s*=\s*require\(["']react["']\)/);
|
157
156
|
if (match) {
|
158
157
|
return [match[2], true];
|
159
158
|
}
|
160
|
-
match = code.match(/^import
|
159
|
+
match = code.match(/^import\s+(?:\*\s+as\s+)?(\w+).+?\bfrom\s*["']react["']/m);
|
161
160
|
if (match) {
|
162
161
|
return [match[1], false];
|
163
162
|
}
|
@@ -165,7 +164,7 @@ function parseReactAlias(code) {
|
|
165
164
|
}
|
166
165
|
|
167
166
|
function viteReact(opts = {}) {
|
168
|
-
let
|
167
|
+
let devBase = "/";
|
169
168
|
let resolvedCacheDir;
|
170
169
|
let filter = createFilter(opts.include, opts.exclude);
|
171
170
|
let isProduction = true;
|
@@ -180,8 +179,19 @@ function viteReact(opts = {}) {
|
|
180
179
|
const viteBabel = {
|
181
180
|
name: "vite:react-babel",
|
182
181
|
enforce: "pre",
|
182
|
+
config() {
|
183
|
+
if (opts.jsxRuntime === "classic") {
|
184
|
+
return {
|
185
|
+
esbuild: {
|
186
|
+
logOverride: {
|
187
|
+
"this-is-undefined-in-esm": "silent"
|
188
|
+
}
|
189
|
+
}
|
190
|
+
};
|
191
|
+
}
|
192
|
+
},
|
183
193
|
configResolved(config) {
|
184
|
-
|
194
|
+
devBase = config.base;
|
185
195
|
projectRoot = config.root;
|
186
196
|
resolvedCacheDir = normalizePath(path.resolve(config.cacheDir));
|
187
197
|
filter = createFilter(opts.include, opts.exclude, {
|
@@ -202,17 +212,17 @@ function viteReact(opts = {}) {
|
|
202
212
|
runPluginOverrides = (babelOptions, context) => {
|
203
213
|
const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(Boolean);
|
204
214
|
if (hooks.length > 0) {
|
205
|
-
return (runPluginOverrides = (babelOptions2) => {
|
206
|
-
hooks.forEach((hook) => hook(babelOptions2,
|
215
|
+
return (runPluginOverrides = (babelOptions2, context2) => {
|
216
|
+
hooks.forEach((hook) => hook(babelOptions2, context2, config));
|
207
217
|
return true;
|
208
|
-
})(babelOptions);
|
218
|
+
})(babelOptions, context);
|
209
219
|
}
|
210
220
|
runPluginOverrides = () => false;
|
211
221
|
return false;
|
212
222
|
};
|
213
223
|
},
|
214
224
|
async transform(code, id, options) {
|
215
|
-
const ssr =
|
225
|
+
const ssr = options?.ssr === true;
|
216
226
|
const [filepath, querystring = ""] = id.split("?");
|
217
227
|
const [extension = ""] = querystring.match(fileExtensionRE) || filepath.match(fileExtensionRE) || [];
|
218
228
|
if (/\.(mjs|[tj]sx?)$/.test(extension)) {
|
@@ -271,7 +281,9 @@ function viteReact(opts = {}) {
|
|
271
281
|
}
|
272
282
|
const shouldSkip = !plugins.length && !babelOptions.configFile && !(isProjectFile && babelOptions.babelrc);
|
273
283
|
if (shouldSkip) {
|
274
|
-
return
|
284
|
+
return {
|
285
|
+
code
|
286
|
+
};
|
275
287
|
}
|
276
288
|
const parserPlugins = [
|
277
289
|
...babelOptions.parserOpts.plugins,
|
@@ -347,20 +359,49 @@ function viteReact(opts = {}) {
|
|
347
359
|
{
|
348
360
|
tag: "script",
|
349
361
|
attrs: { type: "module" },
|
350
|
-
children: preambleCode.replace(`__BASE__`,
|
362
|
+
children: preambleCode.replace(`__BASE__`, devBase)
|
351
363
|
}
|
352
364
|
];
|
353
365
|
}
|
354
366
|
};
|
367
|
+
const reactJsxRuntimeId = "react/jsx-runtime";
|
368
|
+
const reactJsxDevRuntimeId = "react/jsx-dev-runtime";
|
369
|
+
const virtualReactJsxRuntimeId = "\0" + reactJsxRuntimeId;
|
370
|
+
const virtualReactJsxDevRuntimeId = "\0" + reactJsxDevRuntimeId;
|
355
371
|
const viteReactJsx = {
|
356
372
|
name: "vite:react-jsx",
|
357
373
|
enforce: "pre",
|
358
374
|
config() {
|
359
375
|
return {
|
360
376
|
optimizeDeps: {
|
361
|
-
include: [
|
377
|
+
include: [reactJsxRuntimeId, reactJsxDevRuntimeId]
|
362
378
|
}
|
363
379
|
};
|
380
|
+
},
|
381
|
+
resolveId(id, importer) {
|
382
|
+
if (id === reactJsxRuntimeId && importer !== virtualReactJsxRuntimeId) {
|
383
|
+
return virtualReactJsxRuntimeId;
|
384
|
+
}
|
385
|
+
if (id === reactJsxDevRuntimeId && importer !== virtualReactJsxDevRuntimeId) {
|
386
|
+
return virtualReactJsxDevRuntimeId;
|
387
|
+
}
|
388
|
+
},
|
389
|
+
load(id) {
|
390
|
+
if (id === virtualReactJsxRuntimeId) {
|
391
|
+
return [
|
392
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxRuntimeId)}`,
|
393
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
394
|
+
`export const jsx = jsxRuntime.jsx`,
|
395
|
+
`export const jsxs = jsxRuntime.jsxs`
|
396
|
+
].join("\n");
|
397
|
+
}
|
398
|
+
if (id === virtualReactJsxDevRuntimeId) {
|
399
|
+
return [
|
400
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxDevRuntimeId)}`,
|
401
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
402
|
+
`export const jsxDEV = jsxRuntime.jsxDEV`
|
403
|
+
].join("\n");
|
404
|
+
}
|
364
405
|
}
|
365
406
|
};
|
366
407
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx];
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitejs/plugin-react",
|
3
|
-
"version": "2.0.0-
|
3
|
+
"version": "2.0.0-beta.1",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Evan You",
|
6
6
|
"contributors": [
|
@@ -23,11 +23,11 @@
|
|
23
23
|
"scripts": {
|
24
24
|
"dev": "unbuild --stub",
|
25
25
|
"build": "unbuild && pnpm run patch-cjs",
|
26
|
-
"patch-cjs": "
|
26
|
+
"patch-cjs": "tsx ../../scripts/patchCJS.ts",
|
27
27
|
"prepublishOnly": "npm run build"
|
28
28
|
},
|
29
29
|
"engines": {
|
30
|
-
"node": ">=14.
|
30
|
+
"node": ">=14.18.0"
|
31
31
|
},
|
32
32
|
"repository": {
|
33
33
|
"type": "git",
|
@@ -39,17 +39,15 @@
|
|
39
39
|
},
|
40
40
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme",
|
41
41
|
"dependencies": {
|
42
|
-
"@babel/core": "^7.18.
|
43
|
-
"@babel/plugin-transform-react-jsx": "^7.
|
44
|
-
"@babel/plugin-transform-react-jsx-development": "^7.
|
45
|
-
"@babel/plugin-transform-react-jsx-self": "^7.
|
46
|
-
"@babel/plugin-transform-react-jsx-source": "^7.
|
47
|
-
"
|
48
|
-
"react-refresh": "^0.13.0",
|
49
|
-
"resolve": "^1.22.0"
|
42
|
+
"@babel/core": "^7.18.6",
|
43
|
+
"@babel/plugin-transform-react-jsx": "^7.18.6",
|
44
|
+
"@babel/plugin-transform-react-jsx-development": "^7.18.6",
|
45
|
+
"@babel/plugin-transform-react-jsx-self": "^7.18.6",
|
46
|
+
"@babel/plugin-transform-react-jsx-source": "^7.18.6",
|
47
|
+
"react-refresh": "^0.14.0"
|
50
48
|
},
|
51
49
|
"peerDependencies": {
|
52
|
-
"vite": "^3.0.0-alpha"
|
50
|
+
"vite": "^3.0.0-alpha.11"
|
53
51
|
},
|
54
52
|
"devDependencies": {
|
55
53
|
"vite": "workspace:*"
|
package/src/fast-refresh.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import fs from 'fs'
|
2
|
-
import path from 'path'
|
3
|
-
import { createRequire } from 'module'
|
1
|
+
import fs from 'node:fs'
|
2
|
+
import path from 'node:path'
|
3
|
+
import { createRequire } from 'node:module'
|
4
4
|
import type { types as t } from '@babel/core'
|
5
5
|
|
6
6
|
export const runtimePublicPath = '/@react-refresh'
|
package/src/index.ts
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
import path from 'path'
|
1
|
+
import path from 'node:path'
|
2
2
|
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
|
3
3
|
import * as babel from '@babel/core'
|
4
|
-
import { createFilter } from '
|
5
|
-
import { normalizePath } from 'vite'
|
4
|
+
import { createFilter, normalizePath } from 'vite'
|
6
5
|
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
|
7
6
|
import {
|
8
7
|
addRefreshWrapper,
|
@@ -91,7 +90,7 @@ declare module 'vite' {
|
|
91
90
|
|
92
91
|
export default function viteReact(opts: Options = {}): PluginOption[] {
|
93
92
|
// Provide default values for Rollup compat.
|
94
|
-
let
|
93
|
+
let devBase = '/'
|
95
94
|
let resolvedCacheDir: string
|
96
95
|
let filter = createFilter(opts.include, opts.exclude)
|
97
96
|
let isProduction = true
|
@@ -118,8 +117,19 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
118
117
|
const viteBabel: Plugin = {
|
119
118
|
name: 'vite:react-babel',
|
120
119
|
enforce: 'pre',
|
120
|
+
config() {
|
121
|
+
if (opts.jsxRuntime === 'classic') {
|
122
|
+
return {
|
123
|
+
esbuild: {
|
124
|
+
logOverride: {
|
125
|
+
'this-is-undefined-in-esm': 'silent'
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
},
|
121
131
|
configResolved(config) {
|
122
|
-
|
132
|
+
devBase = config.base
|
123
133
|
projectRoot = config.root
|
124
134
|
resolvedCacheDir = normalizePath(path.resolve(config.cacheDir))
|
125
135
|
filter = createFilter(opts.include, opts.exclude, {
|
@@ -155,17 +165,17 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
155
165
|
.filter(Boolean) as ReactBabelHook[]
|
156
166
|
|
157
167
|
if (hooks.length > 0) {
|
158
|
-
return (runPluginOverrides = (babelOptions) => {
|
168
|
+
return (runPluginOverrides = (babelOptions, context) => {
|
159
169
|
hooks.forEach((hook) => hook(babelOptions, context, config))
|
160
170
|
return true
|
161
|
-
})(babelOptions)
|
171
|
+
})(babelOptions, context)
|
162
172
|
}
|
163
173
|
runPluginOverrides = () => false
|
164
174
|
return false
|
165
175
|
}
|
166
176
|
},
|
167
177
|
async transform(code, id, options) {
|
168
|
-
const ssr =
|
178
|
+
const ssr = options?.ssr === true
|
169
179
|
// File extension could be mocked/overridden in querystring.
|
170
180
|
const [filepath, querystring = ''] = id.split('?')
|
171
181
|
const [extension = ''] =
|
@@ -266,7 +276,10 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
266
276
|
!(isProjectFile && babelOptions.babelrc)
|
267
277
|
|
268
278
|
if (shouldSkip) {
|
269
|
-
|
279
|
+
// Avoid parsing if no plugins exist.
|
280
|
+
return {
|
281
|
+
code
|
282
|
+
}
|
270
283
|
}
|
271
284
|
|
272
285
|
const parserPlugins: typeof babelOptions.parserOpts.plugins = [
|
@@ -355,13 +368,16 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
355
368
|
{
|
356
369
|
tag: 'script',
|
357
370
|
attrs: { type: 'module' },
|
358
|
-
children: preambleCode.replace(`__BASE__`,
|
371
|
+
children: preambleCode.replace(`__BASE__`, devBase)
|
359
372
|
}
|
360
373
|
]
|
361
374
|
}
|
362
375
|
}
|
363
376
|
|
364
|
-
|
377
|
+
const reactJsxRuntimeId = 'react/jsx-runtime'
|
378
|
+
const reactJsxDevRuntimeId = 'react/jsx-dev-runtime'
|
379
|
+
const virtualReactJsxRuntimeId = '\0' + reactJsxRuntimeId
|
380
|
+
const virtualReactJsxDevRuntimeId = '\0' + reactJsxDevRuntimeId
|
365
381
|
// Adapted from https://github.com/alloc/vite-react-jsx
|
366
382
|
const viteReactJsx: Plugin = {
|
367
383
|
name: 'vite:react-jsx',
|
@@ -369,32 +385,42 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
369
385
|
config() {
|
370
386
|
return {
|
371
387
|
optimizeDeps: {
|
372
|
-
include: [
|
388
|
+
include: [reactJsxRuntimeId, reactJsxDevRuntimeId]
|
373
389
|
}
|
374
390
|
}
|
375
|
-
}
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
391
|
+
},
|
392
|
+
resolveId(id, importer) {
|
393
|
+
// Resolve runtime to a virtual path to be interoped.
|
394
|
+
// Since the interop code re-imports `id`, we need to prevent re-resolving
|
395
|
+
// to the virtual id if the importer is already the virtual id.
|
396
|
+
if (id === reactJsxRuntimeId && importer !== virtualReactJsxRuntimeId) {
|
397
|
+
return virtualReactJsxRuntimeId
|
398
|
+
}
|
399
|
+
if (
|
400
|
+
id === reactJsxDevRuntimeId &&
|
401
|
+
importer !== virtualReactJsxDevRuntimeId
|
402
|
+
) {
|
403
|
+
return virtualReactJsxDevRuntimeId
|
404
|
+
}
|
405
|
+
},
|
406
|
+
load(id) {
|
407
|
+
// Apply manual interop
|
408
|
+
if (id === virtualReactJsxRuntimeId) {
|
389
409
|
return [
|
390
|
-
`import * as jsxRuntime from ${JSON.stringify(
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
|
410
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxRuntimeId)}`,
|
411
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
412
|
+
`export const jsx = jsxRuntime.jsx`,
|
413
|
+
`export const jsxs = jsxRuntime.jsxs`
|
395
414
|
].join('\n')
|
396
415
|
}
|
397
|
-
|
416
|
+
if (id === virtualReactJsxDevRuntimeId) {
|
417
|
+
return [
|
418
|
+
`import * as jsxRuntime from ${JSON.stringify(reactJsxDevRuntimeId)}`,
|
419
|
+
`export const Fragment = jsxRuntime.Fragment`,
|
420
|
+
`export const jsxDEV = jsxRuntime.jsxDEV`
|
421
|
+
].join('\n')
|
422
|
+
}
|
423
|
+
}
|
398
424
|
}
|
399
425
|
|
400
426
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx]
|
@@ -1,6 +1,67 @@
|
|
1
1
|
import * as babel from '@babel/core'
|
2
2
|
import { describe, expect, it } from 'vitest'
|
3
|
-
import { restoreJSX } from './restore-jsx'
|
3
|
+
import { parseReactAlias, restoreJSX } from './restore-jsx'
|
4
|
+
|
5
|
+
describe('parseReactAlias', () => {
|
6
|
+
it('handles cjs require', () => {
|
7
|
+
expect(parseReactAlias(`const React = require("react")`))
|
8
|
+
.toMatchInlineSnapshot(`
|
9
|
+
[
|
10
|
+
"React",
|
11
|
+
true,
|
12
|
+
]
|
13
|
+
`)
|
14
|
+
})
|
15
|
+
|
16
|
+
it('handles cjs require (minified)', () => {
|
17
|
+
expect(parseReactAlias(`var F=require('foo');var R=require('react')`))
|
18
|
+
.toMatchInlineSnapshot(`
|
19
|
+
[
|
20
|
+
"R",
|
21
|
+
true,
|
22
|
+
]
|
23
|
+
`)
|
24
|
+
})
|
25
|
+
|
26
|
+
it('does not handle destructured cjs require', () => {
|
27
|
+
expect(parseReactAlias(`var {createElement} = require("react")`))
|
28
|
+
.toMatchInlineSnapshot(`
|
29
|
+
[
|
30
|
+
undefined,
|
31
|
+
false,
|
32
|
+
]
|
33
|
+
`)
|
34
|
+
})
|
35
|
+
|
36
|
+
it('handles esm import', () => {
|
37
|
+
expect(parseReactAlias(`import React from 'react'`)).toMatchInlineSnapshot(`
|
38
|
+
[
|
39
|
+
"React",
|
40
|
+
false,
|
41
|
+
]
|
42
|
+
`)
|
43
|
+
})
|
44
|
+
|
45
|
+
it('handles esm import namespace', () => {
|
46
|
+
expect(parseReactAlias(`import * as React from "react"`))
|
47
|
+
.toMatchInlineSnapshot(`
|
48
|
+
[
|
49
|
+
"React",
|
50
|
+
false,
|
51
|
+
]
|
52
|
+
`)
|
53
|
+
})
|
54
|
+
|
55
|
+
it('does not handle destructured esm import', () => {
|
56
|
+
expect(parseReactAlias(`import {createElement} from "react"`))
|
57
|
+
.toMatchInlineSnapshot(`
|
58
|
+
[
|
59
|
+
undefined,
|
60
|
+
false,
|
61
|
+
]
|
62
|
+
`)
|
63
|
+
})
|
64
|
+
})
|
4
65
|
|
5
66
|
async function jsx(sourceCode: string) {
|
6
67
|
const [ast] = await restoreJSX(babel, sourceCode, 'test.js')
|
@@ -79,16 +79,16 @@ export async function restoreJSX(
|
|
79
79
|
return [result?.ast, isCommonJS]
|
80
80
|
}
|
81
81
|
|
82
|
-
function parseReactAlias(
|
82
|
+
export function parseReactAlias(
|
83
83
|
code: string
|
84
84
|
): [alias: string | undefined, isCommonJS: boolean] {
|
85
85
|
let match = code.match(
|
86
|
-
/\b(var|let|const)
|
86
|
+
/\b(var|let|const)\s+([^=\{\s]+)\s*=\s*require\(["']react["']\)/
|
87
87
|
)
|
88
88
|
if (match) {
|
89
89
|
return [match[2], true]
|
90
90
|
}
|
91
|
-
match = code.match(/^import
|
91
|
+
match = code.match(/^import\s+(?:\*\s+as\s+)?(\w+).+?\bfrom\s*["']react["']/m)
|
92
92
|
if (match) {
|
93
93
|
return [match[1], false]
|
94
94
|
}
|