@vitejs/plugin-react 2.0.0-alpha.1 → 2.0.0-alpha.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.cjs +47 -40
- package/dist/index.d.ts +9 -2
- package/dist/index.mjs +46 -38
- package/package.json +5 -5
- package/src/index.ts +76 -23
- package/src/jsx-runtime/restore-jsx.ts +0 -6
package/dist/index.cjs
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
+
const path = require('path');
|
3
4
|
const babel = require('@babel/core');
|
4
5
|
const pluginutils = require('@rollup/pluginutils');
|
5
|
-
const
|
6
|
+
const vite = require('vite');
|
6
7
|
const fs = require('fs');
|
7
|
-
const path = require('path');
|
8
8
|
const module$1 = require('module');
|
9
9
|
|
10
10
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
@@ -21,10 +21,9 @@ function _interopNamespace(e) {
|
|
21
21
|
return n;
|
22
22
|
}
|
23
23
|
|
24
|
+
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
24
25
|
const babel__namespace = /*#__PURE__*/_interopNamespace(babel);
|
25
|
-
const resolve__default = /*#__PURE__*/_interopDefaultLegacy(resolve);
|
26
26
|
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
27
|
-
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
28
27
|
|
29
28
|
const runtimePublicPath = "/@react-refresh";
|
30
29
|
const _require = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
|
@@ -140,9 +139,6 @@ async function getBabelRestoreJSX() {
|
|
140
139
|
return babelRestoreJSX;
|
141
140
|
}
|
142
141
|
async function restoreJSX(babel, code, filename) {
|
143
|
-
if (filename.includes("/.vite/react-dom.js")) {
|
144
|
-
return jsxNotFound;
|
145
|
-
}
|
146
142
|
const [reactAlias, isCommonJS] = parseReactAlias(code);
|
147
143
|
if (!reactAlias) {
|
148
144
|
return jsxNotFound;
|
@@ -189,24 +185,16 @@ function parseReactAlias(code) {
|
|
189
185
|
}
|
190
186
|
|
191
187
|
function viteReact(opts = {}) {
|
192
|
-
var _a;
|
193
188
|
let base = "/";
|
189
|
+
let resolvedCacheDir;
|
194
190
|
let filter = pluginutils.createFilter(opts.include, opts.exclude);
|
195
191
|
let isProduction = true;
|
196
192
|
let projectRoot = process.cwd();
|
197
193
|
let skipFastRefresh = opts.fastRefresh === false;
|
198
194
|
let skipReactImport = false;
|
195
|
+
let runPluginOverrides = (options, context) => false;
|
196
|
+
let staticBabelOptions;
|
199
197
|
const useAutomaticRuntime = opts.jsxRuntime !== "classic";
|
200
|
-
const babelOptions = {
|
201
|
-
babelrc: false,
|
202
|
-
configFile: false,
|
203
|
-
...opts.babel
|
204
|
-
};
|
205
|
-
babelOptions.plugins || (babelOptions.plugins = []);
|
206
|
-
babelOptions.presets || (babelOptions.presets = []);
|
207
|
-
babelOptions.overrides || (babelOptions.overrides = []);
|
208
|
-
babelOptions.parserOpts || (babelOptions.parserOpts = {});
|
209
|
-
(_a = babelOptions.parserOpts).plugins || (_a.plugins = []);
|
210
198
|
const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/;
|
211
199
|
const fileExtensionRE = /\.[^\/\s\?]+$/;
|
212
200
|
const viteBabel = {
|
@@ -215,6 +203,7 @@ function viteReact(opts = {}) {
|
|
215
203
|
configResolved(config) {
|
216
204
|
base = config.base;
|
217
205
|
projectRoot = config.root;
|
206
|
+
resolvedCacheDir = vite.normalizePath(path__default.resolve(config.cacheDir));
|
218
207
|
filter = pluginutils.createFilter(opts.include, opts.exclude, {
|
219
208
|
resolve: projectRoot
|
220
209
|
});
|
@@ -229,10 +218,18 @@ function viteReact(opts = {}) {
|
|
229
218
|
const hasConflict = plugin.name === "react-refresh" || plugin !== viteReactJsx && plugin.name === "vite:react-jsx";
|
230
219
|
if (hasConflict)
|
231
220
|
return config.logger.warn(`[@vitejs/plugin-react] You should stop using "${plugin.name}" since this plugin conflicts with it.`);
|
232
|
-
if (plugin.api?.reactBabel) {
|
233
|
-
plugin.api.reactBabel(babelOptions, config);
|
234
|
-
}
|
235
221
|
});
|
222
|
+
runPluginOverrides = (babelOptions, context) => {
|
223
|
+
const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(Boolean);
|
224
|
+
if (hooks.length > 0) {
|
225
|
+
return (runPluginOverrides = (babelOptions2) => {
|
226
|
+
hooks.forEach((hook) => hook(babelOptions2, context, config));
|
227
|
+
return true;
|
228
|
+
})(babelOptions);
|
229
|
+
}
|
230
|
+
runPluginOverrides = () => false;
|
231
|
+
return false;
|
232
|
+
};
|
236
233
|
},
|
237
234
|
async transform(code, id, options) {
|
238
235
|
const ssr = typeof options === "boolean" ? options : options?.ssr === true;
|
@@ -242,6 +239,17 @@ function viteReact(opts = {}) {
|
|
242
239
|
const isJSX = extension.endsWith("x");
|
243
240
|
const isNodeModules = id.includes("/node_modules/");
|
244
241
|
const isProjectFile = !isNodeModules && (id[0] === "\0" || id.startsWith(projectRoot + "/"));
|
242
|
+
let babelOptions = staticBabelOptions;
|
243
|
+
if (typeof opts.babel === "function") {
|
244
|
+
const rawOptions = opts.babel(id, { ssr });
|
245
|
+
babelOptions = createBabelOptions(rawOptions);
|
246
|
+
runPluginOverrides(babelOptions, { ssr, id });
|
247
|
+
} else if (!babelOptions) {
|
248
|
+
babelOptions = createBabelOptions(opts.babel);
|
249
|
+
if (!runPluginOverrides(babelOptions, { ssr, id })) {
|
250
|
+
staticBabelOptions = babelOptions;
|
251
|
+
}
|
252
|
+
}
|
245
253
|
const plugins = isProjectFile ? [...babelOptions.plugins] : [];
|
246
254
|
let useFastRefresh = false;
|
247
255
|
if (!skipFastRefresh && !ssr && !isNodeModules) {
|
@@ -257,7 +265,8 @@ function viteReact(opts = {}) {
|
|
257
265
|
let ast;
|
258
266
|
if (!isProjectFile || isJSX) {
|
259
267
|
if (useAutomaticRuntime) {
|
260
|
-
const
|
268
|
+
const isOptimizedReactDom = id.startsWith(resolvedCacheDir) && id.includes("/react-dom.js");
|
269
|
+
const [restoredAst, isCommonJS] = !isProjectFile && !isJSX && !isOptimizedReactDom ? await restoreJSX(babel__namespace, code, id) : [null, false];
|
261
270
|
if (isJSX || (ast = restoredAst)) {
|
262
271
|
plugins.push([
|
263
272
|
await loadPlugin("@babel/plugin-transform-react-jsx" + (isProduction ? "" : "-development")),
|
@@ -363,7 +372,6 @@ function viteReact(opts = {}) {
|
|
363
372
|
];
|
364
373
|
}
|
365
374
|
};
|
366
|
-
const runtimeId = "react/jsx-runtime";
|
367
375
|
const viteReactJsx = {
|
368
376
|
name: "vite:react-jsx",
|
369
377
|
enforce: "pre",
|
@@ -373,28 +381,27 @@ function viteReact(opts = {}) {
|
|
373
381
|
include: ["react/jsx-dev-runtime"]
|
374
382
|
}
|
375
383
|
};
|
376
|
-
},
|
377
|
-
resolveId(id) {
|
378
|
-
return id === runtimeId ? id : null;
|
379
|
-
},
|
380
|
-
load(id) {
|
381
|
-
if (id === runtimeId) {
|
382
|
-
const runtimePath = resolve__default.sync(runtimeId, {
|
383
|
-
basedir: projectRoot
|
384
|
-
});
|
385
|
-
const exports = ["jsx", "jsxs", "Fragment"];
|
386
|
-
return [
|
387
|
-
`import * as jsxRuntime from ${JSON.stringify(runtimePath)}`,
|
388
|
-
...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
|
389
|
-
].join("\n");
|
390
|
-
}
|
391
384
|
}
|
392
385
|
};
|
393
386
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx];
|
394
387
|
}
|
395
388
|
viteReact.preambleCode = preambleCode;
|
396
|
-
function loadPlugin(
|
397
|
-
return import(
|
389
|
+
function loadPlugin(path2) {
|
390
|
+
return import(path2).then((module) => module.default || module);
|
391
|
+
}
|
392
|
+
function createBabelOptions(rawOptions) {
|
393
|
+
var _a;
|
394
|
+
const babelOptions = {
|
395
|
+
babelrc: false,
|
396
|
+
configFile: false,
|
397
|
+
...rawOptions
|
398
|
+
};
|
399
|
+
babelOptions.plugins || (babelOptions.plugins = []);
|
400
|
+
babelOptions.presets || (babelOptions.presets = []);
|
401
|
+
babelOptions.overrides || (babelOptions.overrides = []);
|
402
|
+
babelOptions.parserOpts || (babelOptions.parserOpts = {});
|
403
|
+
(_a = babelOptions.parserOpts).plugins || (_a.plugins = []);
|
404
|
+
return babelOptions;
|
398
405
|
}
|
399
406
|
|
400
407
|
module.exports = viteReact;
|
package/dist/index.d.ts
CHANGED
@@ -29,7 +29,9 @@ interface Options {
|
|
29
29
|
/**
|
30
30
|
* Babel configuration applied in both dev and prod.
|
31
31
|
*/
|
32
|
-
babel?: BabelOptions
|
32
|
+
babel?: BabelOptions | ((id: string, options: {
|
33
|
+
ssr?: boolean;
|
34
|
+
}) => BabelOptions);
|
33
35
|
}
|
34
36
|
declare type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
|
35
37
|
/**
|
@@ -44,13 +46,18 @@ interface ReactBabelOptions extends BabelOptions {
|
|
44
46
|
plugins: Extract<ParserOptions['plugins'], any[]>;
|
45
47
|
};
|
46
48
|
}
|
49
|
+
declare type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void;
|
50
|
+
declare type ReactBabelHookContext = {
|
51
|
+
ssr: boolean;
|
52
|
+
id: string;
|
53
|
+
};
|
47
54
|
declare module 'vite' {
|
48
55
|
interface Plugin {
|
49
56
|
api?: {
|
50
57
|
/**
|
51
58
|
* Manipulate the Babel options of `@vitejs/plugin-react`
|
52
59
|
*/
|
53
|
-
reactBabel?:
|
60
|
+
reactBabel?: ReactBabelHook;
|
54
61
|
};
|
55
62
|
}
|
56
63
|
}
|
package/dist/index.mjs
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
import path from 'path';
|
1
2
|
import * as babel from '@babel/core';
|
2
3
|
import { createFilter } from '@rollup/pluginutils';
|
3
|
-
import
|
4
|
+
import { normalizePath } from 'vite';
|
4
5
|
import fs from 'fs';
|
5
|
-
import path from 'path';
|
6
6
|
import { createRequire } from 'module';
|
7
7
|
|
8
8
|
const runtimePublicPath = "/@react-refresh";
|
@@ -119,9 +119,6 @@ async function getBabelRestoreJSX() {
|
|
119
119
|
return babelRestoreJSX;
|
120
120
|
}
|
121
121
|
async function restoreJSX(babel, code, filename) {
|
122
|
-
if (filename.includes("/.vite/react-dom.js")) {
|
123
|
-
return jsxNotFound;
|
124
|
-
}
|
125
122
|
const [reactAlias, isCommonJS] = parseReactAlias(code);
|
126
123
|
if (!reactAlias) {
|
127
124
|
return jsxNotFound;
|
@@ -168,24 +165,16 @@ function parseReactAlias(code) {
|
|
168
165
|
}
|
169
166
|
|
170
167
|
function viteReact(opts = {}) {
|
171
|
-
var _a;
|
172
168
|
let base = "/";
|
169
|
+
let resolvedCacheDir;
|
173
170
|
let filter = createFilter(opts.include, opts.exclude);
|
174
171
|
let isProduction = true;
|
175
172
|
let projectRoot = process.cwd();
|
176
173
|
let skipFastRefresh = opts.fastRefresh === false;
|
177
174
|
let skipReactImport = false;
|
175
|
+
let runPluginOverrides = (options, context) => false;
|
176
|
+
let staticBabelOptions;
|
178
177
|
const useAutomaticRuntime = opts.jsxRuntime !== "classic";
|
179
|
-
const babelOptions = {
|
180
|
-
babelrc: false,
|
181
|
-
configFile: false,
|
182
|
-
...opts.babel
|
183
|
-
};
|
184
|
-
babelOptions.plugins || (babelOptions.plugins = []);
|
185
|
-
babelOptions.presets || (babelOptions.presets = []);
|
186
|
-
babelOptions.overrides || (babelOptions.overrides = []);
|
187
|
-
babelOptions.parserOpts || (babelOptions.parserOpts = {});
|
188
|
-
(_a = babelOptions.parserOpts).plugins || (_a.plugins = []);
|
189
178
|
const importReactRE = /(^|\n)import\s+(\*\s+as\s+)?React(,|\s+)/;
|
190
179
|
const fileExtensionRE = /\.[^\/\s\?]+$/;
|
191
180
|
const viteBabel = {
|
@@ -194,6 +183,7 @@ function viteReact(opts = {}) {
|
|
194
183
|
configResolved(config) {
|
195
184
|
base = config.base;
|
196
185
|
projectRoot = config.root;
|
186
|
+
resolvedCacheDir = normalizePath(path.resolve(config.cacheDir));
|
197
187
|
filter = createFilter(opts.include, opts.exclude, {
|
198
188
|
resolve: projectRoot
|
199
189
|
});
|
@@ -208,10 +198,18 @@ function viteReact(opts = {}) {
|
|
208
198
|
const hasConflict = plugin.name === "react-refresh" || plugin !== viteReactJsx && plugin.name === "vite:react-jsx";
|
209
199
|
if (hasConflict)
|
210
200
|
return config.logger.warn(`[@vitejs/plugin-react] You should stop using "${plugin.name}" since this plugin conflicts with it.`);
|
211
|
-
if (plugin.api?.reactBabel) {
|
212
|
-
plugin.api.reactBabel(babelOptions, config);
|
213
|
-
}
|
214
201
|
});
|
202
|
+
runPluginOverrides = (babelOptions, context) => {
|
203
|
+
const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(Boolean);
|
204
|
+
if (hooks.length > 0) {
|
205
|
+
return (runPluginOverrides = (babelOptions2) => {
|
206
|
+
hooks.forEach((hook) => hook(babelOptions2, context, config));
|
207
|
+
return true;
|
208
|
+
})(babelOptions);
|
209
|
+
}
|
210
|
+
runPluginOverrides = () => false;
|
211
|
+
return false;
|
212
|
+
};
|
215
213
|
},
|
216
214
|
async transform(code, id, options) {
|
217
215
|
const ssr = typeof options === "boolean" ? options : options?.ssr === true;
|
@@ -221,6 +219,17 @@ function viteReact(opts = {}) {
|
|
221
219
|
const isJSX = extension.endsWith("x");
|
222
220
|
const isNodeModules = id.includes("/node_modules/");
|
223
221
|
const isProjectFile = !isNodeModules && (id[0] === "\0" || id.startsWith(projectRoot + "/"));
|
222
|
+
let babelOptions = staticBabelOptions;
|
223
|
+
if (typeof opts.babel === "function") {
|
224
|
+
const rawOptions = opts.babel(id, { ssr });
|
225
|
+
babelOptions = createBabelOptions(rawOptions);
|
226
|
+
runPluginOverrides(babelOptions, { ssr, id });
|
227
|
+
} else if (!babelOptions) {
|
228
|
+
babelOptions = createBabelOptions(opts.babel);
|
229
|
+
if (!runPluginOverrides(babelOptions, { ssr, id })) {
|
230
|
+
staticBabelOptions = babelOptions;
|
231
|
+
}
|
232
|
+
}
|
224
233
|
const plugins = isProjectFile ? [...babelOptions.plugins] : [];
|
225
234
|
let useFastRefresh = false;
|
226
235
|
if (!skipFastRefresh && !ssr && !isNodeModules) {
|
@@ -236,7 +245,8 @@ function viteReact(opts = {}) {
|
|
236
245
|
let ast;
|
237
246
|
if (!isProjectFile || isJSX) {
|
238
247
|
if (useAutomaticRuntime) {
|
239
|
-
const
|
248
|
+
const isOptimizedReactDom = id.startsWith(resolvedCacheDir) && id.includes("/react-dom.js");
|
249
|
+
const [restoredAst, isCommonJS] = !isProjectFile && !isJSX && !isOptimizedReactDom ? await restoreJSX(babel, code, id) : [null, false];
|
240
250
|
if (isJSX || (ast = restoredAst)) {
|
241
251
|
plugins.push([
|
242
252
|
await loadPlugin("@babel/plugin-transform-react-jsx" + (isProduction ? "" : "-development")),
|
@@ -342,7 +352,6 @@ function viteReact(opts = {}) {
|
|
342
352
|
];
|
343
353
|
}
|
344
354
|
};
|
345
|
-
const runtimeId = "react/jsx-runtime";
|
346
355
|
const viteReactJsx = {
|
347
356
|
name: "vite:react-jsx",
|
348
357
|
enforce: "pre",
|
@@ -352,28 +361,27 @@ function viteReact(opts = {}) {
|
|
352
361
|
include: ["react/jsx-dev-runtime"]
|
353
362
|
}
|
354
363
|
};
|
355
|
-
},
|
356
|
-
resolveId(id) {
|
357
|
-
return id === runtimeId ? id : null;
|
358
|
-
},
|
359
|
-
load(id) {
|
360
|
-
if (id === runtimeId) {
|
361
|
-
const runtimePath = resolve.sync(runtimeId, {
|
362
|
-
basedir: projectRoot
|
363
|
-
});
|
364
|
-
const exports = ["jsx", "jsxs", "Fragment"];
|
365
|
-
return [
|
366
|
-
`import * as jsxRuntime from ${JSON.stringify(runtimePath)}`,
|
367
|
-
...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
|
368
|
-
].join("\n");
|
369
|
-
}
|
370
364
|
}
|
371
365
|
};
|
372
366
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx];
|
373
367
|
}
|
374
368
|
viteReact.preambleCode = preambleCode;
|
375
|
-
function loadPlugin(
|
376
|
-
return import(
|
369
|
+
function loadPlugin(path2) {
|
370
|
+
return import(path2).then((module) => module.default || module);
|
371
|
+
}
|
372
|
+
function createBabelOptions(rawOptions) {
|
373
|
+
var _a;
|
374
|
+
const babelOptions = {
|
375
|
+
babelrc: false,
|
376
|
+
configFile: false,
|
377
|
+
...rawOptions
|
378
|
+
};
|
379
|
+
babelOptions.plugins || (babelOptions.plugins = []);
|
380
|
+
babelOptions.presets || (babelOptions.presets = []);
|
381
|
+
babelOptions.overrides || (babelOptions.overrides = []);
|
382
|
+
babelOptions.parserOpts || (babelOptions.parserOpts = {});
|
383
|
+
(_a = babelOptions.parserOpts).plugins || (_a.plugins = []);
|
384
|
+
return babelOptions;
|
377
385
|
}
|
378
386
|
|
379
387
|
export { viteReact as default };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitejs/plugin-react",
|
3
|
-
"version": "2.0.0-alpha.
|
3
|
+
"version": "2.0.0-alpha.2",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Evan You",
|
6
6
|
"contributors": [
|
@@ -23,7 +23,7 @@
|
|
23
23
|
"scripts": {
|
24
24
|
"dev": "unbuild --stub",
|
25
25
|
"build": "unbuild && pnpm run patch-cjs",
|
26
|
-
"patch-cjs": "
|
26
|
+
"patch-cjs": "esno ../../scripts/patchCJS.ts",
|
27
27
|
"prepublishOnly": "npm run build"
|
28
28
|
},
|
29
29
|
"engines": {
|
@@ -39,10 +39,10 @@
|
|
39
39
|
},
|
40
40
|
"homepage": "https://github.com/vitejs/vite/tree/main/packages/plugin-react#readme",
|
41
41
|
"dependencies": {
|
42
|
-
"@babel/core": "^7.
|
43
|
-
"@babel/plugin-transform-react-jsx": "^7.17.
|
42
|
+
"@babel/core": "^7.18.0",
|
43
|
+
"@babel/plugin-transform-react-jsx": "^7.17.12",
|
44
44
|
"@babel/plugin-transform-react-jsx-development": "^7.16.7",
|
45
|
-
"@babel/plugin-transform-react-jsx-self": "^7.
|
45
|
+
"@babel/plugin-transform-react-jsx-self": "^7.17.12",
|
46
46
|
"@babel/plugin-transform-react-jsx-source": "^7.16.7",
|
47
47
|
"@rollup/pluginutils": "^4.2.1",
|
48
48
|
"react-refresh": "^0.13.0",
|
package/src/index.ts
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
import path from 'path'
|
1
2
|
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
|
2
3
|
import * as babel from '@babel/core'
|
3
4
|
import { createFilter } from '@rollup/pluginutils'
|
4
|
-
import
|
5
|
+
import { normalizePath } from 'vite'
|
5
6
|
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
|
6
7
|
import {
|
7
8
|
addRefreshWrapper,
|
@@ -41,7 +42,9 @@ export interface Options {
|
|
41
42
|
/**
|
42
43
|
* Babel configuration applied in both dev and prod.
|
43
44
|
*/
|
44
|
-
babel?:
|
45
|
+
babel?:
|
46
|
+
| BabelOptions
|
47
|
+
| ((id: string, options: { ssr?: boolean }) => BabelOptions)
|
45
48
|
}
|
46
49
|
|
47
50
|
export type BabelOptions = Omit<
|
@@ -67,13 +70,21 @@ export interface ReactBabelOptions extends BabelOptions {
|
|
67
70
|
}
|
68
71
|
}
|
69
72
|
|
73
|
+
type ReactBabelHook = (
|
74
|
+
babelConfig: ReactBabelOptions,
|
75
|
+
context: ReactBabelHookContext,
|
76
|
+
config: ResolvedConfig
|
77
|
+
) => void
|
78
|
+
|
79
|
+
type ReactBabelHookContext = { ssr: boolean; id: string }
|
80
|
+
|
70
81
|
declare module 'vite' {
|
71
82
|
export interface Plugin {
|
72
83
|
api?: {
|
73
84
|
/**
|
74
85
|
* Manipulate the Babel options of `@vitejs/plugin-react`
|
75
86
|
*/
|
76
|
-
reactBabel?:
|
87
|
+
reactBabel?: ReactBabelHook
|
77
88
|
}
|
78
89
|
}
|
79
90
|
}
|
@@ -81,26 +92,20 @@ declare module 'vite' {
|
|
81
92
|
export default function viteReact(opts: Options = {}): PluginOption[] {
|
82
93
|
// Provide default values for Rollup compat.
|
83
94
|
let base = '/'
|
95
|
+
let resolvedCacheDir: string
|
84
96
|
let filter = createFilter(opts.include, opts.exclude)
|
85
97
|
let isProduction = true
|
86
98
|
let projectRoot = process.cwd()
|
87
99
|
let skipFastRefresh = opts.fastRefresh === false
|
88
100
|
let skipReactImport = false
|
101
|
+
let runPluginOverrides = (
|
102
|
+
options: ReactBabelOptions,
|
103
|
+
context: ReactBabelHookContext
|
104
|
+
) => false
|
105
|
+
let staticBabelOptions: ReactBabelOptions | undefined
|
89
106
|
|
90
107
|
const useAutomaticRuntime = opts.jsxRuntime !== 'classic'
|
91
108
|
|
92
|
-
const babelOptions = {
|
93
|
-
babelrc: false,
|
94
|
-
configFile: false,
|
95
|
-
...opts.babel
|
96
|
-
} as ReactBabelOptions
|
97
|
-
|
98
|
-
babelOptions.plugins ||= []
|
99
|
-
babelOptions.presets ||= []
|
100
|
-
babelOptions.overrides ||= []
|
101
|
-
babelOptions.parserOpts ||= {} as any
|
102
|
-
babelOptions.parserOpts.plugins ||= []
|
103
|
-
|
104
109
|
// Support patterns like:
|
105
110
|
// - import * as React from 'react';
|
106
111
|
// - import React from 'react';
|
@@ -116,6 +121,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
116
121
|
configResolved(config) {
|
117
122
|
base = config.base
|
118
123
|
projectRoot = config.root
|
124
|
+
resolvedCacheDir = normalizePath(path.resolve(config.cacheDir))
|
119
125
|
filter = createFilter(opts.include, opts.exclude, {
|
120
126
|
resolve: projectRoot
|
121
127
|
})
|
@@ -141,11 +147,22 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
141
147
|
`[@vitejs/plugin-react] You should stop using "${plugin.name}" ` +
|
142
148
|
`since this plugin conflicts with it.`
|
143
149
|
)
|
150
|
+
})
|
151
|
+
|
152
|
+
runPluginOverrides = (babelOptions, context) => {
|
153
|
+
const hooks = config.plugins
|
154
|
+
.map((plugin) => plugin.api?.reactBabel)
|
155
|
+
.filter(Boolean) as ReactBabelHook[]
|
144
156
|
|
145
|
-
if (
|
146
|
-
|
157
|
+
if (hooks.length > 0) {
|
158
|
+
return (runPluginOverrides = (babelOptions) => {
|
159
|
+
hooks.forEach((hook) => hook(babelOptions, context, config))
|
160
|
+
return true
|
161
|
+
})(babelOptions)
|
147
162
|
}
|
148
|
-
|
163
|
+
runPluginOverrides = () => false
|
164
|
+
return false
|
165
|
+
}
|
149
166
|
},
|
150
167
|
async transform(code, id, options) {
|
151
168
|
const ssr = typeof options === 'boolean' ? options : options?.ssr === true
|
@@ -162,6 +179,18 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
162
179
|
const isProjectFile =
|
163
180
|
!isNodeModules && (id[0] === '\0' || id.startsWith(projectRoot + '/'))
|
164
181
|
|
182
|
+
let babelOptions = staticBabelOptions
|
183
|
+
if (typeof opts.babel === 'function') {
|
184
|
+
const rawOptions = opts.babel(id, { ssr })
|
185
|
+
babelOptions = createBabelOptions(rawOptions)
|
186
|
+
runPluginOverrides(babelOptions, { ssr, id: id })
|
187
|
+
} else if (!babelOptions) {
|
188
|
+
babelOptions = createBabelOptions(opts.babel)
|
189
|
+
if (!runPluginOverrides(babelOptions, { ssr, id: id })) {
|
190
|
+
staticBabelOptions = babelOptions
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
165
194
|
const plugins = isProjectFile ? [...babelOptions.plugins] : []
|
166
195
|
|
167
196
|
let useFastRefresh = false
|
@@ -183,8 +212,12 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
183
212
|
// By reverse-compiling "React.createElement" calls into JSX,
|
184
213
|
// React elements provided by dependencies will also use the
|
185
214
|
// automatic runtime!
|
215
|
+
// Avoid parsing the optimized react-dom since it will never
|
216
|
+
// contain compiled JSX and it's a pretty big file (800kb).
|
217
|
+
const isOptimizedReactDom =
|
218
|
+
id.startsWith(resolvedCacheDir) && id.includes('/react-dom.js')
|
186
219
|
const [restoredAst, isCommonJS] =
|
187
|
-
!isProjectFile && !isJSX
|
220
|
+
!isProjectFile && !isJSX && !isOptimizedReactDom
|
188
221
|
? await restoreJSX(babel, code, id)
|
189
222
|
: [null, false]
|
190
223
|
|
@@ -328,7 +361,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
328
361
|
}
|
329
362
|
}
|
330
363
|
|
331
|
-
const runtimeId = 'react/jsx-runtime'
|
364
|
+
// const runtimeId = 'react/jsx-runtime'
|
332
365
|
// Adapted from https://github.com/alloc/vite-react-jsx
|
333
366
|
const viteReactJsx: Plugin = {
|
334
367
|
name: 'vite:react-jsx',
|
@@ -339,10 +372,14 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
339
372
|
include: ['react/jsx-dev-runtime']
|
340
373
|
}
|
341
374
|
}
|
342
|
-
}
|
375
|
+
}
|
376
|
+
// TODO: this optimization may not be necesary and it is breacking esbuild+rollup compat,
|
377
|
+
// see https://github.com/vitejs/vite/pull/7246#discussion_r861552185
|
378
|
+
// We could still do the same trick and resolve to the optimized dependency here
|
379
|
+
/*
|
343
380
|
resolveId(id: string) {
|
344
381
|
return id === runtimeId ? id : null
|
345
|
-
},
|
382
|
+
},
|
346
383
|
load(id: string) {
|
347
384
|
if (id === runtimeId) {
|
348
385
|
const runtimePath = resolve.sync(runtimeId, {
|
@@ -357,7 +394,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
|
|
357
394
|
...exports.map((name) => `export const ${name} = jsxRuntime.${name}`)
|
358
395
|
].join('\n')
|
359
396
|
}
|
360
|
-
}
|
397
|
+
} */
|
361
398
|
}
|
362
399
|
|
363
400
|
return [viteBabel, viteReactRefresh, useAutomaticRuntime && viteReactJsx]
|
@@ -368,3 +405,19 @@ viteReact.preambleCode = preambleCode
|
|
368
405
|
function loadPlugin(path: string): Promise<any> {
|
369
406
|
return import(path).then((module) => module.default || module)
|
370
407
|
}
|
408
|
+
|
409
|
+
function createBabelOptions(rawOptions?: BabelOptions) {
|
410
|
+
const babelOptions = {
|
411
|
+
babelrc: false,
|
412
|
+
configFile: false,
|
413
|
+
...rawOptions
|
414
|
+
} as ReactBabelOptions
|
415
|
+
|
416
|
+
babelOptions.plugins ||= []
|
417
|
+
babelOptions.presets ||= []
|
418
|
+
babelOptions.overrides ||= []
|
419
|
+
babelOptions.parserOpts ||= {} as any
|
420
|
+
babelOptions.parserOpts.plugins ||= []
|
421
|
+
|
422
|
+
return babelOptions
|
423
|
+
}
|
@@ -27,12 +27,6 @@ export async function restoreJSX(
|
|
27
27
|
code: string,
|
28
28
|
filename: string
|
29
29
|
): Promise<RestoredJSX> {
|
30
|
-
// Avoid parsing the optimized react-dom since it will never
|
31
|
-
// contain compiled JSX and it's a pretty big file (800kb).
|
32
|
-
if (filename.includes('/.vite/react-dom.js')) {
|
33
|
-
return jsxNotFound
|
34
|
-
}
|
35
|
-
|
36
30
|
const [reactAlias, isCommonJS] = parseReactAlias(code)
|
37
31
|
|
38
32
|
if (!reactAlias) {
|