Skip to content

Commit 45a177f

Browse files
committed
refactor: use react-common
1 parent aa98f2c commit 45a177f

File tree

9 files changed

+58
-238
lines changed

9 files changed

+58
-238
lines changed

packages/plugin-react-oxc/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"exports": "./dist/index.mjs",
2525
"scripts": {
2626
"dev": "unbuild --stub",
27-
"build": "unbuild && tsx scripts/copyRefreshUtils.ts",
27+
"build": "unbuild && tsx scripts/copyRefreshRuntime.ts",
2828
"prepublishOnly": "npm run build"
2929
},
3030
"engines": {
@@ -46,6 +46,7 @@
4646
"vite": "^6.3.0"
4747
},
4848
"devDependencies": {
49+
"@vitejs/react-common": "workspace:*",
4950
"unbuild": "^3.5.0",
5051
"vite": "catalog:rolldown-vite"
5152
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { copyFileSync } from 'node:fs'
2+
3+
copyFileSync(
4+
'node_modules/@vitejs/react-common/refresh-runtime.js',
5+
'dist/refresh-runtime.js',
6+
)

packages/plugin-react-oxc/scripts/copyRefreshUtils.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/plugin-react-oxc/src/fast-refresh.ts

Lines changed: 0 additions & 92 deletions
This file was deleted.

packages/plugin-react-oxc/src/index.ts

Lines changed: 27 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import type { BuildOptions, Plugin, PluginOption, UserConfig } from 'vite'
1+
import { dirname, join } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import { readFileSync } from 'node:fs'
4+
import type { BuildOptions, Plugin, PluginOption } from 'vite'
25
import {
3-
addClassComponentRefreshWrapper,
46
addRefreshWrapper,
5-
preambleCode,
6-
runtimeCode,
7+
getPreambleCode,
78
runtimePublicPath,
8-
} from './fast-refresh'
9+
silenceUseClientWarning,
10+
} from '@vitejs/react-common'
11+
12+
const _dirname = dirname(fileURLToPath(import.meta.url))
913

1014
export interface Options {
1115
include?: string | RegExp | Array<string | RegExp>
@@ -17,8 +21,6 @@ export interface Options {
1721
jsxImportSource?: string
1822
}
1923

20-
const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/
21-
const refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/
2224
const defaultIncludeRE = /\.[tj]sx?(?:$|\?)/
2325

2426
export default function viteReact(opts: Options = {}): PluginOption[] {
@@ -40,7 +42,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
4042
name: 'vite:react-oxc:config',
4143
config(userConfig, { command }) {
4244
return {
43-
build: silenceUseClientWarning(userConfig),
45+
// @ts-expect-error rolldown-vite Vite type incompatibility
46+
build: silenceUseClientWarning(userConfig) as BuildOptions,
4447
oxc: {
4548
jsx: {
4649
runtime: 'automatic',
@@ -84,19 +87,23 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
8487
load: {
8588
filter: { id: exactRegex(runtimePublicPath) },
8689
handler(_id) {
87-
return runtimeCode
90+
return readFileSync(
91+
join(_dirname, 'refresh-runtime.js'),
92+
'utf-8',
93+
).replace(
94+
/__README_URL__/g,
95+
'https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react-oxc',
96+
)
8897
},
8998
},
9099
}
91100

92-
let devBase: string
93101
let skipFastRefresh = false
94102

95103
const viteRefreshWrapper: Plugin = {
96104
name: 'vite:react-oxc:refresh-wrapper',
97105
apply: 'serve',
98106
configResolved(config) {
99-
devBase = config.base
100107
skipFastRefresh = config.isProduction || config.server.hmr === false
101108
},
102109
transform: {
@@ -114,24 +121,23 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
114121
(isJSX ||
115122
code.includes(jsxImportDevRuntime) ||
116123
code.includes(jsxImportRuntime))
124+
if (!useFastRefresh) return
117125

118-
if (useFastRefresh) {
119-
if (refreshContentRE.test(code)) {
120-
code = addRefreshWrapper(code, id)
121-
} else if (reactCompRE.test(code)) {
122-
code = addClassComponentRefreshWrapper(code, id)
123-
}
124-
return { code }
125-
}
126+
return addRefreshWrapper(
127+
code,
128+
undefined,
129+
'@vitejs/plugin-react-oxc',
130+
id,
131+
)
126132
},
127133
},
128-
transformIndexHtml() {
134+
transformIndexHtml(_, config) {
129135
if (!skipFastRefresh)
130136
return [
131137
{
132138
tag: 'script',
133139
attrs: { type: 'module' },
134-
children: preambleCode.replace(`__BASE__`, devBase),
140+
children: getPreambleCode(config.server!.config.base),
135141
},
136142
]
137143
},
@@ -140,32 +146,6 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
140146
return [viteConfig, viteRefreshRuntime, viteRefreshWrapper]
141147
}
142148

143-
const silenceUseClientWarning = (userConfig: UserConfig): BuildOptions => ({
144-
rollupOptions: {
145-
onwarn(warning, defaultHandler) {
146-
if (
147-
warning.code === 'MODULE_LEVEL_DIRECTIVE' &&
148-
warning.message.includes('use client')
149-
) {
150-
return
151-
}
152-
// https://github.com/vitejs/vite/issues/15012
153-
if (
154-
warning.code === 'SOURCEMAP_ERROR' &&
155-
warning.message.includes('resolve original location') &&
156-
warning.pos === 0
157-
) {
158-
return
159-
}
160-
if (userConfig.build?.rollupOptions?.onwarn) {
161-
userConfig.build.rollupOptions.onwarn(warning, defaultHandler)
162-
} else {
163-
defaultHandler(warning)
164-
}
165-
},
166-
},
167-
})
168-
169149
function exactRegex(input: string): RegExp {
170150
return new RegExp(`^${escapeRegex(input)}$`)
171151
}

packages/plugin-react-oxc/src/refreshUtils.js

Lines changed: 0 additions & 93 deletions
This file was deleted.

playground/react/__tests__/react.spec.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expect, test } from 'vitest'
22
import {
33
editFile,
4+
escapeRegex,
45
isBuild,
56
isServe,
67
page,
@@ -82,7 +83,13 @@ if (!isBuild) {
8283
code.replace('An Object', 'Updated'),
8384
),
8485
[
85-
'[vite] invalidate /hmr/no-exported-comp.jsx: Could not Fast Refresh ("Foo" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#consistent-components-exports',
86+
new RegExp(
87+
`^${escapeRegex(
88+
'[vite] invalidate /hmr/no-exported-comp.jsx: Could not Fast Refresh ("Foo" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react/tree/main/packages/',
89+
)}plugin-react(?:-\\w+)?${escapeRegex(
90+
'#consistent-components-exports',
91+
)}`,
92+
),
8693
'[vite] hot updated: /hmr/no-exported-comp.jsx',
8794
'[vite] hot updated: /hmr/parent.jsx',
8895
'Parent rendered',
@@ -107,7 +114,13 @@ if (!isBuild) {
107114
code.replace('context provider', 'context provider updated'),
108115
),
109116
[
110-
'[vite] invalidate /context/CountProvider.jsx: Could not Fast Refresh ("CountContext" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#consistent-components-exports',
117+
new RegExp(
118+
`^${escapeRegex(
119+
'[vite] invalidate /context/CountProvider.jsx: Could not Fast Refresh ("CountContext" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react/tree/main/packages/',
120+
)}plugin-react(?:-\\w+)?${escapeRegex(
121+
'#consistent-components-exports',
122+
)}`,
123+
),
111124
'[vite] hot updated: /context/CountProvider.jsx',
112125
'[vite] hot updated: /App.jsx',
113126
'[vite] hot updated: /context/ContextButton.jsx',

playground/test-utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ async function untilBrowserLog(
202202
return logs
203203
}
204204

205+
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g
206+
export function escapeRegex(str: string): string {
207+
return str.replace(escapeRegexRE, '\\$&')
208+
}
209+
205210
/**
206211
* Before implementing a new util, check if it's not available in core https://github.com/vitejs/vite/blob/main/playground/test-utils.ts
207212
*/

0 commit comments

Comments
 (0)