@vitejs/plugin-react 5.2.0 → 6.0.0-beta.0

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/README.md CHANGED
@@ -4,7 +4,6 @@ The default Vite plugin for React projects.
4
4
 
5
5
  - enable [Fast Refresh](https://www.npmjs.com/package/react-refresh) in development (requires react >= 16.9)
6
6
  - use the [automatic JSX runtime](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)
7
- - use custom Babel plugins/presets
8
7
  - small installation size
9
8
 
10
9
  ```js
@@ -68,56 +67,46 @@ By default, the plugin uses the [automatic JSX runtime](https://legacy.reactjs.o
68
67
  react({ jsxRuntime: 'classic' })
69
68
  ```
70
69
 
71
- ### babel
70
+ ### reactRefreshHost
72
71
 
73
- The `babel` option lets you add plugins, presets, and [other configuration](https://babeljs.io/docs/en/options) to the Babel transformation performed on each included file.
72
+ The `reactRefreshHost` option is only necessary in a module federation context. It enables HMR to work between a remote & host application. In your remote Vite config, you would add your host origin:
74
73
 
75
74
  ```js
76
- react({
77
- babel: {
78
- presets: [...],
79
- // Your plugins run before any built-in transform (eg: Fast Refresh)
80
- plugins: [...],
81
- // Use .babelrc files
82
- babelrc: true,
83
- // Use babel.config.js files
84
- configFile: true,
85
- }
86
- })
75
+ react({ reactRefreshHost: 'http://localhost:3000' })
87
76
  ```
88
77
 
89
- Note: When not using plugins, only esbuild is used for production builds, resulting in faster builds.
78
+ Under the hood, this simply updates the React Fash Refresh runtime URL from `/@react-refresh` to `http://localhost:3000/@react-refresh` to ensure there is only one Refresh runtime across the whole application. Note that if you define `base` option in the host application, you need to include it in the option, like: `http://localhost:3000/{base}`.
90
79
 
91
- #### Proposed syntax
80
+ ## React Compiler
92
81
 
93
- If you are using ES syntax that are still in proposal status (e.g. class properties), you can selectively enable them with the `babel.parserOpts.plugins` option:
82
+ [React Compiler](https://react.dev/learn/react-compiler) support is available via the exported `reactCompilerPreset` helper, which requires [`@rolldown/plugin-babel`](https://npmx.dev/package/@rolldown/plugin-babel) and [`babel-plugin-react-compiler`](https://npmx.dev/package/babel-plugin-react-compiler) as peer dependencies:
94
83
 
95
- ```js
96
- react({
97
- babel: {
98
- parserOpts: {
99
- plugins: ['decorators-legacy'],
100
- },
101
- },
102
- })
84
+ ```sh
85
+ npm install -D @rolldown/plugin-babel babel-plugin-react-compiler
103
86
  ```
104
87
 
105
- This option does not enable _code transformation_. That is handled by esbuild.
106
-
107
- **Note:** TypeScript syntax is handled automatically.
88
+ ```js
89
+ // vite.config.js
90
+ import { defineConfig } from 'vite'
91
+ import react, { reactCompilerPreset } from '@vitejs/plugin-react'
92
+ import babel from '@rolldown/plugin-babel'
108
93
 
109
- Here's the [complete list of Babel parser plugins](https://babeljs.io/docs/en/babel-parser#ecmascript-proposalshttpsgithubcombabelproposals).
94
+ export default defineConfig({
95
+ plugins: [react(), babel({ presets: [reactCompilerPreset()] })],
96
+ })
97
+ ```
110
98
 
111
- ### reactRefreshHost
99
+ The `reactCompilerPreset` accepts an optional options object with the following properties:
112
100
 
113
- The `reactRefreshHost` option is only necessary in a module federation context. It enables HMR to work between a remote & host application. In your remote Vite config, you would add your host origin:
101
+ - `compilationMode` Set to `'annotation'` to only compile components annotated with `"use memo"`.
102
+ - `target` — Set to `'17'` or `'18'` to target older React versions (uses `react-compiler-runtime` instead of `react/compiler-runtime`).
114
103
 
115
104
  ```js
116
- react({ reactRefreshHost: 'http://localhost:3000' })
105
+ babel({
106
+ presets: [reactCompilerPreset({ compilationMode: 'annotation' })],
107
+ })
117
108
  ```
118
109
 
119
- Under the hood, this simply updates the React Fash Refresh runtime URL from `/@react-refresh` to `http://localhost:3000/@react-refresh` to ensure there is only one Refresh runtime across the whole application. Note that if you define `base` option in the host application, you need to include it in the option, like: `http://localhost:3000/{base}`.
120
-
121
110
  ## `@vitejs/plugin-react/preamble`
122
111
 
123
112
  The package provides `@vitejs/plugin-react/preamble` to initialize HMR runtime from client entrypoint for SSR applications which don't use [`transformIndexHtml` API](https://vite.dev/guide/api-javascript.html#vitedevserver). For example:
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
- import { Plugin, ResolvedConfig } from "vite";
2
- import { ParserOptions, TransformOptions } from "@babel/core";
1
+ import { Plugin } from "vite";
2
+ import { ReactCompilerBabelPluginOptions, RolldownBabelPreset } from "#optionalTypes";
3
3
 
4
+ //#region src/reactCompilerPreset.d.ts
5
+ declare const reactCompilerPreset: (options?: Pick<ReactCompilerBabelPluginOptions, "compilationMode" | "target">) => RolldownBabelPreset;
6
+ //#endregion
4
7
  //#region src/index.d.ts
5
8
  interface Options {
6
9
  /**
@@ -18,7 +21,7 @@ interface Options {
18
21
  exclude?: string | RegExp | Array<string | RegExp>;
19
22
  /**
20
23
  * Control where the JSX factory is imported from.
21
- * https://esbuild.github.io/api/#jsx-import-source
24
+ * https://oxc.rs/docs/guide/usage/transformer/jsx.html#import-source
22
25
  * @default 'react'
23
26
  */
24
27
  jsxImportSource?: string;
@@ -27,12 +30,6 @@ interface Options {
27
30
  * @default "automatic"
28
31
  */
29
32
  jsxRuntime?: 'classic' | 'automatic';
30
- /**
31
- * Babel configuration applied in both dev and prod.
32
- */
33
- babel?: BabelOptions | ((id: string, options: {
34
- ssr?: boolean;
35
- }) => BabelOptions);
36
33
  /**
37
34
  * React Fast Refresh runtime URL prefix.
38
35
  * Useful in a module federation context to enable HMR by specifying
@@ -42,34 +39,10 @@ interface Options {
42
39
  */
43
40
  reactRefreshHost?: string;
44
41
  }
45
- type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
46
- /**
47
- * The object type used by the `options` passed to plugins with
48
- * an `api.reactBabel` method.
49
- */
50
- interface ReactBabelOptions extends BabelOptions {
51
- plugins: Extract<BabelOptions['plugins'], any[]>;
52
- presets: Extract<BabelOptions['presets'], any[]>;
53
- overrides: Extract<BabelOptions['overrides'], any[]>;
54
- parserOpts: ParserOptions & {
55
- plugins: Extract<ParserOptions['plugins'], any[]>;
56
- };
57
- }
58
- type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void;
59
- type ReactBabelHookContext = {
60
- ssr: boolean;
61
- id: string;
62
- };
63
- type ViteReactPluginApi = {
64
- /**
65
- * Manipulate the Babel options of `@vitejs/plugin-react`
66
- */
67
- reactBabel?: ReactBabelHook;
68
- };
69
42
  declare function viteReact(opts?: Options): Plugin[];
70
43
  declare namespace viteReact {
71
44
  var preambleCode: string;
72
45
  }
73
46
  declare function viteReactForCjs(this: unknown, options: Options): Plugin[];
74
47
  //#endregion
75
- export { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi, viteReact as default, viteReactForCjs as "module.exports" };
48
+ export { Options, viteReact as default, viteReactForCjs as "module.exports", reactCompilerPreset };
package/dist/index.js CHANGED
@@ -2,49 +2,15 @@ import { readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { exactRegex, makeIdFiltersToMatchWithQuery } from "@rolldown/pluginutils";
5
- import * as vite from "vite";
6
- import { createFilter } from "vite";
5
+ import { reactRefreshWrapperPlugin } from "vite/internal";
7
6
 
8
7
  //#region ../common/refresh-utils.ts
9
8
  const runtimePublicPath = "/@react-refresh";
10
- const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/;
11
- const refreshContentRE = /\$RefreshReg\$\(/;
12
9
  const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice(1)}";
13
10
  injectIntoGlobalHook(window);
14
11
  window.$RefreshReg$ = () => {};
15
12
  window.$RefreshSig$ = () => (type) => type;`;
16
13
  const getPreambleCode = (base) => preambleCode.replace("__BASE__", base);
17
- function addRefreshWrapper(code, pluginName, id, reactRefreshHost = "") {
18
- const hasRefresh = refreshContentRE.test(code);
19
- const onlyReactComp = !hasRefresh && reactCompRE.test(code);
20
- if (!hasRefresh && !onlyReactComp) return void 0;
21
- let newCode = code;
22
- newCode += `
23
-
24
- import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}";
25
- const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;
26
- if (import.meta.hot && !inWebWorker) {
27
- if (!window.$RefreshReg$) {
28
- throw new Error(
29
- "${pluginName} can't detect preamble. Something is wrong."
30
- );
31
- }
32
-
33
- RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
34
- RefreshRuntime.registerExportsForReactRefresh(${JSON.stringify(id)}, currentExports);
35
- import.meta.hot.accept((nextExports) => {
36
- if (!nextExports) return;
37
- const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(${JSON.stringify(id)}, currentExports, nextExports);
38
- if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
39
- });
40
- });
41
- }
42
- `;
43
- if (hasRefresh) newCode += `function $RefreshReg$(type, id) { return RefreshRuntime.register(type, ${JSON.stringify(id)} + ' ' + id) }
44
- function $RefreshSig$() { return RefreshRuntime.createSignatureFunctionForTransform(); }
45
- `;
46
- return newCode;
47
- }
48
14
  function virtualPreamblePlugin({ name, isEnabled }) {
49
15
  return {
50
16
  name: "vite:react-virtual-preamble",
@@ -76,44 +42,41 @@ const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warni
76
42
  else defaultHandler(warning);
77
43
  } } });
78
44
 
45
+ //#endregion
46
+ //#region src/reactCompilerPreset.ts
47
+ const reactCompilerPreset = (options = {}) => ({
48
+ preset: () => ({ plugins: [["babel-plugin-react-compiler", options]] }),
49
+ rolldown: {
50
+ filter: { code: options.compilationMode === "annotation" ? /['"]use memo['"]/ : /\b[A-Z]|\buse/ },
51
+ applyToEnvironmentHook: (env) => env.config.consumer === "client",
52
+ optimizeDeps: { include: options.target === "17" || options.target === "18" ? ["react-compiler-runtime"] : ["react/compiler-runtime"] }
53
+ }
54
+ });
55
+
79
56
  //#endregion
80
57
  //#region src/index.ts
81
58
  const refreshRuntimePath = join(dirname(fileURLToPath(import.meta.url)), "refresh-runtime.js");
82
- let babel;
83
- async function loadBabel() {
84
- if (!babel) babel = await import("@babel/core");
85
- return babel;
86
- }
87
59
  const defaultIncludeRE = /\.[tj]sx?$/;
88
60
  const defaultExcludeRE = /\/node_modules\//;
89
- const tsRE = /\.tsx?$/;
90
- const compilerAnnotationRE = /['"]use memo['"]/;
91
61
  function viteReact(opts = {}) {
92
62
  const include = opts.include ?? defaultIncludeRE;
93
63
  const exclude = opts.exclude ?? defaultExcludeRE;
94
- const filter = createFilter(include, exclude);
95
64
  const jsxImportSource = opts.jsxImportSource ?? "react";
96
65
  const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`;
97
66
  const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`;
98
- const isRolldownVite = "rolldownVersion" in vite;
99
67
  let runningInVite = false;
100
68
  let isProduction = true;
101
- let projectRoot = process.cwd();
102
69
  let skipFastRefresh = true;
103
70
  let base;
104
71
  let isBundledDev = false;
105
- let runPluginOverrides;
106
- let staticBabelOptions;
107
- const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/;
108
72
  const viteBabel = {
109
73
  name: "vite:react-babel",
110
74
  enforce: "pre",
111
75
  config(_userConfig, { command }) {
112
- if ("rolldownVersion" in vite) if (opts.jsxRuntime === "classic") return { oxc: {
76
+ if (opts.jsxRuntime === "classic") return { oxc: {
113
77
  jsx: {
114
78
  runtime: "classic",
115
- refresh: command === "serve",
116
- development: false
79
+ refresh: command === "serve"
117
80
  },
118
81
  jsxRefreshInclude: makeIdFiltersToMatchWithQuery(include),
119
82
  jsxRefreshExclude: makeIdFiltersToMatchWithQuery(exclude)
@@ -130,30 +93,13 @@ function viteReact(opts = {}) {
130
93
  },
131
94
  optimizeDeps: { rolldownOptions: { transform: { jsx: { runtime: "automatic" } } } }
132
95
  };
133
- if (opts.jsxRuntime === "classic") return { esbuild: { jsx: "transform" } };
134
- else return {
135
- esbuild: {
136
- jsx: "automatic",
137
- jsxImportSource: opts.jsxImportSource
138
- },
139
- optimizeDeps: { esbuildOptions: { jsx: "automatic" } }
140
- };
141
96
  },
142
97
  configResolved(config) {
143
98
  runningInVite = true;
144
99
  base = config.base;
145
100
  if (config.experimental.bundledDev) isBundledDev = true;
146
- projectRoot = config.root;
147
101
  isProduction = config.isProduction;
148
102
  skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false;
149
- const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(defined);
150
- if (hooks.length > 0) runPluginOverrides = (babelOptions, context) => {
151
- hooks.forEach((hook) => hook(babelOptions, context, config));
152
- };
153
- else if (typeof opts.babel !== "function") {
154
- staticBabelOptions = createBabelOptions(opts.babel);
155
- if ((isRolldownVite || skipFastRefresh) && canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && (opts.jsxRuntime === "classic" ? isProduction : true)) delete viteBabel.transform;
156
- }
157
103
  },
158
104
  options(options) {
159
105
  if (!runningInVite) {
@@ -164,76 +110,6 @@ function viteReact(opts = {}) {
164
110
  };
165
111
  return options;
166
112
  }
167
- },
168
- transform: {
169
- filter: { id: {
170
- include: makeIdFiltersToMatchWithQuery(include),
171
- exclude: makeIdFiltersToMatchWithQuery(exclude)
172
- } },
173
- async handler(code, id, options) {
174
- const [filepath] = id.split("?");
175
- if (!filter(filepath)) return;
176
- const ssr = options?.ssr === true;
177
- const babelOptions = (() => {
178
- if (staticBabelOptions) return staticBabelOptions;
179
- const newBabelOptions = createBabelOptions(typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel);
180
- runPluginOverrides?.(newBabelOptions, {
181
- id,
182
- ssr
183
- });
184
- return newBabelOptions;
185
- })();
186
- const plugins = [...babelOptions.plugins];
187
- let reactCompilerPlugin = getReactCompilerPlugin(plugins);
188
- if (reactCompilerPlugin && ssr) {
189
- plugins.splice(plugins.indexOf(reactCompilerPlugin), 1);
190
- reactCompilerPlugin = void 0;
191
- }
192
- if (Array.isArray(reactCompilerPlugin) && reactCompilerPlugin[1]?.compilationMode === "annotation" && !compilerAnnotationRE.test(code)) {
193
- plugins.splice(plugins.indexOf(reactCompilerPlugin), 1);
194
- reactCompilerPlugin = void 0;
195
- }
196
- const isJSX = filepath.endsWith("x");
197
- const useFastRefresh = !(isRolldownVite || skipFastRefresh) && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)));
198
- if (useFastRefresh) plugins.push([await loadPlugin("react-refresh/babel"), { skipEnvCheck: true }]);
199
- if (opts.jsxRuntime === "classic" && isJSX) {
200
- if (!isProduction) plugins.push(await loadPlugin("@babel/plugin-transform-react-jsx-self"), await loadPlugin("@babel/plugin-transform-react-jsx-source"));
201
- }
202
- if (canSkipBabel(plugins, babelOptions)) return;
203
- const parserPlugins = [...babelOptions.parserOpts.plugins];
204
- if (!filepath.endsWith(".ts")) parserPlugins.push("jsx");
205
- if (tsRE.test(filepath)) parserPlugins.push("typescript");
206
- const result = await (await loadBabel()).transformAsync(code, {
207
- ...babelOptions,
208
- root: projectRoot,
209
- filename: id,
210
- sourceFileName: filepath,
211
- retainLines: reactCompilerPlugin ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic",
212
- parserOpts: {
213
- ...babelOptions.parserOpts,
214
- sourceType: "module",
215
- allowAwaitOutsideFunction: true,
216
- plugins: parserPlugins
217
- },
218
- generatorOpts: {
219
- ...babelOptions.generatorOpts,
220
- importAttributesKeyword: "with",
221
- decoratorsBeforeExport: true
222
- },
223
- plugins,
224
- sourceMaps: true
225
- });
226
- if (result) {
227
- if (!useFastRefresh) return {
228
- code: result.code,
229
- map: result.map
230
- };
231
- return {
232
- code: addRefreshWrapper(result.code, "@vitejs/plugin-react", id, opts.reactRefreshHost) ?? result.code,
233
- map: result.map
234
- };
235
- }
236
- }
237
113
  }
238
114
  };
239
115
  const viteRefreshWrapper = {
@@ -241,40 +117,13 @@ function viteReact(opts = {}) {
241
117
  apply: "serve",
242
118
  async applyToEnvironment(env) {
243
119
  if (env.config.consumer !== "client" || skipFastRefresh) return false;
244
- let nativePlugin;
245
- try {
246
- nativePlugin = (await import("vite/internal")).reactRefreshWrapperPlugin;
247
- } catch {}
248
- if (!nativePlugin || [
249
- "7.1.10",
250
- "7.1.11",
251
- "7.1.12"
252
- ].includes(vite.version)) return true;
253
- delete viteRefreshWrapper.transform;
254
- return nativePlugin({
120
+ return reactRefreshWrapperPlugin({
255
121
  cwd: process.cwd(),
256
122
  include: makeIdFiltersToMatchWithQuery(include),
257
123
  exclude: makeIdFiltersToMatchWithQuery(exclude),
258
124
  jsxImportSource,
259
125
  reactRefreshHost: opts.reactRefreshHost ?? ""
260
126
  });
261
- },
262
- transform: {
263
- filter: { id: {
264
- include: makeIdFiltersToMatchWithQuery(include),
265
- exclude: makeIdFiltersToMatchWithQuery(exclude)
266
- } },
267
- handler(code, id, options) {
268
- const ssr = options?.ssr === true;
269
- const [filepath] = id.split("?");
270
- const isJSX = filepath.endsWith("x");
271
- if (!(!skipFastRefresh && !ssr && (isJSX || code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)))) return;
272
- const newCode = addRefreshWrapper(code, "@vitejs/plugin-react", id, opts.reactRefreshHost);
273
- return newCode ? {
274
- code: newCode,
275
- map: null
276
- } : void 0;
277
- }
278
127
  }
279
128
  };
280
129
  const viteConfigPost = {
@@ -304,46 +153,38 @@ function viteReact(opts = {}) {
304
153
  jsxImportDevRuntime,
305
154
  jsxImportRuntime
306
155
  ];
307
- const reactCompilerPlugin = getReactCompilerPlugin(typeof opts.babel === "object" ? opts.babel?.plugins ?? [] : []);
308
- if (reactCompilerPlugin != null) {
309
- const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin);
310
- dependencies.push(reactCompilerRuntimeModule);
311
- }
312
- const viteReactRefresh = {
313
- name: "vite:react-refresh",
314
- enforce: "pre",
315
- config: (userConfig) => ({
316
- build: silenceUseClientWarning(userConfig),
317
- optimizeDeps: { include: dependencies }
318
- }),
319
- resolveId: {
320
- filter: { id: exactRegex(runtimePublicPath) },
321
- handler(id) {
322
- if (id === runtimePublicPath) return id;
323
- }
324
- },
325
- load: {
326
- filter: { id: exactRegex(runtimePublicPath) },
327
- handler(id) {
328
- if (id === runtimePublicPath) return readFileSync(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react");
329
- }
330
- },
331
- transformIndexHtml() {
332
- if (!skipFastRefresh && !isBundledDev) return [{
333
- tag: "script",
334
- attrs: { type: "module" },
335
- children: getPreambleCode(base)
336
- }];
337
- }
338
- };
339
156
  return [
340
157
  viteBabel,
341
- ...isRolldownVite ? [
342
- viteRefreshWrapper,
343
- viteConfigPost,
344
- viteReactRefreshBundledDevMode
345
- ] : [],
346
- viteReactRefresh,
158
+ viteRefreshWrapper,
159
+ viteConfigPost,
160
+ viteReactRefreshBundledDevMode,
161
+ {
162
+ name: "vite:react-refresh",
163
+ enforce: "pre",
164
+ config: (userConfig) => ({
165
+ build: silenceUseClientWarning(userConfig),
166
+ optimizeDeps: { include: dependencies }
167
+ }),
168
+ resolveId: {
169
+ filter: { id: exactRegex(runtimePublicPath) },
170
+ handler(id) {
171
+ if (id === runtimePublicPath) return id;
172
+ }
173
+ },
174
+ load: {
175
+ filter: { id: exactRegex(runtimePublicPath) },
176
+ handler(id) {
177
+ if (id === runtimePublicPath) return readFileSync(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react");
178
+ }
179
+ },
180
+ transformIndexHtml() {
181
+ if (!skipFastRefresh && !isBundledDev) return [{
182
+ tag: "script",
183
+ attrs: { type: "module" },
184
+ children: getPreambleCode(base)
185
+ }];
186
+ }
187
+ },
347
188
  virtualPreamblePlugin({
348
189
  name: "@vitejs/plugin-react/preamble",
349
190
  isEnabled: () => !skipFastRefresh && !isBundledDev
@@ -354,48 +195,10 @@ viteReact.preambleCode = preambleCode;
354
195
  function viteReactForCjs(options) {
355
196
  return viteReact.call(this, options);
356
197
  }
357
- Object.assign(viteReactForCjs, { default: viteReactForCjs });
358
- function canSkipBabel(plugins, babelOptions) {
359
- return !(plugins.length || babelOptions.presets.length || babelOptions.overrides.length || babelOptions.configFile || babelOptions.babelrc);
360
- }
361
- const loadedPlugin = /* @__PURE__ */ new Map();
362
- function loadPlugin(path) {
363
- const cached = loadedPlugin.get(path);
364
- if (cached) return cached;
365
- const promise = import(path).then((module) => {
366
- const value = module.default || module;
367
- loadedPlugin.set(path, value);
368
- return value;
369
- });
370
- loadedPlugin.set(path, promise);
371
- return promise;
372
- }
373
- function createBabelOptions(rawOptions) {
374
- const babelOptions = {
375
- babelrc: false,
376
- configFile: false,
377
- ...rawOptions
378
- };
379
- babelOptions.plugins ||= [];
380
- babelOptions.presets ||= [];
381
- babelOptions.overrides ||= [];
382
- babelOptions.parserOpts ||= {};
383
- babelOptions.parserOpts.plugins ||= [];
384
- return babelOptions;
385
- }
386
- function defined(value) {
387
- return value !== void 0;
388
- }
389
- function getReactCompilerPlugin(plugins) {
390
- return plugins.find((p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler");
391
- }
392
- function getReactCompilerRuntimeModule(plugin) {
393
- let moduleName = "react/compiler-runtime";
394
- if (Array.isArray(plugin)) {
395
- if (plugin[1]?.target === "17" || plugin[1]?.target === "18") moduleName = "react-compiler-runtime";
396
- }
397
- return moduleName;
398
- }
198
+ Object.assign(viteReactForCjs, {
199
+ default: viteReactForCjs,
200
+ reactCompilerPreset
201
+ });
399
202
 
400
203
  //#endregion
401
- export { viteReact as default, viteReactForCjs as "module.exports" };
204
+ export { viteReact as default, viteReactForCjs as "module.exports", reactCompilerPreset };
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "@vitejs/plugin-react",
3
- "version": "5.2.0",
3
+ "version": "6.0.0-beta.0",
4
4
  "description": "The default Vite plugin for React projects",
5
5
  "keywords": [
6
- "babel",
7
6
  "fast refresh",
8
7
  "react",
9
8
  "react-refresh",
@@ -30,6 +29,9 @@
30
29
  "types"
31
30
  ],
32
31
  "type": "module",
32
+ "imports": {
33
+ "#optionalTypes": "./types/optionalTypes.d.ts"
34
+ },
33
35
  "exports": {
34
36
  ".": "./dist/index.js",
35
37
  "./preamble": "./types/preamble.d.ts"
@@ -41,23 +43,31 @@
41
43
  "test-unit": "vitest run"
42
44
  },
43
45
  "dependencies": {
44
- "@babel/core": "^7.29.0",
45
- "@babel/plugin-transform-react-jsx-self": "^7.27.1",
46
- "@babel/plugin-transform-react-jsx-source": "^7.27.1",
47
- "@rolldown/pluginutils": "1.0.0-rc.3",
48
- "@types/babel__core": "^7.20.5",
49
- "react-refresh": "^0.18.0"
46
+ "@rolldown/pluginutils": "1.0.0-rc.6"
50
47
  },
51
48
  "devDependencies": {
49
+ "@babel/core": "8.0.0-rc.2",
50
+ "@rolldown/plugin-babel": "^0.1.7",
52
51
  "@vitejs/react-common": "workspace:*",
53
- "babel-plugin-react-compiler": "19.1.0-rc.3",
52
+ "babel-plugin-react-compiler": "^1.0.0",
54
53
  "react": "^19.2.4",
55
54
  "react-dom": "^19.2.4",
56
- "rolldown": "1.0.0-rc.3",
57
- "tsdown": "^0.20.3"
55
+ "rolldown": "1.0.0-rc.6",
56
+ "tsdown": "^0.20.3",
57
+ "vite": "^8.0.0-beta.16"
58
58
  },
59
59
  "peerDependencies": {
60
- "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
60
+ "@rolldown/plugin-babel": "^0.1.7",
61
+ "babel-plugin-react-compiler": "^1.0.0",
62
+ "vite": "^8.0.0"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@rolldown/plugin-babel": {
66
+ "optional": true
67
+ },
68
+ "babel-plugin-react-compiler": {
69
+ "optional": true
70
+ }
61
71
  },
62
72
  "engines": {
63
73
  "node": "^20.19.0 || >=22.12.0"
@@ -0,0 +1,12 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+
3
+ // @ts-ignore --- `@rolldown/plugin-babel` is an optional peer dependency, so this may cause an error
4
+ import type * as pluginBabel from '@rolldown/plugin-babel'
5
+ // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error
6
+ import type * as babelPluginReactCompiler from 'babel-plugin-react-compiler'
7
+
8
+ // @ts-ignore --- `@rolldown/plugin-babel` is an optional peer dependency, so this may cause an error
9
+ export type RolldownBabelPreset = pluginBabel.RolldownBabelPreset
10
+ // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error
11
+ export type ReactCompilerBabelPluginOptions =
12
+ babelPluginReactCompiler.PluginOptions