@vitejs/plugin-react 4.6.0 → 5.0.4
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 +2 -8
- package/dist/index.d.ts +47 -50
- package/dist/index.js +377 -0
- package/dist/refresh-runtime.js +24 -8
- package/package.json +13 -22
- package/dist/index.cjs +0 -420
- package/dist/index.d.cts +0 -67
- package/dist/index.d.mts +0 -67
- package/dist/index.mjs +0 -403
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ export default defineConfig({
|
|
|
21
21
|
|
|
22
22
|
### include/exclude
|
|
23
23
|
|
|
24
|
-
Includes `.js`, `.jsx`, `.ts` & `.tsx` by default. This option can be used to add fast refresh to `.mdx` files:
|
|
24
|
+
Includes `.js`, `.jsx`, `.ts` & `.tsx` and excludes `/node_modules/` by default. This option can be used to add fast refresh to `.mdx` files:
|
|
25
25
|
|
|
26
26
|
```js
|
|
27
27
|
import { defineConfig } from 'vite'
|
|
@@ -36,11 +36,9 @@ export default defineConfig({
|
|
|
36
36
|
})
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
> `node_modules` are never processed by this plugin (but esbuild will)
|
|
40
|
-
|
|
41
39
|
### jsxImportSource
|
|
42
40
|
|
|
43
|
-
Control where the JSX factory is imported from.
|
|
41
|
+
Control where the JSX factory is imported from. By default, this is inferred from `jsxImportSource` from corresponding a tsconfig file for a transformed file.
|
|
44
42
|
|
|
45
43
|
```js
|
|
46
44
|
react({ jsxImportSource: '@emotion/react' })
|
|
@@ -129,10 +127,6 @@ Otherwise, you'll probably get this error:
|
|
|
129
127
|
Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong.
|
|
130
128
|
```
|
|
131
129
|
|
|
132
|
-
### disableOxcRecommendation
|
|
133
|
-
|
|
134
|
-
If set, disables the recommendation to use `@vitejs/plugin-react-oxc` (which is shown when `rolldown-vite` is detected and `babel` is not configured).
|
|
135
|
-
|
|
136
130
|
## Consistent components exports
|
|
137
131
|
|
|
138
132
|
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).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Plugin, ResolvedConfig } from "vite";
|
|
2
|
+
import { ParserOptions, TransformOptions } from "@babel/core";
|
|
3
3
|
|
|
4
|
+
//#region src/index.d.ts
|
|
4
5
|
interface Options {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* If set, disables the recommendation to use `@vitejs/plugin-react-oxc`
|
|
34
|
-
*/
|
|
35
|
-
disableOxcRecommendation?: boolean;
|
|
6
|
+
include?: string | RegExp | Array<string | RegExp>;
|
|
7
|
+
exclude?: string | RegExp | Array<string | RegExp>;
|
|
8
|
+
/**
|
|
9
|
+
* Control where the JSX factory is imported from.
|
|
10
|
+
* https://esbuild.github.io/api/#jsx-import-source
|
|
11
|
+
* @default 'react'
|
|
12
|
+
*/
|
|
13
|
+
jsxImportSource?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Note: Skipping React import with classic runtime is not supported from v4
|
|
16
|
+
* @default "automatic"
|
|
17
|
+
*/
|
|
18
|
+
jsxRuntime?: 'classic' | 'automatic';
|
|
19
|
+
/**
|
|
20
|
+
* Babel configuration applied in both dev and prod.
|
|
21
|
+
*/
|
|
22
|
+
babel?: BabelOptions | ((id: string, options: {
|
|
23
|
+
ssr?: boolean;
|
|
24
|
+
}) => BabelOptions);
|
|
25
|
+
/**
|
|
26
|
+
* React Fast Refresh runtime URL prefix.
|
|
27
|
+
* Useful in a module federation context to enable HMR by specifying
|
|
28
|
+
* the host application URL in the Vite config of a remote application.
|
|
29
|
+
* @example
|
|
30
|
+
* reactRefreshHost: 'http://localhost:3000'
|
|
31
|
+
*/
|
|
32
|
+
reactRefreshHost?: string;
|
|
36
33
|
}
|
|
37
34
|
type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
|
|
38
35
|
/**
|
|
@@ -40,28 +37,28 @@ type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'source
|
|
|
40
37
|
* an `api.reactBabel` method.
|
|
41
38
|
*/
|
|
42
39
|
interface ReactBabelOptions extends BabelOptions {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
plugins: Extract<BabelOptions['plugins'], any[]>;
|
|
41
|
+
presets: Extract<BabelOptions['presets'], any[]>;
|
|
42
|
+
overrides: Extract<BabelOptions['overrides'], any[]>;
|
|
43
|
+
parserOpts: ParserOptions & {
|
|
44
|
+
plugins: Extract<ParserOptions['plugins'], any[]>;
|
|
45
|
+
};
|
|
49
46
|
}
|
|
50
47
|
type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void;
|
|
51
48
|
type ReactBabelHookContext = {
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
ssr: boolean;
|
|
50
|
+
id: string;
|
|
54
51
|
};
|
|
55
52
|
type ViteReactPluginApi = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Manipulate the Babel options of `@vitejs/plugin-react`
|
|
55
|
+
*/
|
|
56
|
+
reactBabel?: ReactBabelHook;
|
|
60
57
|
};
|
|
61
|
-
declare function viteReact(opts?: Options):
|
|
58
|
+
declare function viteReact(opts?: Options): Plugin[];
|
|
62
59
|
declare namespace viteReact {
|
|
63
|
-
|
|
60
|
+
var preambleCode: string;
|
|
64
61
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
export
|
|
62
|
+
declare function viteReactForCjs(this: unknown, options: Options): Plugin[];
|
|
63
|
+
//#endregion
|
|
64
|
+
export { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi, viteReact as default, viteReactForCjs as "module.exports" };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import * as vite from "vite";
|
|
5
|
+
import { createFilter } from "vite";
|
|
6
|
+
import { exactRegex, makeIdFiltersToMatchWithQuery } from "@rolldown/pluginutils";
|
|
7
|
+
|
|
8
|
+
//#region ../common/refresh-utils.ts
|
|
9
|
+
const runtimePublicPath = "/@react-refresh";
|
|
10
|
+
const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/;
|
|
11
|
+
const refreshContentRE = /\$RefreshReg\$\(/;
|
|
12
|
+
const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice(1)}";
|
|
13
|
+
injectIntoGlobalHook(window);
|
|
14
|
+
window.$RefreshReg$ = () => {};
|
|
15
|
+
window.$RefreshSig$ = () => (type) => type;`;
|
|
16
|
+
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
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region ../common/warning.ts
|
|
51
|
+
const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warning, defaultHandler) {
|
|
52
|
+
if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message.includes("use client") || warning.message.includes("use server"))) return;
|
|
53
|
+
if (warning.code === "SOURCEMAP_ERROR" && warning.message.includes("resolve original location") && warning.pos === 0) return;
|
|
54
|
+
if (userConfig.build?.rollupOptions?.onwarn) userConfig.build.rollupOptions.onwarn(warning, defaultHandler);
|
|
55
|
+
else defaultHandler(warning);
|
|
56
|
+
} } });
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/index.ts
|
|
60
|
+
const _dirname = dirname(fileURLToPath(import.meta.url));
|
|
61
|
+
const refreshRuntimePath = join(_dirname, "refresh-runtime.js");
|
|
62
|
+
let babel;
|
|
63
|
+
async function loadBabel() {
|
|
64
|
+
if (!babel) babel = await import("@babel/core");
|
|
65
|
+
return babel;
|
|
66
|
+
}
|
|
67
|
+
const defaultIncludeRE = /\.[tj]sx?$/;
|
|
68
|
+
const defaultExcludeRE = /\/node_modules\//;
|
|
69
|
+
const tsRE = /\.tsx?$/;
|
|
70
|
+
const compilerAnnotationRE = /['"]use memo['"]/;
|
|
71
|
+
function viteReact(opts = {}) {
|
|
72
|
+
const include = opts.include ?? defaultIncludeRE;
|
|
73
|
+
const exclude = opts.exclude ?? defaultExcludeRE;
|
|
74
|
+
const filter = createFilter(include, exclude);
|
|
75
|
+
const jsxImportSource = opts.jsxImportSource ?? "react";
|
|
76
|
+
const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`;
|
|
77
|
+
const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`;
|
|
78
|
+
const isRolldownVite = "rolldownVersion" in vite;
|
|
79
|
+
let runningInVite = false;
|
|
80
|
+
let isProduction = true;
|
|
81
|
+
let projectRoot = process.cwd();
|
|
82
|
+
let skipFastRefresh = true;
|
|
83
|
+
let base;
|
|
84
|
+
let isFullBundle = false;
|
|
85
|
+
let runPluginOverrides;
|
|
86
|
+
let staticBabelOptions;
|
|
87
|
+
const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/;
|
|
88
|
+
const viteBabel = {
|
|
89
|
+
name: "vite:react-babel",
|
|
90
|
+
enforce: "pre",
|
|
91
|
+
config(_userConfig, { command }) {
|
|
92
|
+
if ("rolldownVersion" in vite) if (opts.jsxRuntime === "classic") return { oxc: {
|
|
93
|
+
jsx: {
|
|
94
|
+
runtime: "classic",
|
|
95
|
+
refresh: command === "serve",
|
|
96
|
+
development: false
|
|
97
|
+
},
|
|
98
|
+
jsxRefreshInclude: makeIdFiltersToMatchWithQuery(include),
|
|
99
|
+
jsxRefreshExclude: makeIdFiltersToMatchWithQuery(exclude)
|
|
100
|
+
} };
|
|
101
|
+
else return {
|
|
102
|
+
oxc: {
|
|
103
|
+
jsx: {
|
|
104
|
+
runtime: "automatic",
|
|
105
|
+
importSource: opts.jsxImportSource,
|
|
106
|
+
refresh: command === "serve"
|
|
107
|
+
},
|
|
108
|
+
jsxRefreshInclude: makeIdFiltersToMatchWithQuery(include),
|
|
109
|
+
jsxRefreshExclude: makeIdFiltersToMatchWithQuery(exclude)
|
|
110
|
+
},
|
|
111
|
+
optimizeDeps: { rollupOptions: { transform: { jsx: { runtime: "automatic" } } } }
|
|
112
|
+
};
|
|
113
|
+
if (opts.jsxRuntime === "classic") return { esbuild: { jsx: "transform" } };
|
|
114
|
+
else return {
|
|
115
|
+
esbuild: {
|
|
116
|
+
jsx: "automatic",
|
|
117
|
+
jsxImportSource: opts.jsxImportSource
|
|
118
|
+
},
|
|
119
|
+
optimizeDeps: { esbuildOptions: { jsx: "automatic" } }
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
configResolved(config) {
|
|
123
|
+
runningInVite = true;
|
|
124
|
+
base = config.base;
|
|
125
|
+
if (config.experimental.fullBundleMode) isFullBundle = true;
|
|
126
|
+
projectRoot = config.root;
|
|
127
|
+
isProduction = config.isProduction;
|
|
128
|
+
skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false;
|
|
129
|
+
const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(defined);
|
|
130
|
+
if (hooks.length > 0) runPluginOverrides = (babelOptions, context) => {
|
|
131
|
+
hooks.forEach((hook) => hook(babelOptions, context, config));
|
|
132
|
+
};
|
|
133
|
+
else if (typeof opts.babel !== "function") {
|
|
134
|
+
staticBabelOptions = createBabelOptions(opts.babel);
|
|
135
|
+
if ((isRolldownVite || skipFastRefresh) && canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && (opts.jsxRuntime === "classic" ? isProduction : true)) delete viteBabel.transform;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
options(options) {
|
|
139
|
+
if (!runningInVite) {
|
|
140
|
+
options.jsx = {
|
|
141
|
+
mode: opts.jsxRuntime,
|
|
142
|
+
importSource: opts.jsxImportSource
|
|
143
|
+
};
|
|
144
|
+
return options;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
transform: {
|
|
148
|
+
filter: { id: {
|
|
149
|
+
include: makeIdFiltersToMatchWithQuery(include),
|
|
150
|
+
exclude: makeIdFiltersToMatchWithQuery(exclude)
|
|
151
|
+
} },
|
|
152
|
+
async handler(code, id, options) {
|
|
153
|
+
const [filepath] = id.split("?");
|
|
154
|
+
if (!filter(filepath)) return;
|
|
155
|
+
const ssr = options?.ssr === true;
|
|
156
|
+
const babelOptions = (() => {
|
|
157
|
+
if (staticBabelOptions) return staticBabelOptions;
|
|
158
|
+
const newBabelOptions = createBabelOptions(typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel);
|
|
159
|
+
runPluginOverrides?.(newBabelOptions, {
|
|
160
|
+
id,
|
|
161
|
+
ssr
|
|
162
|
+
});
|
|
163
|
+
return newBabelOptions;
|
|
164
|
+
})();
|
|
165
|
+
const plugins = [...babelOptions.plugins];
|
|
166
|
+
let reactCompilerPlugin$1 = getReactCompilerPlugin(plugins);
|
|
167
|
+
if (reactCompilerPlugin$1 && ssr) {
|
|
168
|
+
plugins.splice(plugins.indexOf(reactCompilerPlugin$1), 1);
|
|
169
|
+
reactCompilerPlugin$1 = void 0;
|
|
170
|
+
}
|
|
171
|
+
if (Array.isArray(reactCompilerPlugin$1) && reactCompilerPlugin$1[1]?.compilationMode === "annotation" && !compilerAnnotationRE.test(code)) {
|
|
172
|
+
plugins.splice(plugins.indexOf(reactCompilerPlugin$1), 1);
|
|
173
|
+
reactCompilerPlugin$1 = void 0;
|
|
174
|
+
}
|
|
175
|
+
const isJSX = filepath.endsWith("x");
|
|
176
|
+
const useFastRefresh = !(isRolldownVite || skipFastRefresh) && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)));
|
|
177
|
+
if (useFastRefresh) plugins.push([await loadPlugin("react-refresh/babel"), { skipEnvCheck: true }]);
|
|
178
|
+
if (opts.jsxRuntime === "classic" && isJSX) {
|
|
179
|
+
if (!isProduction) plugins.push(await loadPlugin("@babel/plugin-transform-react-jsx-self"), await loadPlugin("@babel/plugin-transform-react-jsx-source"));
|
|
180
|
+
}
|
|
181
|
+
if (canSkipBabel(plugins, babelOptions)) return;
|
|
182
|
+
const parserPlugins = [...babelOptions.parserOpts.plugins];
|
|
183
|
+
if (!filepath.endsWith(".ts")) parserPlugins.push("jsx");
|
|
184
|
+
if (tsRE.test(filepath)) parserPlugins.push("typescript");
|
|
185
|
+
const result = await (await loadBabel()).transformAsync(code, {
|
|
186
|
+
...babelOptions,
|
|
187
|
+
root: projectRoot,
|
|
188
|
+
filename: id,
|
|
189
|
+
sourceFileName: filepath,
|
|
190
|
+
retainLines: reactCompilerPlugin$1 ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic",
|
|
191
|
+
parserOpts: {
|
|
192
|
+
...babelOptions.parserOpts,
|
|
193
|
+
sourceType: "module",
|
|
194
|
+
allowAwaitOutsideFunction: true,
|
|
195
|
+
plugins: parserPlugins
|
|
196
|
+
},
|
|
197
|
+
generatorOpts: {
|
|
198
|
+
...babelOptions.generatorOpts,
|
|
199
|
+
importAttributesKeyword: "with",
|
|
200
|
+
decoratorsBeforeExport: true
|
|
201
|
+
},
|
|
202
|
+
plugins,
|
|
203
|
+
sourceMaps: true
|
|
204
|
+
});
|
|
205
|
+
if (result) {
|
|
206
|
+
if (!useFastRefresh) return {
|
|
207
|
+
code: result.code,
|
|
208
|
+
map: result.map
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
code: addRefreshWrapper(result.code, "@vitejs/plugin-react", id, opts.reactRefreshHost) ?? result.code,
|
|
212
|
+
map: result.map
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const viteRefreshWrapper = {
|
|
219
|
+
name: "vite:react:refresh-wrapper",
|
|
220
|
+
apply: "serve",
|
|
221
|
+
async applyToEnvironment(env) {
|
|
222
|
+
if (env.config.consumer !== "client" || skipFastRefresh) return false;
|
|
223
|
+
let nativePlugin;
|
|
224
|
+
try {
|
|
225
|
+
nativePlugin = (await import("vite/internal")).reactRefreshWrapperPlugin;
|
|
226
|
+
} catch {}
|
|
227
|
+
if (!nativePlugin || [
|
|
228
|
+
"7.1.10",
|
|
229
|
+
"7.1.11",
|
|
230
|
+
"7.1.12"
|
|
231
|
+
].includes(vite.version)) return true;
|
|
232
|
+
delete viteRefreshWrapper.transform;
|
|
233
|
+
return nativePlugin({
|
|
234
|
+
cwd: process.cwd(),
|
|
235
|
+
include: makeIdFiltersToMatchWithQuery(include),
|
|
236
|
+
exclude: makeIdFiltersToMatchWithQuery(exclude),
|
|
237
|
+
jsxImportSource,
|
|
238
|
+
reactRefreshHost: opts.reactRefreshHost ?? ""
|
|
239
|
+
});
|
|
240
|
+
},
|
|
241
|
+
transform: {
|
|
242
|
+
filter: { id: {
|
|
243
|
+
include: makeIdFiltersToMatchWithQuery(include),
|
|
244
|
+
exclude: makeIdFiltersToMatchWithQuery(exclude)
|
|
245
|
+
} },
|
|
246
|
+
handler(code, id, options) {
|
|
247
|
+
const ssr = options?.ssr === true;
|
|
248
|
+
const [filepath] = id.split("?");
|
|
249
|
+
const isJSX = filepath.endsWith("x");
|
|
250
|
+
if (!(!skipFastRefresh && !ssr && (isJSX || code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)))) return;
|
|
251
|
+
const newCode = addRefreshWrapper(code, "@vitejs/plugin-react", id, opts.reactRefreshHost);
|
|
252
|
+
return newCode ? {
|
|
253
|
+
code: newCode,
|
|
254
|
+
map: null
|
|
255
|
+
} : void 0;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
const viteConfigPost = {
|
|
260
|
+
name: "vite:react:config-post",
|
|
261
|
+
enforce: "post",
|
|
262
|
+
config(userConfig) {
|
|
263
|
+
if (userConfig.server?.hmr === false) return { oxc: { jsx: { refresh: false } } };
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
const viteReactRefreshFullBundleMode = {
|
|
267
|
+
name: "vite:react-refresh-fbm",
|
|
268
|
+
enforce: "pre",
|
|
269
|
+
transformIndexHtml: {
|
|
270
|
+
handler() {
|
|
271
|
+
if (!skipFastRefresh && isFullBundle) return [{
|
|
272
|
+
tag: "script",
|
|
273
|
+
attrs: { type: "module" },
|
|
274
|
+
children: getPreambleCode(base)
|
|
275
|
+
}];
|
|
276
|
+
},
|
|
277
|
+
order: "pre"
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
const dependencies = [
|
|
281
|
+
"react",
|
|
282
|
+
"react-dom",
|
|
283
|
+
jsxImportDevRuntime,
|
|
284
|
+
jsxImportRuntime
|
|
285
|
+
];
|
|
286
|
+
const staticBabelPlugins = typeof opts.babel === "object" ? opts.babel?.plugins ?? [] : [];
|
|
287
|
+
const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins);
|
|
288
|
+
if (reactCompilerPlugin != null) {
|
|
289
|
+
const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin);
|
|
290
|
+
dependencies.push(reactCompilerRuntimeModule);
|
|
291
|
+
}
|
|
292
|
+
const viteReactRefresh = {
|
|
293
|
+
name: "vite:react-refresh",
|
|
294
|
+
enforce: "pre",
|
|
295
|
+
config: (userConfig) => ({
|
|
296
|
+
build: silenceUseClientWarning(userConfig),
|
|
297
|
+
optimizeDeps: { include: dependencies }
|
|
298
|
+
}),
|
|
299
|
+
resolveId: {
|
|
300
|
+
filter: { id: exactRegex(runtimePublicPath) },
|
|
301
|
+
handler(id) {
|
|
302
|
+
if (id === runtimePublicPath) return id;
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
load: {
|
|
306
|
+
filter: { id: exactRegex(runtimePublicPath) },
|
|
307
|
+
handler(id) {
|
|
308
|
+
if (id === runtimePublicPath) return readFileSync(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react");
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
transformIndexHtml() {
|
|
312
|
+
if (!skipFastRefresh && !isFullBundle) return [{
|
|
313
|
+
tag: "script",
|
|
314
|
+
attrs: { type: "module" },
|
|
315
|
+
children: getPreambleCode(base)
|
|
316
|
+
}];
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
return [
|
|
320
|
+
viteBabel,
|
|
321
|
+
...isRolldownVite ? [
|
|
322
|
+
viteRefreshWrapper,
|
|
323
|
+
viteConfigPost,
|
|
324
|
+
viteReactRefreshFullBundleMode
|
|
325
|
+
] : [],
|
|
326
|
+
viteReactRefresh
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
viteReact.preambleCode = preambleCode;
|
|
330
|
+
function viteReactForCjs(options) {
|
|
331
|
+
return viteReact.call(this, options);
|
|
332
|
+
}
|
|
333
|
+
Object.assign(viteReactForCjs, { default: viteReactForCjs });
|
|
334
|
+
function canSkipBabel(plugins, babelOptions) {
|
|
335
|
+
return !(plugins.length || babelOptions.presets.length || babelOptions.configFile || babelOptions.babelrc);
|
|
336
|
+
}
|
|
337
|
+
const loadedPlugin = /* @__PURE__ */ new Map();
|
|
338
|
+
function loadPlugin(path) {
|
|
339
|
+
const cached = loadedPlugin.get(path);
|
|
340
|
+
if (cached) return cached;
|
|
341
|
+
const promise = import(path).then((module) => {
|
|
342
|
+
const value = module.default || module;
|
|
343
|
+
loadedPlugin.set(path, value);
|
|
344
|
+
return value;
|
|
345
|
+
});
|
|
346
|
+
loadedPlugin.set(path, promise);
|
|
347
|
+
return promise;
|
|
348
|
+
}
|
|
349
|
+
function createBabelOptions(rawOptions) {
|
|
350
|
+
const babelOptions = {
|
|
351
|
+
babelrc: false,
|
|
352
|
+
configFile: false,
|
|
353
|
+
...rawOptions
|
|
354
|
+
};
|
|
355
|
+
babelOptions.plugins ||= [];
|
|
356
|
+
babelOptions.presets ||= [];
|
|
357
|
+
babelOptions.overrides ||= [];
|
|
358
|
+
babelOptions.parserOpts ||= {};
|
|
359
|
+
babelOptions.parserOpts.plugins ||= [];
|
|
360
|
+
return babelOptions;
|
|
361
|
+
}
|
|
362
|
+
function defined(value) {
|
|
363
|
+
return value !== void 0;
|
|
364
|
+
}
|
|
365
|
+
function getReactCompilerPlugin(plugins) {
|
|
366
|
+
return plugins.find((p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler");
|
|
367
|
+
}
|
|
368
|
+
function getReactCompilerRuntimeModule(plugin) {
|
|
369
|
+
let moduleName = "react/compiler-runtime";
|
|
370
|
+
if (Array.isArray(plugin)) {
|
|
371
|
+
if (plugin[1]?.target === "17" || plugin[1]?.target === "18") moduleName = "react-compiler-runtime";
|
|
372
|
+
}
|
|
373
|
+
return moduleName;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//#endregion
|
|
377
|
+
export { viteReact as default, viteReactForCjs as "module.exports" };
|
package/dist/refresh-runtime.js
CHANGED
|
@@ -243,7 +243,7 @@ function performReactRefresh() {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
function register(type, id) {
|
|
246
|
+
export function register(type, id) {
|
|
247
247
|
if (type === null) {
|
|
248
248
|
return
|
|
249
249
|
}
|
|
@@ -545,14 +545,25 @@ function isLikelyComponentType(type) {
|
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
function isCompoundComponent(type) {
|
|
549
|
+
if (!isPlainObject(type)) return false
|
|
550
|
+
for (const key in type) {
|
|
551
|
+
if (!isLikelyComponentType(type[key])) return false
|
|
552
|
+
}
|
|
553
|
+
return true
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function isPlainObject(obj) {
|
|
557
|
+
return (
|
|
558
|
+
Object.prototype.toString.call(obj) === '[object Object]' &&
|
|
559
|
+
(obj.constructor === Object || obj.constructor === undefined)
|
|
560
|
+
)
|
|
561
|
+
}
|
|
562
|
+
|
|
548
563
|
/**
|
|
549
564
|
* Plugin utils
|
|
550
565
|
*/
|
|
551
566
|
|
|
552
|
-
export function getRefreshReg(filename) {
|
|
553
|
-
return (type, id) => register(type, filename + ' ' + id)
|
|
554
|
-
}
|
|
555
|
-
|
|
556
567
|
// Taken from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/lib/runtime/RefreshUtils.js#L141
|
|
557
568
|
// This allows to resister components not detected by SWC like styled component
|
|
558
569
|
export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
@@ -565,6 +576,13 @@ export function registerExportsForReactRefresh(filename, moduleExports) {
|
|
|
565
576
|
// The register function has an identity check to not register twice the same component,
|
|
566
577
|
// so this is safe to not used the same key here.
|
|
567
578
|
register(exportValue, filename + ' export ' + key)
|
|
579
|
+
} else if (isCompoundComponent(exportValue)) {
|
|
580
|
+
for (const subKey in exportValue) {
|
|
581
|
+
register(
|
|
582
|
+
exportValue[subKey],
|
|
583
|
+
filename + ' export ' + key + '-' + subKey,
|
|
584
|
+
)
|
|
585
|
+
}
|
|
568
586
|
}
|
|
569
587
|
}
|
|
570
588
|
}
|
|
@@ -618,6 +636,7 @@ export function validateRefreshBoundaryAndEnqueueUpdate(
|
|
|
618
636
|
(key, value) => {
|
|
619
637
|
hasExports = true
|
|
620
638
|
if (isLikelyComponentType(value)) return true
|
|
639
|
+
if (isCompoundComponent(value)) return true
|
|
621
640
|
return prevExports[key] === nextExports[key]
|
|
622
641
|
},
|
|
623
642
|
)
|
|
@@ -630,10 +649,7 @@ export function validateRefreshBoundaryAndEnqueueUpdate(
|
|
|
630
649
|
|
|
631
650
|
function predicateOnExport(ignoredExports, moduleExports, predicate) {
|
|
632
651
|
for (const key in moduleExports) {
|
|
633
|
-
if (key === '__esModule') continue
|
|
634
652
|
if (ignoredExports.includes(key)) continue
|
|
635
|
-
const desc = Object.getOwnPropertyDescriptor(moduleExports, key)
|
|
636
|
-
if (desc && desc.get) return key
|
|
637
653
|
if (!predicate(key, moduleExports[key])) return key
|
|
638
654
|
}
|
|
639
655
|
return true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/plugin-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Evan You",
|
|
6
6
|
"description": "The default Vite plugin for React projects",
|
|
@@ -20,24 +20,15 @@
|
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
22
|
"type": "module",
|
|
23
|
-
"
|
|
24
|
-
"module": "./dist/index.mjs",
|
|
25
|
-
"types": "./dist/index.d.mts",
|
|
26
|
-
"exports": {
|
|
27
|
-
".": {
|
|
28
|
-
"import": "./dist/index.mjs",
|
|
29
|
-
"require": "./dist/index.cjs"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
23
|
+
"exports": "./dist/index.js",
|
|
32
24
|
"scripts": {
|
|
33
|
-
"dev": "
|
|
34
|
-
"build": "
|
|
35
|
-
"patch-cjs": "tsx ../../scripts/patchCJS.ts",
|
|
25
|
+
"dev": "tsdown --watch ./src --watch ../common",
|
|
26
|
+
"build": "tsdown",
|
|
36
27
|
"prepublishOnly": "npm run build",
|
|
37
28
|
"test-unit": "vitest run"
|
|
38
29
|
},
|
|
39
30
|
"engines": {
|
|
40
|
-
"node": "^
|
|
31
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
41
32
|
},
|
|
42
33
|
"repository": {
|
|
43
34
|
"type": "git",
|
|
@@ -49,23 +40,23 @@
|
|
|
49
40
|
},
|
|
50
41
|
"homepage": "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#readme",
|
|
51
42
|
"dependencies": {
|
|
52
|
-
"@babel/core": "^7.
|
|
43
|
+
"@babel/core": "^7.28.4",
|
|
53
44
|
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
|
|
54
45
|
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
|
|
55
|
-
"@rolldown/pluginutils": "1.0.0-beta.
|
|
46
|
+
"@rolldown/pluginutils": "1.0.0-beta.38",
|
|
56
47
|
"@types/babel__core": "^7.20.5",
|
|
57
48
|
"react-refresh": "^0.17.0"
|
|
58
49
|
},
|
|
59
50
|
"peerDependencies": {
|
|
60
|
-
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
|
51
|
+
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
61
52
|
},
|
|
62
53
|
"devDependencies": {
|
|
63
54
|
"@vitejs/react-common": "workspace:*",
|
|
64
|
-
"babel-plugin-react-compiler": "19.1.0-rc.
|
|
65
|
-
"react": "^19.1.
|
|
66
|
-
"react-dom": "^19.1.
|
|
67
|
-
"rolldown": "1.0.0-beta.
|
|
68
|
-
"
|
|
55
|
+
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
|
56
|
+
"react": "^19.1.1",
|
|
57
|
+
"react-dom": "^19.1.1",
|
|
58
|
+
"rolldown": "1.0.0-beta.38",
|
|
59
|
+
"tsdown": "^0.15.4",
|
|
69
60
|
"vitest": "^3.2.4"
|
|
70
61
|
}
|
|
71
62
|
}
|