@vitejs/plugin-react 4.0.4 → 4.1.1

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/dist/index.cjs CHANGED
@@ -1,31 +1,18 @@
1
1
  'use strict';
2
2
 
3
- const babel = require('@babel/core');
4
3
  const vite = require('vite');
5
4
  const fs = require('node:fs');
6
5
  const path = require('node:path');
7
6
  const node_module = require('node:module');
8
7
 
8
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
10
10
 
11
- function _interopNamespaceCompat(e) {
12
- if (e && typeof e === 'object' && 'default' in e) return e;
13
- const n = Object.create(null);
14
- if (e) {
15
- for (const k in e) {
16
- n[k] = e[k];
17
- }
18
- }
19
- n.default = e;
20
- return n;
21
- }
22
-
23
- const babel__namespace = /*#__PURE__*/_interopNamespaceCompat(babel);
24
11
  const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
25
12
  const path__default = /*#__PURE__*/_interopDefaultCompat(path);
26
13
 
27
14
  const runtimePublicPath = "/@react-refresh";
28
- const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
15
+ const _require = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
29
16
  const reactRefreshDir = path__default.dirname(
30
17
  _require.resolve("react-refresh/package.json")
31
18
  );
@@ -86,13 +73,22 @@ function addRefreshWrapper(code, id) {
86
73
  return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer.replace("__SOURCE__", JSON.stringify(id));
87
74
  }
88
75
 
76
+ let babel;
77
+ async function loadBabel() {
78
+ if (!babel) {
79
+ babel = await import('@babel/core');
80
+ }
81
+ return babel;
82
+ }
89
83
  const refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
90
84
  const defaultIncludeRE = /\.[tj]sx?$/;
91
85
  const tsRE = /\.tsx?$/;
92
86
  function viteReact(opts = {}) {
93
87
  let devBase = "/";
94
88
  const filter = vite.createFilter(opts.include ?? defaultIncludeRE, opts.exclude);
95
- const devRuntime = `${opts.jsxImportSource ?? "react"}/jsx-dev-runtime`;
89
+ const jsxImportSource = opts.jsxImportSource ?? "react";
90
+ const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`;
91
+ const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`;
96
92
  let isProduction = true;
97
93
  let projectRoot = process.cwd();
98
94
  let skipFastRefresh = false;
@@ -155,7 +151,7 @@ function viteReact(opts = {}) {
155
151
  })();
156
152
  const plugins = [...babelOptions.plugins];
157
153
  const isJSX = filepath.endsWith("x");
158
- const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(devRuntime)));
154
+ const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)));
159
155
  if (useFastRefresh) {
160
156
  plugins.push([
161
157
  await loadPlugin("react-refresh/babel"),
@@ -180,11 +176,14 @@ function viteReact(opts = {}) {
180
176
  if (tsRE.test(filepath)) {
181
177
  parserPlugins.push("typescript");
182
178
  }
183
- const result = await babel__namespace.transformAsync(code, {
179
+ const babel2 = await loadBabel();
180
+ const result = await babel2.transformAsync(code, {
184
181
  ...babelOptions,
185
182
  root: projectRoot,
186
183
  filename: id,
187
184
  sourceFileName: filepath,
185
+ // Required for esbuild.jsxDev to provide correct line numbers
186
+ retainLines: !isProduction && isJSX && opts.jsxRuntime !== "classic",
188
187
  parserOpts: {
189
188
  ...babelOptions.parserOpts,
190
189
  sourceType: "module",
@@ -216,7 +215,7 @@ function viteReact(opts = {}) {
216
215
  // We can't add `react-dom` because the dependency is `react-dom/client`
217
216
  // for React 18 while it's `react-dom` for React 17. We'd need to detect
218
217
  // what React version the user has installed.
219
- include: ["react", devRuntime]
218
+ include: ["react", jsxImportDevRuntime, jsxImportRuntime]
220
219
  },
221
220
  resolve: {
222
221
  dedupe: ["react", "react-dom"]
@@ -0,0 +1,58 @@
1
+ import { TransformOptions, ParserOptions } from '@babel/core';
2
+ import { ResolvedConfig, PluginOption } from 'vite';
3
+
4
+ interface Options {
5
+ include?: string | RegExp | Array<string | RegExp>;
6
+ exclude?: string | RegExp | Array<string | RegExp>;
7
+ /**
8
+ * Control where the JSX factory is imported from.
9
+ * https://esbuild.github.io/api/#jsx-import-source
10
+ * @default 'react'
11
+ */
12
+ jsxImportSource?: string;
13
+ /**
14
+ * Note: Skipping React import with classic runtime is not supported from v4
15
+ * @default "automatic"
16
+ */
17
+ jsxRuntime?: 'classic' | 'automatic';
18
+ /**
19
+ * Babel configuration applied in both dev and prod.
20
+ */
21
+ babel?: BabelOptions | ((id: string, options: {
22
+ ssr?: boolean;
23
+ }) => BabelOptions);
24
+ }
25
+ type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
26
+ /**
27
+ * The object type used by the `options` passed to plugins with
28
+ * an `api.reactBabel` method.
29
+ */
30
+ interface ReactBabelOptions extends BabelOptions {
31
+ plugins: Extract<BabelOptions['plugins'], any[]>;
32
+ presets: Extract<BabelOptions['presets'], any[]>;
33
+ overrides: Extract<BabelOptions['overrides'], any[]>;
34
+ parserOpts: ParserOptions & {
35
+ plugins: Extract<ParserOptions['plugins'], any[]>;
36
+ };
37
+ }
38
+ type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void;
39
+ type ReactBabelHookContext = {
40
+ ssr: boolean;
41
+ id: string;
42
+ };
43
+ declare module 'vite' {
44
+ interface Plugin {
45
+ api?: {
46
+ /**
47
+ * Manipulate the Babel options of `@vitejs/plugin-react`
48
+ */
49
+ reactBabel?: ReactBabelHook;
50
+ };
51
+ }
52
+ }
53
+ declare function viteReact(opts?: Options): PluginOption[];
54
+ declare namespace viteReact {
55
+ var preambleCode: string;
56
+ }
57
+
58
+ export { type BabelOptions, type Options, type ReactBabelOptions, viteReact as default };
@@ -0,0 +1,58 @@
1
+ import { TransformOptions, ParserOptions } from '@babel/core';
2
+ import { ResolvedConfig, PluginOption } from 'vite';
3
+
4
+ interface Options {
5
+ include?: string | RegExp | Array<string | RegExp>;
6
+ exclude?: string | RegExp | Array<string | RegExp>;
7
+ /**
8
+ * Control where the JSX factory is imported from.
9
+ * https://esbuild.github.io/api/#jsx-import-source
10
+ * @default 'react'
11
+ */
12
+ jsxImportSource?: string;
13
+ /**
14
+ * Note: Skipping React import with classic runtime is not supported from v4
15
+ * @default "automatic"
16
+ */
17
+ jsxRuntime?: 'classic' | 'automatic';
18
+ /**
19
+ * Babel configuration applied in both dev and prod.
20
+ */
21
+ babel?: BabelOptions | ((id: string, options: {
22
+ ssr?: boolean;
23
+ }) => BabelOptions);
24
+ }
25
+ type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>;
26
+ /**
27
+ * The object type used by the `options` passed to plugins with
28
+ * an `api.reactBabel` method.
29
+ */
30
+ interface ReactBabelOptions extends BabelOptions {
31
+ plugins: Extract<BabelOptions['plugins'], any[]>;
32
+ presets: Extract<BabelOptions['presets'], any[]>;
33
+ overrides: Extract<BabelOptions['overrides'], any[]>;
34
+ parserOpts: ParserOptions & {
35
+ plugins: Extract<ParserOptions['plugins'], any[]>;
36
+ };
37
+ }
38
+ type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void;
39
+ type ReactBabelHookContext = {
40
+ ssr: boolean;
41
+ id: string;
42
+ };
43
+ declare module 'vite' {
44
+ interface Plugin {
45
+ api?: {
46
+ /**
47
+ * Manipulate the Babel options of `@vitejs/plugin-react`
48
+ */
49
+ reactBabel?: ReactBabelHook;
50
+ };
51
+ }
52
+ }
53
+ declare function viteReact(opts?: Options): PluginOption[];
54
+ declare namespace viteReact {
55
+ var preambleCode: string;
56
+ }
57
+
58
+ export { type BabelOptions, type Options, type ReactBabelOptions, viteReact as default };
package/dist/index.d.ts CHANGED
@@ -55,4 +55,4 @@ declare namespace viteReact {
55
55
  var preambleCode: string;
56
56
  }
57
57
 
58
- export { BabelOptions, Options, ReactBabelOptions, viteReact as default };
58
+ export { type BabelOptions, type Options, type ReactBabelOptions, viteReact as default };
package/dist/index.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import * as babel from '@babel/core';
2
1
  import { createFilter } from 'vite';
3
2
  import fs from 'node:fs';
4
3
  import path from 'node:path';
@@ -66,13 +65,22 @@ function addRefreshWrapper(code, id) {
66
65
  return header.replace("__SOURCE__", JSON.stringify(id)) + code + footer.replace("__SOURCE__", JSON.stringify(id));
67
66
  }
68
67
 
68
+ let babel;
69
+ async function loadBabel() {
70
+ if (!babel) {
71
+ babel = await import('@babel/core');
72
+ }
73
+ return babel;
74
+ }
69
75
  const refreshContentRE = /\$Refresh(?:Reg|Sig)\$\(/;
70
76
  const defaultIncludeRE = /\.[tj]sx?$/;
71
77
  const tsRE = /\.tsx?$/;
72
78
  function viteReact(opts = {}) {
73
79
  let devBase = "/";
74
80
  const filter = createFilter(opts.include ?? defaultIncludeRE, opts.exclude);
75
- const devRuntime = `${opts.jsxImportSource ?? "react"}/jsx-dev-runtime`;
81
+ const jsxImportSource = opts.jsxImportSource ?? "react";
82
+ const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`;
83
+ const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`;
76
84
  let isProduction = true;
77
85
  let projectRoot = process.cwd();
78
86
  let skipFastRefresh = false;
@@ -135,7 +143,7 @@ function viteReact(opts = {}) {
135
143
  })();
136
144
  const plugins = [...babelOptions.plugins];
137
145
  const isJSX = filepath.endsWith("x");
138
- const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(devRuntime)));
146
+ const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)));
139
147
  if (useFastRefresh) {
140
148
  plugins.push([
141
149
  await loadPlugin("react-refresh/babel"),
@@ -160,11 +168,14 @@ function viteReact(opts = {}) {
160
168
  if (tsRE.test(filepath)) {
161
169
  parserPlugins.push("typescript");
162
170
  }
163
- const result = await babel.transformAsync(code, {
171
+ const babel2 = await loadBabel();
172
+ const result = await babel2.transformAsync(code, {
164
173
  ...babelOptions,
165
174
  root: projectRoot,
166
175
  filename: id,
167
176
  sourceFileName: filepath,
177
+ // Required for esbuild.jsxDev to provide correct line numbers
178
+ retainLines: !isProduction && isJSX && opts.jsxRuntime !== "classic",
168
179
  parserOpts: {
169
180
  ...babelOptions.parserOpts,
170
181
  sourceType: "module",
@@ -196,7 +207,7 @@ function viteReact(opts = {}) {
196
207
  // We can't add `react-dom` because the dependency is `react-dom/client`
197
208
  // for React 18 while it's `react-dom` for React 17. We'd need to detect
198
209
  // what React version the user has installed.
199
- include: ["react", devRuntime]
210
+ include: ["react", jsxImportDevRuntime, jsxImportRuntime]
200
211
  },
201
212
  resolve: {
202
213
  dedupe: ["react", "react-dom"]
@@ -26,9 +26,12 @@ function registerExportsForReactRefresh(filename, moduleExports) {
26
26
  }
27
27
 
28
28
  function validateRefreshBoundaryAndEnqueueUpdate(prevExports, nextExports) {
29
- if (!predicateOnExport(prevExports, (key) => !!nextExports[key])) {
29
+ if (!predicateOnExport(prevExports, (key) => key in nextExports)) {
30
30
  return 'Could not Fast Refresh (export removed)'
31
31
  }
32
+ if (!predicateOnExport(nextExports, (key) => key in prevExports)) {
33
+ return 'Could not Fast Refresh (new export)'
34
+ }
32
35
 
33
36
  let hasExports = false
34
37
  const allExportsAreComponentsOrUnchanged = predicateOnExport(
@@ -36,7 +39,6 @@ function validateRefreshBoundaryAndEnqueueUpdate(prevExports, nextExports) {
36
39
  (key, value) => {
37
40
  hasExports = true
38
41
  if (exports.isLikelyComponentType(value)) return true
39
- if (!prevExports[key]) return false
40
42
  return prevExports[key] === nextExports[key]
41
43
  },
42
44
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitejs/plugin-react",
3
- "version": "4.0.4",
3
+ "version": "4.1.1",
4
4
  "license": "MIT",
5
5
  "author": "Evan You",
6
6
  "contributors": [
@@ -15,7 +15,6 @@
15
15
  "types": "./dist/index.d.ts",
16
16
  "exports": {
17
17
  ".": {
18
- "types": "./dist/index.d.ts",
19
18
  "import": "./dist/index.mjs",
20
19
  "require": "./dist/index.cjs"
21
20
  }
@@ -39,9 +38,10 @@
39
38
  },
40
39
  "homepage": "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react#readme",
41
40
  "dependencies": {
42
- "@babel/core": "^7.22.9",
41
+ "@babel/core": "^7.23.2",
43
42
  "@babel/plugin-transform-react-jsx-self": "^7.22.5",
44
43
  "@babel/plugin-transform-react-jsx-source": "^7.22.5",
44
+ "@types/babel__core": "^7.20.3",
45
45
  "react-refresh": "^0.14.0"
46
46
  },
47
47
  "peerDependencies": {