@vitejs/plugin-react 3.0.1 → 3.1.0-beta.0
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 +8 -0
- package/dist/index.cjs +19 -53
- package/dist/index.mjs +19 -53
- package/dist/refreshUtils.js +57 -0
- package/package.json +6 -5
package/README.md
CHANGED
@@ -105,3 +105,11 @@ Otherwise, you'll probably get this error:
|
|
105
105
|
```
|
106
106
|
Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong.
|
107
107
|
```
|
108
|
+
|
109
|
+
## Consistent components exports
|
110
|
+
|
111
|
+
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).
|
112
|
+
|
113
|
+
If an incompatible change in exports is found, the module will be invalidated and HMR will propagate. To make it easier to export simple constants alongside your component, the module is only invalidated when their value changes.
|
114
|
+
|
115
|
+
You can catch mistakes and get more detailed warning with this [eslint rule](https://github.com/ArnaudBarre/eslint-plugin-react-refresh).
|
package/dist/index.cjs
CHANGED
@@ -32,14 +32,7 @@ const runtimeFilePath = path.join(
|
|
32
32
|
const runtimeCode = `
|
33
33
|
const exports = {}
|
34
34
|
${fs.readFileSync(runtimeFilePath, "utf-8")}
|
35
|
-
|
36
|
-
let handle
|
37
|
-
return () => {
|
38
|
-
clearTimeout(handle)
|
39
|
-
handle = setTimeout(fn, delay)
|
40
|
-
}
|
41
|
-
}
|
42
|
-
exports.performReactRefresh = debounce(exports.performReactRefresh, 16)
|
35
|
+
${fs.readFileSync(_require.resolve("./refreshUtils.js"), "utf-8")}
|
43
36
|
export default exports
|
44
37
|
`;
|
45
38
|
const preambleCode = `
|
@@ -70,60 +63,26 @@ if (import.meta.hot) {
|
|
70
63
|
};
|
71
64
|
window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
|
72
65
|
}`.replace(/\n+/g, "");
|
73
|
-
const timeout = `
|
74
|
-
if (!window.__vite_plugin_react_timeout) {
|
75
|
-
window.__vite_plugin_react_timeout = setTimeout(() => {
|
76
|
-
window.__vite_plugin_react_timeout = 0;
|
77
|
-
RefreshRuntime.performReactRefresh();
|
78
|
-
}, 30);
|
79
|
-
}
|
80
|
-
`;
|
81
|
-
const checkAndAccept = `
|
82
|
-
function isReactRefreshBoundary(mod) {
|
83
|
-
if (mod == null || typeof mod !== 'object') {
|
84
|
-
return false;
|
85
|
-
}
|
86
|
-
let hasExports = false;
|
87
|
-
let areAllExportsComponents = true;
|
88
|
-
for (const exportName in mod) {
|
89
|
-
hasExports = true;
|
90
|
-
if (exportName === '__esModule') {
|
91
|
-
continue;
|
92
|
-
}
|
93
|
-
const desc = Object.getOwnPropertyDescriptor(mod, exportName);
|
94
|
-
if (desc && desc.get) {
|
95
|
-
// Don't invoke getters as they may have side effects.
|
96
|
-
return false;
|
97
|
-
}
|
98
|
-
const exportValue = mod[exportName];
|
99
|
-
if (!RefreshRuntime.isLikelyComponentType(exportValue)) {
|
100
|
-
areAllExportsComponents = false;
|
101
|
-
}
|
102
|
-
}
|
103
|
-
return hasExports && areAllExportsComponents;
|
104
|
-
}
|
105
|
-
|
106
|
-
import.meta.hot.accept(mod => {
|
107
|
-
if (!mod) return;
|
108
|
-
if (isReactRefreshBoundary(mod)) {
|
109
|
-
${timeout}
|
110
|
-
} else {
|
111
|
-
import.meta.hot.invalidate();
|
112
|
-
}
|
113
|
-
});
|
114
|
-
`;
|
115
66
|
const footer = `
|
116
67
|
if (import.meta.hot) {
|
117
68
|
window.$RefreshReg$ = prevRefreshReg;
|
118
69
|
window.$RefreshSig$ = prevRefreshSig;
|
119
70
|
|
120
|
-
|
71
|
+
import(/* @vite-ignore */ import.meta.url).then((currentExports) => {
|
72
|
+
RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports);
|
73
|
+
import.meta.hot.accept((nextExports) => {
|
74
|
+
if (!nextExports) return;
|
75
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports);
|
76
|
+
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
|
77
|
+
});
|
78
|
+
});
|
121
79
|
}`;
|
122
80
|
function addRefreshWrapper(code, id) {
|
123
|
-
return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer;
|
81
|
+
return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer.replace("__SOURCE__", JSON.stringify(id));
|
124
82
|
}
|
125
83
|
|
126
84
|
const prependReactImportCode = "import React from 'react'; ";
|
85
|
+
const refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
|
127
86
|
function viteReact(opts = {}) {
|
128
87
|
let devBase = "/";
|
129
88
|
let filter = vite.createFilter(opts.include, opts.exclude);
|
@@ -270,6 +229,9 @@ function viteReact(opts = {}) {
|
|
270
229
|
const parserPlugins = [
|
271
230
|
...babelOptions.parserOpts.plugins,
|
272
231
|
"importMeta",
|
232
|
+
// This plugin is applied before esbuild transforms the code,
|
233
|
+
// so we need to enable some stage 3 syntax that is supported in
|
234
|
+
// TypeScript and some environments already.
|
273
235
|
"topLevelAwait",
|
274
236
|
"classProperties",
|
275
237
|
"classPrivateProperties",
|
@@ -298,11 +260,12 @@ function viteReact(opts = {}) {
|
|
298
260
|
},
|
299
261
|
plugins,
|
300
262
|
sourceMaps: true,
|
263
|
+
// Vite handles sourcemap flattening
|
301
264
|
inputSourceMap: inputMap ?? false
|
302
265
|
});
|
303
266
|
if (result) {
|
304
267
|
let code2 = result.code;
|
305
|
-
if (useFastRefresh &&
|
268
|
+
if (useFastRefresh && refreshContentRE.test(code2)) {
|
306
269
|
code2 = addRefreshWrapper(code2, id);
|
307
270
|
}
|
308
271
|
return {
|
@@ -352,6 +315,9 @@ function viteReact(opts = {}) {
|
|
352
315
|
config() {
|
353
316
|
return {
|
354
317
|
optimizeDeps: {
|
318
|
+
// We can't add `react-dom` because the dependency is `react-dom/client`
|
319
|
+
// for React 18 while it's `react-dom` for React 17. We'd need to detect
|
320
|
+
// what React version the user has installed.
|
355
321
|
include: [reactJsxRuntimeId, reactJsxDevRuntimeId, "react"]
|
356
322
|
}
|
357
323
|
};
|
package/dist/index.mjs
CHANGED
@@ -17,14 +17,7 @@ const runtimeFilePath = path.join(
|
|
17
17
|
const runtimeCode = `
|
18
18
|
const exports = {}
|
19
19
|
${fs.readFileSync(runtimeFilePath, "utf-8")}
|
20
|
-
|
21
|
-
let handle
|
22
|
-
return () => {
|
23
|
-
clearTimeout(handle)
|
24
|
-
handle = setTimeout(fn, delay)
|
25
|
-
}
|
26
|
-
}
|
27
|
-
exports.performReactRefresh = debounce(exports.performReactRefresh, 16)
|
20
|
+
${fs.readFileSync(_require.resolve("./refreshUtils.js"), "utf-8")}
|
28
21
|
export default exports
|
29
22
|
`;
|
30
23
|
const preambleCode = `
|
@@ -55,60 +48,26 @@ if (import.meta.hot) {
|
|
55
48
|
};
|
56
49
|
window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
|
57
50
|
}`.replace(/\n+/g, "");
|
58
|
-
const timeout = `
|
59
|
-
if (!window.__vite_plugin_react_timeout) {
|
60
|
-
window.__vite_plugin_react_timeout = setTimeout(() => {
|
61
|
-
window.__vite_plugin_react_timeout = 0;
|
62
|
-
RefreshRuntime.performReactRefresh();
|
63
|
-
}, 30);
|
64
|
-
}
|
65
|
-
`;
|
66
|
-
const checkAndAccept = `
|
67
|
-
function isReactRefreshBoundary(mod) {
|
68
|
-
if (mod == null || typeof mod !== 'object') {
|
69
|
-
return false;
|
70
|
-
}
|
71
|
-
let hasExports = false;
|
72
|
-
let areAllExportsComponents = true;
|
73
|
-
for (const exportName in mod) {
|
74
|
-
hasExports = true;
|
75
|
-
if (exportName === '__esModule') {
|
76
|
-
continue;
|
77
|
-
}
|
78
|
-
const desc = Object.getOwnPropertyDescriptor(mod, exportName);
|
79
|
-
if (desc && desc.get) {
|
80
|
-
// Don't invoke getters as they may have side effects.
|
81
|
-
return false;
|
82
|
-
}
|
83
|
-
const exportValue = mod[exportName];
|
84
|
-
if (!RefreshRuntime.isLikelyComponentType(exportValue)) {
|
85
|
-
areAllExportsComponents = false;
|
86
|
-
}
|
87
|
-
}
|
88
|
-
return hasExports && areAllExportsComponents;
|
89
|
-
}
|
90
|
-
|
91
|
-
import.meta.hot.accept(mod => {
|
92
|
-
if (!mod) return;
|
93
|
-
if (isReactRefreshBoundary(mod)) {
|
94
|
-
${timeout}
|
95
|
-
} else {
|
96
|
-
import.meta.hot.invalidate();
|
97
|
-
}
|
98
|
-
});
|
99
|
-
`;
|
100
51
|
const footer = `
|
101
52
|
if (import.meta.hot) {
|
102
53
|
window.$RefreshReg$ = prevRefreshReg;
|
103
54
|
window.$RefreshSig$ = prevRefreshSig;
|
104
55
|
|
105
|
-
|
56
|
+
import(/* @vite-ignore */ import.meta.url).then((currentExports) => {
|
57
|
+
RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports);
|
58
|
+
import.meta.hot.accept((nextExports) => {
|
59
|
+
if (!nextExports) return;
|
60
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports);
|
61
|
+
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
|
62
|
+
});
|
63
|
+
});
|
106
64
|
}`;
|
107
65
|
function addRefreshWrapper(code, id) {
|
108
|
-
return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer;
|
66
|
+
return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer.replace("__SOURCE__", JSON.stringify(id));
|
109
67
|
}
|
110
68
|
|
111
69
|
const prependReactImportCode = "import React from 'react'; ";
|
70
|
+
const refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
|
112
71
|
function viteReact(opts = {}) {
|
113
72
|
let devBase = "/";
|
114
73
|
let filter = createFilter(opts.include, opts.exclude);
|
@@ -255,6 +214,9 @@ function viteReact(opts = {}) {
|
|
255
214
|
const parserPlugins = [
|
256
215
|
...babelOptions.parserOpts.plugins,
|
257
216
|
"importMeta",
|
217
|
+
// This plugin is applied before esbuild transforms the code,
|
218
|
+
// so we need to enable some stage 3 syntax that is supported in
|
219
|
+
// TypeScript and some environments already.
|
258
220
|
"topLevelAwait",
|
259
221
|
"classProperties",
|
260
222
|
"classPrivateProperties",
|
@@ -283,11 +245,12 @@ function viteReact(opts = {}) {
|
|
283
245
|
},
|
284
246
|
plugins,
|
285
247
|
sourceMaps: true,
|
248
|
+
// Vite handles sourcemap flattening
|
286
249
|
inputSourceMap: inputMap ?? false
|
287
250
|
});
|
288
251
|
if (result) {
|
289
252
|
let code2 = result.code;
|
290
|
-
if (useFastRefresh &&
|
253
|
+
if (useFastRefresh && refreshContentRE.test(code2)) {
|
291
254
|
code2 = addRefreshWrapper(code2, id);
|
292
255
|
}
|
293
256
|
return {
|
@@ -337,6 +300,9 @@ function viteReact(opts = {}) {
|
|
337
300
|
config() {
|
338
301
|
return {
|
339
302
|
optimizeDeps: {
|
303
|
+
// We can't add `react-dom` because the dependency is `react-dom/client`
|
304
|
+
// for React 18 while it's `react-dom` for React 17. We'd need to detect
|
305
|
+
// what React version the user has installed.
|
340
306
|
include: [reactJsxRuntimeId, reactJsxDevRuntimeId, "react"]
|
341
307
|
}
|
342
308
|
};
|
@@ -0,0 +1,57 @@
|
|
1
|
+
function debounce(fn, delay) {
|
2
|
+
let handle
|
3
|
+
return () => {
|
4
|
+
clearTimeout(handle)
|
5
|
+
handle = setTimeout(fn, delay)
|
6
|
+
}
|
7
|
+
}
|
8
|
+
|
9
|
+
const enqueueUpdate = debounce(exports.performReactRefresh, 16)
|
10
|
+
|
11
|
+
// Taken from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/lib/runtime/RefreshUtils.js#L141
|
12
|
+
// This allows to resister components not detected by SWC like styled component
|
13
|
+
function registerExportsForReactRefresh(filename, moduleExports) {
|
14
|
+
for (const key in moduleExports) {
|
15
|
+
if (key === '__esModule') continue
|
16
|
+
const exportValue = moduleExports[key]
|
17
|
+
if (exports.isLikelyComponentType(exportValue)) {
|
18
|
+
exports.register(exportValue, filename + ' ' + key)
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
function validateRefreshBoundaryAndEnqueueUpdate(prevExports, nextExports) {
|
24
|
+
if (!predicateOnExport(prevExports, (key) => !!nextExports[key])) {
|
25
|
+
return 'Could not Fast Refresh (export removed)'
|
26
|
+
}
|
27
|
+
|
28
|
+
let hasExports = false
|
29
|
+
const allExportsAreComponentsOrUnchanged = predicateOnExport(
|
30
|
+
nextExports,
|
31
|
+
(key, value) => {
|
32
|
+
hasExports = true
|
33
|
+
if (exports.isLikelyComponentType(value)) return true
|
34
|
+
if (!prevExports[key]) return false
|
35
|
+
return prevExports[key] === nextExports[key]
|
36
|
+
},
|
37
|
+
)
|
38
|
+
if (hasExports && allExportsAreComponentsOrUnchanged) {
|
39
|
+
enqueueUpdate()
|
40
|
+
} else {
|
41
|
+
return 'Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react#consistent-components-exports'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
function predicateOnExport(moduleExports, predicate) {
|
46
|
+
for (const key in moduleExports) {
|
47
|
+
if (key === '__esModule') continue
|
48
|
+
const desc = Object.getOwnPropertyDescriptor(moduleExports, key)
|
49
|
+
if (desc && desc.get) return false
|
50
|
+
if (!predicate(key, moduleExports[key])) return false
|
51
|
+
}
|
52
|
+
return true
|
53
|
+
}
|
54
|
+
|
55
|
+
exports.registerExportsForReactRefresh = registerExportsForReactRefresh
|
56
|
+
exports.validateRefreshBoundaryAndEnqueueUpdate =
|
57
|
+
validateRefreshBoundaryAndEnqueueUpdate
|
package/package.json
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitejs/plugin-react",
|
3
|
-
"version": "3.0.
|
3
|
+
"version": "3.1.0-beta.0",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "Evan You",
|
6
6
|
"contributors": [
|
7
|
-
"Alec Larson"
|
7
|
+
"Alec Larson",
|
8
|
+
"Arnaud Barré"
|
8
9
|
],
|
9
10
|
"files": [
|
10
11
|
"dist"
|
@@ -21,7 +22,7 @@
|
|
21
22
|
},
|
22
23
|
"scripts": {
|
23
24
|
"dev": "unbuild --stub",
|
24
|
-
"build": "unbuild && pnpm run patch-cjs",
|
25
|
+
"build": "unbuild && pnpm run patch-cjs && tsx scripts/copyRefreshUtils.ts",
|
25
26
|
"patch-cjs": "tsx ../../scripts/patchCJS.ts",
|
26
27
|
"prepublishOnly": "npm run build"
|
27
28
|
},
|
@@ -38,13 +39,13 @@
|
|
38
39
|
},
|
39
40
|
"homepage": "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#readme",
|
40
41
|
"dependencies": {
|
41
|
-
"@babel/core": "^7.20.
|
42
|
+
"@babel/core": "^7.20.12",
|
42
43
|
"@babel/plugin-transform-react-jsx-self": "^7.18.6",
|
43
44
|
"@babel/plugin-transform-react-jsx-source": "^7.19.6",
|
44
45
|
"magic-string": "^0.27.0",
|
45
46
|
"react-refresh": "^0.14.0"
|
46
47
|
},
|
47
48
|
"peerDependencies": {
|
48
|
-
"vite": "^4.0.0"
|
49
|
+
"vite": "^4.1.0-beta.0"
|
49
50
|
}
|
50
51
|
}
|