From 099643760f99d30ab77014173a62152eed918eb2 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Tue, 12 Aug 2025 20:56:27 +0900 Subject: [PATCH 1/3] fix(react): refreshWrapper was injected twice for class components when using babel plugins and rolldown-vite --- packages/plugin-react/src/index.ts | 3 ++- playground/compiler/__tests__/compiler.spec.ts | 1 + playground/compiler/src/App.tsx | 2 ++ playground/compiler/src/ClassComponent.tsx | 7 +++++++ 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 playground/compiler/src/ClassComponent.tsx diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 87d00b167..6184084a5 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -324,7 +324,8 @@ export default function viteReact(opts: Options = {}): Plugin[] { }) if (result) { - if (!useFastRefresh) { + // refresh wrapper is added later for rolldown-vite + if (!useFastRefresh || isRolldownVite) { return { code: result.code!, map: result.map } } return addRefreshWrapper( diff --git a/playground/compiler/__tests__/compiler.spec.ts b/playground/compiler/__tests__/compiler.spec.ts index 742b6f37a..0889e0bd4 100644 --- a/playground/compiler/__tests__/compiler.spec.ts +++ b/playground/compiler/__tests__/compiler.spec.ts @@ -5,6 +5,7 @@ test('should render', async () => { expect(await page.textContent('button')).toMatch('count is 0') expect(await page.click('button')) expect(await page.textContent('button')).toMatch('count is 1') + expect(await page.textContent('.class-component')).toMatch('ClassComponent') }) test.runIf(isServe)('should hmr', async () => { diff --git a/playground/compiler/src/App.tsx b/playground/compiler/src/App.tsx index 3cdc1d623..07f8d0add 100644 --- a/playground/compiler/src/App.tsx +++ b/playground/compiler/src/App.tsx @@ -1,5 +1,6 @@ import { useState } from 'react' import './App.css' +import { ClassComponent } from './ClassComponent' export function App() { const [count, setCount] = useState(0) @@ -18,6 +19,7 @@ export function App() {

Click on the Vite and React logos to learn more

+ ) } diff --git a/playground/compiler/src/ClassComponent.tsx b/playground/compiler/src/ClassComponent.tsx new file mode 100644 index 000000000..c0f0e39a4 --- /dev/null +++ b/playground/compiler/src/ClassComponent.tsx @@ -0,0 +1,7 @@ +import { Component } from 'react' + +export class ClassComponent extends Component { + public render() { + return
ClassComponent
+ } +} From 275d2ee807f96bc8e79294df3f1ce1b65c0e8a0b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 14 Aug 2025 09:38:01 +0900 Subject: [PATCH 2/3] refactor: move condition --- packages/plugin-react/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 6184084a5..3a4cdbc51 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -255,6 +255,7 @@ export default function viteReact(opts: Options = {}): Plugin[] { const isJSX = filepath.endsWith('x') const useFastRefresh = + !isRolldownVite && !skipFastRefresh && !ssr && (isJSX || @@ -262,7 +263,7 @@ export default function viteReact(opts: Options = {}): Plugin[] { ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime))) - if (useFastRefresh && !isRolldownVite) { + if (useFastRefresh) { plugins.push([ await loadPlugin('react-refresh/babel'), { skipEnvCheck: true }, @@ -324,8 +325,7 @@ export default function viteReact(opts: Options = {}): Plugin[] { }) if (result) { - // refresh wrapper is added later for rolldown-vite - if (!useFastRefresh || isRolldownVite) { + if (!useFastRefresh) { return { code: result.code!, map: result.map } } return addRefreshWrapper( From aa1f1cc4b1a5d35973387c26de839db850317a2f Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 14 Aug 2025 10:03:19 +0900 Subject: [PATCH 3/3] chore: changelog --- packages/plugin-react/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/plugin-react/CHANGELOG.md b/packages/plugin-react/CHANGELOG.md index c1dc40979..131a1fc9e 100644 --- a/packages/plugin-react/CHANGELOG.md +++ b/packages/plugin-react/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +### Fix `RefreshRuntime` being injected twice for class components on rolldown-vite ([#708](https://github.com/vitejs/vite-plugin-react/pull/708)) + ## 5.0.0 (2025-08-07) ## 5.0.0-beta.0 (2025-07-28)