@vitejs/plugin-react 6.0.5 → 6.1.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/README.md CHANGED
@@ -79,13 +79,48 @@ Under the hood, this simply updates the React Fash Refresh runtime URL from `/@r
79
79
 
80
80
  ## React Compiler
81
81
 
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) and [`@babel/core`](https://npmx.dev/package/@babel/core) as peer dependencies:
82
+ ### Rust React Compiler
83
+
84
+ > [!WARNING]
85
+ > Native React Compiler support is experimental.
86
+
87
+ The `compiler` option uses [`oxc-transform-react`](https://npmx.dev/package/oxc-transform-react), a Rust port of [React Compiler](https://react.dev/learn/react-compiler), which must be installed as an optional peer dependency:
88
+
89
+ ```sh
90
+ npm install -D oxc-transform-react
91
+ ```
92
+
93
+ ```js
94
+ // vite.config.js
95
+ import { defineConfig } from 'vite'
96
+ import react from '@vitejs/plugin-react'
97
+
98
+ export default defineConfig({
99
+ plugins: [react({ compiler: true })],
100
+ })
101
+ ```
102
+
103
+ The `compiler` option also accepts [React Compiler options](https://react.dev/reference/react-compiler/configuration):
104
+
105
+ ```js
106
+ react({ compiler: { compilationMode: 'annotation' } })
107
+ ```
108
+
109
+ Set `logDiagnostics` to `true` to log recoverable React Compiler diagnostics through Vite. This option defaults to `false`. Fatal diagnostics are always logged and fail the transform.
110
+
111
+ ```js
112
+ react({ compiler: { logDiagnostics: true } })
113
+ ```
114
+
115
+ ### Babel React Compiler
116
+
117
+ React Compiler can also be used through Babel with the exported `reactCompilerPreset` helper. This requires [`@rolldown/plugin-babel`](https://npmx.dev/package/@rolldown/plugin-babel), [`babel-plugin-react-compiler`](https://npmx.dev/package/babel-plugin-react-compiler), and [`@babel/core`](https://npmx.dev/package/@babel/core) as peer dependencies:
83
118
 
84
119
  ```sh
85
120
  npm install -D @rolldown/plugin-babel @babel/core babel-plugin-react-compiler
86
121
  ```
87
122
 
88
- If you are using TypeScript, you will also need to install [`@types/babel__core`](https://npmx.dev/package/@types/babel__core):
123
+ If you are using TypeScript with Babel 7, you will also need to install [`@types/babel__core`](https://npmx.dev/package/@types/babel__core):
89
124
 
90
125
  ```sh
91
126
  npm install -D @types/babel__core
package/dist/index.d.ts CHANGED
@@ -1,9 +1,17 @@
1
1
  import { Plugin } from "vite";
2
- import { ReactCompilerBabelPluginOptions, RolldownBabelPreset } from "#optionalTypes";
2
+ import { ReactCompilerBabelPluginOptions, ReactCompilerOptions, RolldownBabelPreset } from "#optionalTypes";
3
3
  //#region src/reactCompilerPreset.d.ts
4
4
  declare const reactCompilerPreset: (options?: ReactCompilerBabelPluginOptions) => RolldownBabelPreset;
5
5
  //#endregion
6
6
  //#region src/index.d.ts
7
+ interface ReactCompilerPluginOptions extends ReactCompilerOptions {
8
+ /**
9
+ * Log recoverable React Compiler diagnostics through Vite.
10
+ * Fatal diagnostics are always logged and fail the transform.
11
+ * @default false
12
+ */
13
+ logDiagnostics?: boolean;
14
+ }
7
15
  interface Options {
8
16
  /**
9
17
  * Can be used to process extra files like `.mdx`
@@ -37,6 +45,13 @@ interface Options {
37
45
  * reactRefreshHost: 'http://localhost:3000'
38
46
  */
39
47
  reactRefreshHost?: string;
48
+ /**
49
+ * Enable React Compiler with its default options or configure it.
50
+ * This requires `oxc-transform-react` to be installed.
51
+ * @default false
52
+ * @experimental
53
+ */
54
+ compiler?: boolean | ReactCompilerPluginOptions;
40
55
  }
41
56
  declare function viteReact(opts?: Options): Plugin[];
42
57
  declare namespace viteReact {
@@ -44,4 +59,4 @@ declare namespace viteReact {
44
59
  }
45
60
  declare function viteReactForCjs(this: unknown, options: Options): Plugin[];
46
61
  //#endregion
47
- export { Options, viteReact as default, viteReactForCjs as "module.exports", reactCompilerPreset };
62
+ export { Options, type ReactCompilerPluginOptions as ReactCompilerOptions, viteReact as default, viteReactForCjs as "module.exports", reactCompilerPreset };
package/dist/index.js CHANGED
@@ -52,7 +52,8 @@ const reactCompilerPreset = (options = {}) => ({
52
52
  });
53
53
  //#endregion
54
54
  //#region src/index.ts
55
- const refreshRuntimePath = join(dirname(fileURLToPath(import.meta.url)), "refresh-runtime.js");
55
+ const _dirname = dirname(fileURLToPath(import.meta.url));
56
+ const refreshRuntimePath = join(_dirname, "refresh-runtime.js");
56
57
  const defaultIncludeRE = /\.[tj]sx?$/;
57
58
  const defaultExcludeRE = /\/node_modules\//;
58
59
  function viteReact(opts = {}) {
@@ -72,10 +73,11 @@ function viteReact(opts = {}) {
72
73
  name: "vite:react-babel",
73
74
  enforce: "pre",
74
75
  config(_userConfig, { command }) {
76
+ const refresh = command === "serve" && !opts.compiler;
75
77
  if (opts.jsxRuntime === "classic") return { oxc: {
76
78
  jsx: {
77
79
  runtime: "classic",
78
- refresh: command === "serve"
80
+ refresh
79
81
  },
80
82
  jsxRefreshInclude: makeIdFiltersToMatchWithQuery(include),
81
83
  jsxRefreshExclude: makeIdFiltersToMatchWithQuery(exclude)
@@ -85,7 +87,7 @@ function viteReact(opts = {}) {
85
87
  jsx: {
86
88
  runtime: "automatic",
87
89
  importSource: opts.jsxImportSource,
88
- refresh: command === "serve"
90
+ refresh
89
91
  },
90
92
  jsxRefreshInclude: makeIdFiltersToMatchWithQuery(include),
91
93
  jsxRefreshExclude: makeIdFiltersToMatchWithQuery(exclude)
@@ -152,7 +154,7 @@ function viteReact(opts = {}) {
152
154
  jsxImportDevRuntime,
153
155
  jsxImportRuntime
154
156
  ];
155
- return [
157
+ const plugins = [
156
158
  viteBabel,
157
159
  viteRefreshWrapper,
158
160
  viteConfigPost,
@@ -189,6 +191,60 @@ function viteReact(opts = {}) {
189
191
  isEnabled: () => !skipFastRefresh && !isBundledDev
190
192
  })
191
193
  ];
194
+ if (opts.compiler) plugins.unshift(createReactCompilerPlugin(opts.compiler === true ? {} : opts.compiler, include, exclude, opts, () => !skipFastRefresh));
195
+ return plugins;
196
+ }
197
+ function createReactCompilerPlugin({ logDiagnostics, ...reactCompilerOptions }, include, exclude, reactOptions, isFastRefreshEnabled) {
198
+ let jsxDevelopment = false;
199
+ let compiler;
200
+ const runtime = reactCompilerOptions.target === "17" || reactCompilerOptions.target === "18" ? "react-compiler-runtime" : "react/compiler-runtime";
201
+ const loadCompiler = async (onError) => {
202
+ if (compiler) return compiler;
203
+ try {
204
+ return compiler = await import("oxc-transform-react");
205
+ } catch (error) {
206
+ return onError(`React Compiler requires the optional \`oxc-transform-react\` package. Install it in your project before enabling \`react({ compiler: true })\`.${error instanceof Error ? `\n${error.message}` : ""}`);
207
+ }
208
+ };
209
+ return {
210
+ name: "vite:react-compiler",
211
+ enforce: "pre",
212
+ async config() {
213
+ await loadCompiler((message) => this.error(message));
214
+ return { optimizeDeps: { include: [runtime] } };
215
+ },
216
+ configResolved(config) {
217
+ jsxDevelopment = !config.isProduction;
218
+ },
219
+ transform: {
220
+ filter: { id: {
221
+ include: makeIdFiltersToMatchWithQuery(include),
222
+ exclude: makeIdFiltersToMatchWithQuery(exclude)
223
+ } },
224
+ async handler(code, id) {
225
+ const isClient = this.environment?.config.consumer !== "server";
226
+ const shouldCompile = isClient && (reactCompilerOptions.compilationMode === "annotation" ? /['"]use memo['"]/.test(code) : defaultCodeFilter.test(code));
227
+ const { transform } = compiler ?? await loadCompiler((message) => this.error(message));
228
+ const result = await transform(id.split("?")[0], code, {
229
+ jsx: {
230
+ runtime: reactOptions.jsxRuntime,
231
+ development: jsxDevelopment,
232
+ importSource: reactOptions.jsxImportSource,
233
+ refresh: isClient && isFastRefreshEnabled()
234
+ },
235
+ reactCompiler: shouldCompile ? reactCompilerOptions : false,
236
+ sourcemap: this.environment ? this.environment.config.command !== "build" || !!this.environment.config.build.sourcemap : true
237
+ });
238
+ const diagnostics = result.errors.map((error) => `${error.message}${error.codeframe ? `\n${error.codeframe}` : ""}`);
239
+ if (result.fatal) this.error(diagnostics.join("\n\n") || "React Compiler transform failed.");
240
+ if (logDiagnostics) for (const diagnostic of diagnostics) this.warn(diagnostic);
241
+ return {
242
+ code: result.code,
243
+ map: result.map
244
+ };
245
+ }
246
+ }
247
+ };
192
248
  }
193
249
  viteReact.preambleCode = preambleCode;
194
250
  function viteReactForCjs(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitejs/plugin-react",
3
- "version": "6.0.5",
3
+ "version": "6.1.1",
4
4
  "description": "The default Vite plugin for React projects",
5
5
  "keywords": [
6
6
  "fast refresh",
@@ -50,15 +50,17 @@
50
50
  "@rolldown/plugin-babel": "^0.2.3",
51
51
  "@vitejs/react-common": "workspace:*",
52
52
  "babel-plugin-react-compiler": "^1.0.0",
53
+ "oxc-transform-react": "^0.147.0",
53
54
  "react": "^19.2.8",
54
55
  "react-dom": "^19.2.8",
55
- "rolldown": "^1.2.0",
56
+ "rolldown": "^1.2.6",
56
57
  "tsdown": "^0.22.14",
57
- "vite": "^8.1.5"
58
+ "vite": "^8.2.2"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0",
61
62
  "babel-plugin-react-compiler": "^1.0.0",
63
+ "oxc-transform-react": "^0.145.0",
62
64
  "vite": "^8.0.0"
63
65
  },
64
66
  "peerDependenciesMeta": {
@@ -67,6 +69,9 @@
67
69
  },
68
70
  "babel-plugin-react-compiler": {
69
71
  "optional": true
72
+ },
73
+ "oxc-transform-react": {
74
+ "optional": true
70
75
  }
71
76
  },
72
77
  "engines": {
@@ -4,9 +4,13 @@
4
4
  import type * as pluginBabel from '@rolldown/plugin-babel'
5
5
  // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error
6
6
  import type * as babelPluginReactCompiler from 'babel-plugin-react-compiler'
7
+ // @ts-ignore --- `oxc-transform-react` is an optional peer dependency, so this may cause an error
8
+ import type * as oxcTransformReact from 'oxc-transform-react'
7
9
 
8
10
  // @ts-ignore --- `@rolldown/plugin-babel` is an optional peer dependency, so this may cause an error
9
11
  export type RolldownBabelPreset = pluginBabel.RolldownBabelPreset
10
12
  // @ts-ignore --- `babel-plugin-react-compiler` is an optional peer dependency, so this may cause an error
11
13
  export type ReactCompilerBabelPluginOptions =
12
14
  babelPluginReactCompiler.PluginOptions
15
+ // @ts-ignore --- `oxc-transform-react` is an optional peer dependency, so this may cause an error
16
+ export type ReactCompilerOptions = oxcTransformReact.ReactCompilerOptions