@vitejs/plugin-react-swc 3.5.0 → 3.7.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 +19 -2
- package/index.cjs +20 -15
- package/index.d.ts +8 -1
- package/index.mjs +20 -15
- package/package.json +2 -2
- package/refresh-runtime.js +35 -21
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ Enable TypeScript decorators. Requires `experimentalDecorators` in tsconfig.
|
|
|
56
56
|
react({ tsDecorators: true });
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
### plugins
|
|
60
60
|
|
|
61
61
|
Use SWC plugins. Enable SWC at build time.
|
|
62
62
|
|
|
@@ -64,7 +64,7 @@ Use SWC plugins. Enable SWC at build time.
|
|
|
64
64
|
react({ plugins: [["@swc/plugin-styled-components", {}]] });
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
### devTarget
|
|
68
68
|
|
|
69
69
|
Set the target for SWC in dev. This can avoid to down-transpile private class method for example.
|
|
70
70
|
|
|
@@ -76,6 +76,23 @@ For production target, see https://vitejs.dev/config/build-options.html#build-ta
|
|
|
76
76
|
react({ devTarget: "es2022" });
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
### parserConfig
|
|
80
|
+
|
|
81
|
+
Override the default include list (.ts, .tsx, .mts, .jsx, .mdx).
|
|
82
|
+
|
|
83
|
+
This requires to redefine the config for any file you want to be included (ts, mdx, ...).
|
|
84
|
+
|
|
85
|
+
If you want to trigger fast refresh on compiled JS, use `jsx: true`. Exclusion of node_modules should be handled by the function if needed. Using this option to use JSX inside `.js` files is highly discouraged and can be removed in any future version.
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
react({
|
|
89
|
+
parserConfig(id) {
|
|
90
|
+
if (id.endsWith(".res")) return { syntax: "ecmascript", jsx: true };
|
|
91
|
+
if (id.endsWith(".ts")) return { syntax: "typescript", tsx: false };
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
79
96
|
## Consistent components exports
|
|
80
97
|
|
|
81
98
|
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).
|
package/index.cjs
CHANGED
|
@@ -14,6 +14,7 @@ var _dirname = typeof __dirname !== "undefined" ? __dirname : (0, import_path.di
|
|
|
14
14
|
var resolve = (0, import_module.createRequire)(
|
|
15
15
|
typeof __filename !== "undefined" ? __filename : import_meta.url
|
|
16
16
|
).resolve;
|
|
17
|
+
var reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/;
|
|
17
18
|
var refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
|
|
18
19
|
var _a, _b;
|
|
19
20
|
var isWebContainer = (_b = (_a = globalThis.process) == null ? void 0 : _a.versions) == null ? void 0 : _b.webcontainer;
|
|
@@ -23,7 +24,8 @@ var react = (_options) => {
|
|
|
23
24
|
jsxImportSource: (_options == null ? void 0 : _options.jsxImportSource) ?? "react",
|
|
24
25
|
tsDecorators: _options == null ? void 0 : _options.tsDecorators,
|
|
25
26
|
plugins: (_options == null ? void 0 : _options.plugins) ? _options == null ? void 0 : _options.plugins.map((el) => [resolve(el[0]), el[1]]) : void 0,
|
|
26
|
-
devTarget: (_options == null ? void 0 : _options.devTarget) ?? "es2020"
|
|
27
|
+
devTarget: (_options == null ? void 0 : _options.devTarget) ?? "es2020",
|
|
28
|
+
parserConfig: _options == null ? void 0 : _options.parserConfig
|
|
27
29
|
};
|
|
28
30
|
return [
|
|
29
31
|
{
|
|
@@ -45,8 +47,7 @@ var react = (_options) => {
|
|
|
45
47
|
}
|
|
46
48
|
}),
|
|
47
49
|
configResolved(config) {
|
|
48
|
-
if (config.server.hmr === false)
|
|
49
|
-
hmrDisabled = true;
|
|
50
|
+
if (config.server.hmr === false) hmrDisabled = true;
|
|
50
51
|
const mdxIndex = config.plugins.findIndex(
|
|
51
52
|
(p) => p.name === "@mdx-js/rollup"
|
|
52
53
|
);
|
|
@@ -86,14 +87,18 @@ var react = (_options) => {
|
|
|
86
87
|
importSource: options.jsxImportSource
|
|
87
88
|
}
|
|
88
89
|
);
|
|
89
|
-
if (!result)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
if (!result) return;
|
|
91
|
+
if (!refresh) return result;
|
|
92
|
+
const hasRefresh = refreshContentRE.test(result.code);
|
|
93
|
+
if (!hasRefresh && !reactCompRE.test(result.code)) return result;
|
|
94
|
+
const sourceMap = JSON.parse(result.map);
|
|
95
|
+
sourceMap.mappings = ";;" + sourceMap.mappings;
|
|
94
96
|
result.code = `import * as RefreshRuntime from "${runtimePublicPath}";
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
${result.code}`;
|
|
99
|
+
if (hasRefresh) {
|
|
100
|
+
sourceMap.mappings = ";;;;;;" + sourceMap.mappings;
|
|
101
|
+
result.code = `if (!window.$RefreshReg$) throw new Error("React refresh preamble was not loaded. Something is wrong.");
|
|
97
102
|
const prevRefreshReg = window.$RefreshReg$;
|
|
98
103
|
const prevRefreshSig = window.$RefreshSig$;
|
|
99
104
|
window.$RefreshReg$ = RefreshRuntime.getRefreshReg("${id}");
|
|
@@ -103,17 +108,18 @@ ${result.code}
|
|
|
103
108
|
|
|
104
109
|
window.$RefreshReg$ = prevRefreshReg;
|
|
105
110
|
window.$RefreshSig$ = prevRefreshSig;
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
result.code += `
|
|
106
114
|
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
107
115
|
RefreshRuntime.registerExportsForReactRefresh("${id}", currentExports);
|
|
108
116
|
import.meta.hot.accept((nextExports) => {
|
|
109
117
|
if (!nextExports) return;
|
|
110
|
-
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports);
|
|
118
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate("${id}", currentExports, nextExports);
|
|
111
119
|
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
|
|
112
120
|
});
|
|
113
121
|
});
|
|
114
122
|
`;
|
|
115
|
-
const sourceMap = JSON.parse(result.map);
|
|
116
|
-
sourceMap.mappings = ";;;;;;;;" + sourceMap.mappings;
|
|
117
123
|
return { code: result.code, map: sourceMap };
|
|
118
124
|
}
|
|
119
125
|
},
|
|
@@ -147,12 +153,11 @@ RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
|
147
153
|
};
|
|
148
154
|
var transformWithOptions = async (id, code, target, options, reactConfig) => {
|
|
149
155
|
const decorators = (options == null ? void 0 : options.tsDecorators) ?? false;
|
|
150
|
-
const parser = id.endsWith(".tsx") ? { syntax: "typescript", tsx: true, decorators } : id.endsWith(".ts") || id.endsWith(".mts") ? { syntax: "typescript", tsx: false, decorators } : id.endsWith(".jsx") ? { syntax: "ecmascript", jsx: true } : id.endsWith(".mdx") ? (
|
|
156
|
+
const parser = options.parserConfig ? options.parserConfig(id) : id.endsWith(".tsx") ? { syntax: "typescript", tsx: true, decorators } : id.endsWith(".ts") || id.endsWith(".mts") ? { syntax: "typescript", tsx: false, decorators } : id.endsWith(".jsx") ? { syntax: "ecmascript", jsx: true } : id.endsWith(".mdx") ? (
|
|
151
157
|
// JSX is required to trigger fast refresh transformations, even if MDX already transforms it
|
|
152
158
|
{ syntax: "ecmascript", jsx: true }
|
|
153
159
|
) : void 0;
|
|
154
|
-
if (!parser)
|
|
155
|
-
return;
|
|
160
|
+
if (!parser) return;
|
|
156
161
|
let result;
|
|
157
162
|
try {
|
|
158
163
|
result = await (0, import_core.transform)(code, {
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JscTarget } from "@swc/core";
|
|
1
|
+
import { ParserConfig, JscTarget } from "@swc/core";
|
|
2
2
|
import { PluginOption } from "vite";
|
|
3
3
|
type Options = {
|
|
4
4
|
/**
|
|
@@ -22,6 +22,13 @@ type Options = {
|
|
|
22
22
|
* @default "es2020"
|
|
23
23
|
*/
|
|
24
24
|
devTarget?: JscTarget;
|
|
25
|
+
/**
|
|
26
|
+
* Override the default include list (.ts, .tsx, .mts, .jsx, .mdx).
|
|
27
|
+
* This requires to redefine the config for any file you want to be included.
|
|
28
|
+
* If you want to trigger fast refresh on compiled JS, use `jsx: true`.
|
|
29
|
+
* Exclusion of node_modules should be handled by the function if needed.
|
|
30
|
+
*/
|
|
31
|
+
parserConfig?: (id: string) => ParserConfig | undefined;
|
|
25
32
|
};
|
|
26
33
|
declare const react: (_options?: Options) => PluginOption[];
|
|
27
34
|
export default react;
|
package/index.mjs
CHANGED
|
@@ -15,6 +15,7 @@ var _dirname = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToP
|
|
|
15
15
|
var resolve = createRequire(
|
|
16
16
|
typeof __filename !== "undefined" ? __filename : import.meta.url
|
|
17
17
|
).resolve;
|
|
18
|
+
var reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/;
|
|
18
19
|
var refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
|
|
19
20
|
var _a, _b;
|
|
20
21
|
var isWebContainer = (_b = (_a = globalThis.process) == null ? void 0 : _a.versions) == null ? void 0 : _b.webcontainer;
|
|
@@ -24,7 +25,8 @@ var react = (_options) => {
|
|
|
24
25
|
jsxImportSource: (_options == null ? void 0 : _options.jsxImportSource) ?? "react",
|
|
25
26
|
tsDecorators: _options == null ? void 0 : _options.tsDecorators,
|
|
26
27
|
plugins: (_options == null ? void 0 : _options.plugins) ? _options == null ? void 0 : _options.plugins.map((el) => [resolve(el[0]), el[1]]) : void 0,
|
|
27
|
-
devTarget: (_options == null ? void 0 : _options.devTarget) ?? "es2020"
|
|
28
|
+
devTarget: (_options == null ? void 0 : _options.devTarget) ?? "es2020",
|
|
29
|
+
parserConfig: _options == null ? void 0 : _options.parserConfig
|
|
28
30
|
};
|
|
29
31
|
return [
|
|
30
32
|
{
|
|
@@ -46,8 +48,7 @@ var react = (_options) => {
|
|
|
46
48
|
}
|
|
47
49
|
}),
|
|
48
50
|
configResolved(config) {
|
|
49
|
-
if (config.server.hmr === false)
|
|
50
|
-
hmrDisabled = true;
|
|
51
|
+
if (config.server.hmr === false) hmrDisabled = true;
|
|
51
52
|
const mdxIndex = config.plugins.findIndex(
|
|
52
53
|
(p) => p.name === "@mdx-js/rollup"
|
|
53
54
|
);
|
|
@@ -87,14 +88,18 @@ var react = (_options) => {
|
|
|
87
88
|
importSource: options.jsxImportSource
|
|
88
89
|
}
|
|
89
90
|
);
|
|
90
|
-
if (!result)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
if (!result) return;
|
|
92
|
+
if (!refresh) return result;
|
|
93
|
+
const hasRefresh = refreshContentRE.test(result.code);
|
|
94
|
+
if (!hasRefresh && !reactCompRE.test(result.code)) return result;
|
|
95
|
+
const sourceMap = JSON.parse(result.map);
|
|
96
|
+
sourceMap.mappings = ";;" + sourceMap.mappings;
|
|
95
97
|
result.code = `import * as RefreshRuntime from "${runtimePublicPath}";
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
${result.code}`;
|
|
100
|
+
if (hasRefresh) {
|
|
101
|
+
sourceMap.mappings = ";;;;;;" + sourceMap.mappings;
|
|
102
|
+
result.code = `if (!window.$RefreshReg$) throw new Error("React refresh preamble was not loaded. Something is wrong.");
|
|
98
103
|
const prevRefreshReg = window.$RefreshReg$;
|
|
99
104
|
const prevRefreshSig = window.$RefreshSig$;
|
|
100
105
|
window.$RefreshReg$ = RefreshRuntime.getRefreshReg("${id}");
|
|
@@ -104,17 +109,18 @@ ${result.code}
|
|
|
104
109
|
|
|
105
110
|
window.$RefreshReg$ = prevRefreshReg;
|
|
106
111
|
window.$RefreshSig$ = prevRefreshSig;
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
result.code += `
|
|
107
115
|
RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
108
116
|
RefreshRuntime.registerExportsForReactRefresh("${id}", currentExports);
|
|
109
117
|
import.meta.hot.accept((nextExports) => {
|
|
110
118
|
if (!nextExports) return;
|
|
111
|
-
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports);
|
|
119
|
+
const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate("${id}", currentExports, nextExports);
|
|
112
120
|
if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage);
|
|
113
121
|
});
|
|
114
122
|
});
|
|
115
123
|
`;
|
|
116
|
-
const sourceMap = JSON.parse(result.map);
|
|
117
|
-
sourceMap.mappings = ";;;;;;;;" + sourceMap.mappings;
|
|
118
124
|
return { code: result.code, map: sourceMap };
|
|
119
125
|
}
|
|
120
126
|
},
|
|
@@ -148,12 +154,11 @@ RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => {
|
|
|
148
154
|
};
|
|
149
155
|
var transformWithOptions = async (id, code, target, options, reactConfig) => {
|
|
150
156
|
const decorators = (options == null ? void 0 : options.tsDecorators) ?? false;
|
|
151
|
-
const parser = id.endsWith(".tsx") ? { syntax: "typescript", tsx: true, decorators } : id.endsWith(".ts") || id.endsWith(".mts") ? { syntax: "typescript", tsx: false, decorators } : id.endsWith(".jsx") ? { syntax: "ecmascript", jsx: true } : id.endsWith(".mdx") ? (
|
|
157
|
+
const parser = options.parserConfig ? options.parserConfig(id) : id.endsWith(".tsx") ? { syntax: "typescript", tsx: true, decorators } : id.endsWith(".ts") || id.endsWith(".mts") ? { syntax: "typescript", tsx: false, decorators } : id.endsWith(".jsx") ? { syntax: "ecmascript", jsx: true } : id.endsWith(".mdx") ? (
|
|
152
158
|
// JSX is required to trigger fast refresh transformations, even if MDX already transforms it
|
|
153
159
|
{ syntax: "ecmascript", jsx: true }
|
|
154
160
|
) : void 0;
|
|
155
|
-
if (!parser)
|
|
156
|
-
return;
|
|
161
|
+
if (!parser) return;
|
|
157
162
|
let result;
|
|
158
163
|
try {
|
|
159
164
|
result = await transform(code, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitejs/plugin-react-swc",
|
|
3
3
|
"description": "Speed up your Vite dev server with SWC",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.7.0",
|
|
5
5
|
"author": "Arnaud Barré (https://github.com/ArnaudBarre)",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "github:vitejs/vite-plugin-react-swc",
|
|
@@ -28,6 +28,6 @@
|
|
|
28
28
|
"vite": "^4 || ^5"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@swc/core": "^1.
|
|
31
|
+
"@swc/core": "^1.5.7"
|
|
32
32
|
}
|
|
33
33
|
}
|
package/refresh-runtime.js
CHANGED
|
@@ -17,16 +17,16 @@ function computeFullKey(signature) {
|
|
|
17
17
|
return signature.fullKey;
|
|
18
18
|
}
|
|
19
19
|
let fullKey = signature.ownKey;
|
|
20
|
-
let
|
|
20
|
+
let hooks2;
|
|
21
21
|
try {
|
|
22
|
-
|
|
22
|
+
hooks2 = signature.getCustomHooks();
|
|
23
23
|
} catch (err) {
|
|
24
24
|
signature.forceReset = true;
|
|
25
25
|
signature.fullKey = fullKey;
|
|
26
26
|
return fullKey;
|
|
27
27
|
}
|
|
28
|
-
for (let i = 0; i <
|
|
29
|
-
const hook =
|
|
28
|
+
for (let i = 0; i < hooks2.length; i++) {
|
|
29
|
+
const hook = hooks2[i];
|
|
30
30
|
if (typeof hook !== "function") {
|
|
31
31
|
signature.forceReset = true;
|
|
32
32
|
signature.fullKey = fullKey;
|
|
@@ -374,8 +374,7 @@ function getRefreshReg(filename) {
|
|
|
374
374
|
}
|
|
375
375
|
function registerExportsForReactRefresh(filename, moduleExports) {
|
|
376
376
|
for (const key in moduleExports) {
|
|
377
|
-
if (key === "__esModule")
|
|
378
|
-
continue;
|
|
377
|
+
if (key === "__esModule") continue;
|
|
379
378
|
const exportValue = moduleExports[key];
|
|
380
379
|
if (isLikelyComponentType(exportValue)) {
|
|
381
380
|
register(exportValue, filename + " export " + key);
|
|
@@ -389,39 +388,54 @@ function debounce(fn, delay) {
|
|
|
389
388
|
handle = setTimeout(fn, delay);
|
|
390
389
|
};
|
|
391
390
|
}
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
391
|
+
const hooks = [];
|
|
392
|
+
window.__registerBeforePerformReactRefresh = (cb) => {
|
|
393
|
+
hooks.push(cb);
|
|
394
|
+
};
|
|
395
|
+
const enqueueUpdate = debounce(async () => {
|
|
396
|
+
if (hooks.length) await Promise.all(hooks.map((cb) => cb()));
|
|
397
|
+
performReactRefresh();
|
|
398
|
+
}, 16);
|
|
399
|
+
function validateRefreshBoundaryAndEnqueueUpdate(id, prevExports, nextExports) {
|
|
400
|
+
var _a, _b;
|
|
401
|
+
const ignoredExports = (_b = (_a = window.__getReactRefreshIgnoredExports) == null ? void 0 : _a.call(window, { id })) != null ? _b : [];
|
|
402
|
+
if (predicateOnExport(
|
|
403
|
+
ignoredExports,
|
|
404
|
+
prevExports,
|
|
405
|
+
(key) => key in nextExports
|
|
406
|
+
) !== true) {
|
|
395
407
|
return "Could not Fast Refresh (export removed)";
|
|
396
408
|
}
|
|
397
|
-
if (
|
|
409
|
+
if (predicateOnExport(
|
|
410
|
+
ignoredExports,
|
|
411
|
+
nextExports,
|
|
412
|
+
(key) => key in prevExports
|
|
413
|
+
) !== true) {
|
|
398
414
|
return "Could not Fast Refresh (new export)";
|
|
399
415
|
}
|
|
400
416
|
let hasExports = false;
|
|
401
417
|
const allExportsAreComponentsOrUnchanged = predicateOnExport(
|
|
418
|
+
ignoredExports,
|
|
402
419
|
nextExports,
|
|
403
420
|
(key, value) => {
|
|
404
421
|
hasExports = true;
|
|
405
|
-
if (isLikelyComponentType(value))
|
|
406
|
-
return true;
|
|
422
|
+
if (isLikelyComponentType(value)) return true;
|
|
407
423
|
return prevExports[key] === nextExports[key];
|
|
408
424
|
}
|
|
409
425
|
);
|
|
410
|
-
if (hasExports && allExportsAreComponentsOrUnchanged) {
|
|
426
|
+
if (hasExports && allExportsAreComponentsOrUnchanged === true) {
|
|
411
427
|
enqueueUpdate();
|
|
412
428
|
} else {
|
|
413
|
-
return
|
|
429
|
+
return `Could not Fast Refresh ("${allExportsAreComponentsOrUnchanged}" export is incompatible). Learn more at https://github.com/vitejs/vite-plugin-react-swc#consistent-components-exports`;
|
|
414
430
|
}
|
|
415
431
|
}
|
|
416
|
-
function predicateOnExport(moduleExports, predicate) {
|
|
432
|
+
function predicateOnExport(ignoredExports, moduleExports, predicate) {
|
|
417
433
|
for (const key in moduleExports) {
|
|
418
|
-
if (key === "__esModule")
|
|
419
|
-
|
|
434
|
+
if (key === "__esModule") continue;
|
|
435
|
+
if (ignoredExports.includes(key)) continue;
|
|
420
436
|
const desc = Object.getOwnPropertyDescriptor(moduleExports, key);
|
|
421
|
-
if (desc && desc.get)
|
|
422
|
-
|
|
423
|
-
if (!predicate(key, moduleExports[key]))
|
|
424
|
-
return false;
|
|
437
|
+
if (desc && desc.get) return key;
|
|
438
|
+
if (!predicate(key, moduleExports[key])) return key;
|
|
425
439
|
}
|
|
426
440
|
return true;
|
|
427
441
|
}
|