diff --git a/packages/plugin-react-swc/CHANGELOG.md b/packages/plugin-react-swc/CHANGELOG.md index f9166a84c..456128748 100644 --- a/packages/plugin-react-swc/CHANGELOG.md +++ b/packages/plugin-react-swc/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Suggest `@vitejs/plugin-react-oxc` if rolldown-vite is detected [#491](https://github.com/vitejs/vite-plugin-react/pull/491) + +Emit a log which recommends `@vitejs/plugin-react-oxc` when `rolldown-vite` is detected to improve performance and use Oxc under the hood. The warning can be disabled by setting `disableOxcRecommendation: false` in the plugin options. + ### Use `optimizeDeps.rollupOptions` instead of `optimizeDeps.esbuildOptions` for rolldown-vite [#489](https://github.com/vitejs/vite-plugin-react/pull/489) This suppresses the warning about `optimizeDeps.esbuildOptions` being deprecated in rolldown-vite. diff --git a/packages/plugin-react-swc/README.md b/packages/plugin-react-swc/README.md index 76bd52e6f..c74f11d72 100644 --- a/packages/plugin-react-swc/README.md +++ b/packages/plugin-react-swc/README.md @@ -117,6 +117,14 @@ react({ }) ``` +### disableOxcRecommendation + +If set, disables the recommendation to use `@vitejs/plugin-react-oxc` (which is shown when `rolldown-vite` is detected and neither `swc` plugins are used nor the `swc` options are mutated). + +```ts +react({ disableOxcRecommendation: true }) +``` + ## Consistent components exports For React refresh to work correctly, your file should only export React components. The best explanation I've read is the one from the [Gatsby docs](https://www.gatsbyjs.com/docs/reference/local-development/fast-refresh/#how-it-works). diff --git a/packages/plugin-react-swc/src/index.ts b/packages/plugin-react-swc/src/index.ts index b2a277e31..9f9f6738b 100644 --- a/packages/plugin-react-swc/src/index.ts +++ b/packages/plugin-react-swc/src/index.ts @@ -12,13 +12,13 @@ import { transform, } from '@swc/core' import type { PluginOption } from 'vite' -import * as vite from 'vite' import { addRefreshWrapper, getPreambleCode, runtimePublicPath, silenceUseClientWarning, } from '@vitejs/react-common' +import * as vite from 'vite' import { exactRegex } from '@rolldown/pluginutils' /* eslint-disable no-restricted-globals */ @@ -76,6 +76,11 @@ type Options = { * feature doesn't work is not fun, so we won't provide support for it, hence the name `useAtYourOwnRisk` */ useAtYourOwnRisk_mutateSwcOptions?: (options: SWCOptions) => void + + /** + * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` + */ + disableOxcRecommendation?: boolean } const react = (_options?: Options): PluginOption[] => { @@ -91,6 +96,7 @@ const react = (_options?: Options): PluginOption[] => { reactRefreshHost: _options?.reactRefreshHost, useAtYourOwnRisk_mutateSwcOptions: _options?.useAtYourOwnRisk_mutateSwcOptions, + disableOxcRecommendation: _options?.disableOxcRecommendation, } return [ @@ -144,6 +150,17 @@ const react = (_options?: Options): PluginOption[] => { '[vite:react-swc] The MDX plugin should be placed before this plugin', ) } + + if ( + 'rolldownVersion' in vite && + !options.plugins && + !options.useAtYourOwnRisk_mutateSwcOptions && + !options.disableOxcRecommendation + ) { + config.logger.warn( + '[vite:react-swc] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance as no swc plugins are used. More information at https://vite.dev/rolldown', + ) + } }, transformIndexHtml: (_, config) => { if (!hmrDisabled) { diff --git a/packages/plugin-react/CHANGELOG.md b/packages/plugin-react/CHANGELOG.md index 7f5082a81..f7d2e708a 100644 --- a/packages/plugin-react/CHANGELOG.md +++ b/packages/plugin-react/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Suggest `@vitejs/plugin-react-oxc` if rolldown-vite is detected [#491](https://github.com/vitejs/vite-plugin-react/pull/491) + +Emit a log which recommends `@vitejs/plugin-react-oxc` when `rolldown-vite` is detected to improve performance and use Oxc under the hood. The warning can be disabled by setting `disableOxcRecommendation: false` in the plugin options. + + ### Use `optimizeDeps.rollupOptions` instead of `optimizeDeps.esbuildOptions` for rolldown-vite [#489](https://github.com/vitejs/vite-plugin-react/pull/489) This suppresses the warning about `optimizeDeps.esbuildOptions` being deprecated in rolldown-vite. diff --git a/packages/plugin-react/README.md b/packages/plugin-react/README.md index 7eaa29ab4..af7a2d545 100644 --- a/packages/plugin-react/README.md +++ b/packages/plugin-react/README.md @@ -129,6 +129,10 @@ Otherwise, you'll probably get this error: Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong. ``` +### disableOxcRecommendation + +If set, disables the recommendation to use `@vitejs/plugin-react-oxc` (which is shown when `rolldown-vite` is detected and `babel` is not configured). + ## Consistent components exports For React refresh to work correctly, your file should only export React components. You can find a good explanation in the [Gatsby docs](https://www.gatsbyjs.com/docs/reference/local-development/fast-refresh/#how-it-works). diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 147845e5c..8103e2f25 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -62,6 +62,11 @@ export interface Options { * reactRefreshHost: 'http://localhost:3000' */ reactRefreshHost?: string + + /** + * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` + */ + disableOxcRecommendation?: boolean } export type BabelOptions = Omit< @@ -182,6 +187,17 @@ export default function viteReact(opts: Options = {}): PluginOption[] { .map((plugin) => plugin.api?.reactBabel) .filter(defined) + if ( + 'rolldownVersion' in vite && + !opts.babel && + !hooks.length && + !opts.disableOxcRecommendation + ) { + config.logger.warn( + '[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown', + ) + } + if (hooks.length > 0) { runPluginOverrides = (babelOptions, context) => { hooks.forEach((hook) => hook(babelOptions, context, config))