@vitejs/plugin-react
Advanced tools
+320
| import { dirname, join } from "node:path"; | ||
| import { fileURLToPath } from "node:url"; | ||
| import { readFileSync } from "node:fs"; | ||
| import * as vite from "vite"; | ||
| import { createFilter } from "vite"; | ||
| import { exactRegex, makeIdFiltersToMatchWithQuery } from "@rolldown/pluginutils"; | ||
| //#region ../common/refresh-utils.ts | ||
| const runtimePublicPath = "/@react-refresh"; | ||
| const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/; | ||
| const refreshContentRE = /\$RefreshReg\$\(/; | ||
| const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice(1)}"; | ||
| injectIntoGlobalHook(window); | ||
| window.$RefreshReg$ = () => {}; | ||
| window.$RefreshSig$ = () => (type) => type;`; | ||
| const getPreambleCode = (base) => preambleCode.replace("__BASE__", base); | ||
| const avoidSourceMapOption = Symbol(); | ||
| function addRefreshWrapper(code, map, pluginName, id, reactRefreshHost = "") { | ||
| const hasRefresh = refreshContentRE.test(code); | ||
| const onlyReactComp = !hasRefresh && reactCompRE.test(code); | ||
| const normalizedMap = map === avoidSourceMapOption ? null : map; | ||
| if (!hasRefresh && !onlyReactComp) return { | ||
| code, | ||
| map: normalizedMap | ||
| }; | ||
| const avoidSourceMap = map === avoidSourceMapOption; | ||
| const newMap = typeof normalizedMap === "string" ? JSON.parse(normalizedMap) : normalizedMap; | ||
| let newCode = code; | ||
| if (hasRefresh) { | ||
| const refreshHead = removeLineBreaksIfNeeded(`let prevRefreshReg; | ||
| let prevRefreshSig; | ||
| if (import.meta.hot && !inWebWorker) { | ||
| if (!window.$RefreshReg$) { | ||
| throw new Error( | ||
| "${pluginName} can't detect preamble. Something is wrong." | ||
| ); | ||
| } | ||
| prevRefreshReg = window.$RefreshReg$; | ||
| prevRefreshSig = window.$RefreshSig$; | ||
| window.$RefreshReg$ = RefreshRuntime.getRefreshReg(${JSON.stringify(id)}); | ||
| window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform; | ||
| } | ||
| `, avoidSourceMap); | ||
| newCode = `${refreshHead}${newCode} | ||
| if (import.meta.hot && !inWebWorker) { | ||
| window.$RefreshReg$ = prevRefreshReg; | ||
| window.$RefreshSig$ = prevRefreshSig; | ||
| } | ||
| `; | ||
| if (newMap) newMap.mappings = ";".repeat(16) + newMap.mappings; | ||
| } | ||
| const sharedHead = removeLineBreaksIfNeeded(`import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}"; | ||
| const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; | ||
| `, avoidSourceMap); | ||
| newCode = `${sharedHead}${newCode} | ||
| if (import.meta.hot && !inWebWorker) { | ||
| RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => { | ||
| RefreshRuntime.registerExportsForReactRefresh(${JSON.stringify(id)}, currentExports); | ||
| import.meta.hot.accept((nextExports) => { | ||
| if (!nextExports) return; | ||
| const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(${JSON.stringify(id)}, currentExports, nextExports); | ||
| if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage); | ||
| }); | ||
| }); | ||
| } | ||
| `; | ||
| if (newMap) newMap.mappings = ";;;" + newMap.mappings; | ||
| return { | ||
| code: newCode, | ||
| map: newMap | ||
| }; | ||
| } | ||
| function removeLineBreaksIfNeeded(code, enabled) { | ||
| return enabled ? code.replace(/\n/g, "") : code; | ||
| } | ||
| //#endregion | ||
| //#region ../common/warning.ts | ||
| const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warning, defaultHandler) { | ||
| var _userConfig$build; | ||
| if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message.includes("use client") || warning.message.includes("use server"))) return; | ||
| if (warning.code === "SOURCEMAP_ERROR" && warning.message.includes("resolve original location") && warning.pos === 0) return; | ||
| if ((_userConfig$build = userConfig.build) === null || _userConfig$build === void 0 || (_userConfig$build = _userConfig$build.rollupOptions) === null || _userConfig$build === void 0 ? void 0 : _userConfig$build.onwarn) userConfig.build.rollupOptions.onwarn(warning, defaultHandler); | ||
| else defaultHandler(warning); | ||
| } } }); | ||
| //#endregion | ||
| //#region src/index.ts | ||
| const _dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const refreshRuntimePath = join(_dirname, "refresh-runtime.js"); | ||
| let babel; | ||
| async function loadBabel() { | ||
| if (!babel) babel = await import("@babel/core"); | ||
| return babel; | ||
| } | ||
| const defaultIncludeRE = /\.[tj]sx?$/; | ||
| const tsRE = /\.tsx?$/; | ||
| function viteReact(opts = {}) { | ||
| var _opts$babel; | ||
| const include = opts.include ?? defaultIncludeRE; | ||
| const exclude = opts.exclude; | ||
| const filter = createFilter(include, exclude); | ||
| const jsxImportSource = opts.jsxImportSource ?? "react"; | ||
| const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`; | ||
| const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`; | ||
| let runningInVite = false; | ||
| let isProduction = true; | ||
| let projectRoot = process.cwd(); | ||
| let skipFastRefresh = true; | ||
| let runPluginOverrides; | ||
| let staticBabelOptions; | ||
| const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/; | ||
| const viteBabel = { | ||
| name: "vite:react-babel", | ||
| enforce: "pre", | ||
| config() { | ||
| if (opts.jsxRuntime === "classic") if ("rolldownVersion" in vite) return { oxc: { jsx: { | ||
| runtime: "classic", | ||
| development: false | ||
| } } }; | ||
| else return { esbuild: { jsx: "transform" } }; | ||
| else return { | ||
| esbuild: { | ||
| jsx: "automatic", | ||
| jsxImportSource: opts.jsxImportSource | ||
| }, | ||
| optimizeDeps: "rolldownVersion" in vite ? { rollupOptions: { jsx: { mode: "automatic" } } } : { esbuildOptions: { jsx: "automatic" } } | ||
| }; | ||
| }, | ||
| configResolved(config) { | ||
| runningInVite = true; | ||
| projectRoot = config.root; | ||
| isProduction = config.isProduction; | ||
| skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false; | ||
| if ("jsxPure" in opts) config.logger.warnOnce("[@vitejs/plugin-react] jsxPure was removed. You can configure esbuild.jsxSideEffects directly."); | ||
| const hooks = config.plugins.map((plugin) => { | ||
| var _plugin$api; | ||
| return (_plugin$api = plugin.api) === null || _plugin$api === void 0 ? void 0 : _plugin$api.reactBabel; | ||
| }).filter(defined); | ||
| if ("rolldownVersion" in vite && !opts.babel && !hooks.length && !opts.disableOxcRecommendation) config.logger.warn("[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown"); | ||
| if (hooks.length > 0) runPluginOverrides = (babelOptions, context) => { | ||
| hooks.forEach((hook) => hook(babelOptions, context, config)); | ||
| }; | ||
| else if (typeof opts.babel !== "function") { | ||
| staticBabelOptions = createBabelOptions(opts.babel); | ||
| if (canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && skipFastRefresh && (opts.jsxRuntime === "classic" ? isProduction : true)) delete viteBabel.transform; | ||
| } | ||
| }, | ||
| options(options) { | ||
| if (!runningInVite) { | ||
| options.jsx = { | ||
| mode: opts.jsxRuntime, | ||
| importSource: opts.jsxImportSource | ||
| }; | ||
| return options; | ||
| } | ||
| }, | ||
| transform: { | ||
| filter: { id: { | ||
| include: makeIdFiltersToMatchWithQuery(include), | ||
| exclude: [...exclude ? makeIdFiltersToMatchWithQuery(ensureArray(exclude)) : [], /\/node_modules\//] | ||
| } }, | ||
| async handler(code, id, options) { | ||
| if (id.includes("/node_modules/")) return; | ||
| const [filepath] = id.split("?"); | ||
| if (!filter(filepath)) return; | ||
| const ssr = (options === null || options === void 0 ? void 0 : options.ssr) === true; | ||
| const babelOptions = (() => { | ||
| if (staticBabelOptions) return staticBabelOptions; | ||
| const newBabelOptions = createBabelOptions(typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel); | ||
| runPluginOverrides === null || runPluginOverrides === void 0 || runPluginOverrides(newBabelOptions, { | ||
| id, | ||
| ssr | ||
| }); | ||
| return newBabelOptions; | ||
| })(); | ||
| const plugins = [...babelOptions.plugins]; | ||
| const isJSX = filepath.endsWith("x"); | ||
| const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime))); | ||
| if (useFastRefresh) plugins.push([await loadPlugin("react-refresh/babel"), { skipEnvCheck: true }]); | ||
| if (opts.jsxRuntime === "classic" && isJSX) { | ||
| if (!isProduction) plugins.push(await loadPlugin("@babel/plugin-transform-react-jsx-self"), await loadPlugin("@babel/plugin-transform-react-jsx-source")); | ||
| } | ||
| if (canSkipBabel(plugins, babelOptions)) return; | ||
| const parserPlugins = [...babelOptions.parserOpts.plugins]; | ||
| if (!filepath.endsWith(".ts")) parserPlugins.push("jsx"); | ||
| if (tsRE.test(filepath)) parserPlugins.push("typescript"); | ||
| const babel$1 = await loadBabel(); | ||
| const result = await babel$1.transformAsync(code, { | ||
| ...babelOptions, | ||
| root: projectRoot, | ||
| filename: id, | ||
| sourceFileName: filepath, | ||
| retainLines: getReactCompilerPlugin(plugins) != null ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic", | ||
| parserOpts: { | ||
| ...babelOptions.parserOpts, | ||
| sourceType: "module", | ||
| allowAwaitOutsideFunction: true, | ||
| plugins: parserPlugins | ||
| }, | ||
| generatorOpts: { | ||
| ...babelOptions.generatorOpts, | ||
| importAttributesKeyword: "with", | ||
| decoratorsBeforeExport: true | ||
| }, | ||
| plugins, | ||
| sourceMaps: true | ||
| }); | ||
| if (result) { | ||
| if (!useFastRefresh) return { | ||
| code: result.code, | ||
| map: result.map | ||
| }; | ||
| return addRefreshWrapper(result.code, result.map, "@vitejs/plugin-react", id, opts.reactRefreshHost); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const dependencies = [ | ||
| "react", | ||
| "react-dom", | ||
| jsxImportDevRuntime, | ||
| jsxImportRuntime | ||
| ]; | ||
| const staticBabelPlugins = typeof opts.babel === "object" ? ((_opts$babel = opts.babel) === null || _opts$babel === void 0 ? void 0 : _opts$babel.plugins) ?? [] : []; | ||
| const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins); | ||
| if (reactCompilerPlugin != null) { | ||
| const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin); | ||
| dependencies.push(reactCompilerRuntimeModule); | ||
| } | ||
| const viteReactRefresh = { | ||
| name: "vite:react-refresh", | ||
| enforce: "pre", | ||
| config: (userConfig) => ({ | ||
| build: silenceUseClientWarning(userConfig), | ||
| optimizeDeps: { include: dependencies }, | ||
| resolve: { dedupe: ["react", "react-dom"] } | ||
| }), | ||
| resolveId: { | ||
| filter: { id: exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) return id; | ||
| } | ||
| }, | ||
| load: { | ||
| filter: { id: exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) return readFileSync(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react"); | ||
| } | ||
| }, | ||
| transformIndexHtml(_, config) { | ||
| if (!skipFastRefresh) return [{ | ||
| tag: "script", | ||
| attrs: { type: "module" }, | ||
| children: getPreambleCode(config.server.config.base) | ||
| }]; | ||
| } | ||
| }; | ||
| return [viteBabel, viteReactRefresh]; | ||
| } | ||
| viteReact.preambleCode = preambleCode; | ||
| function canSkipBabel(plugins, babelOptions) { | ||
| return !(plugins.length || babelOptions.presets.length || babelOptions.configFile || babelOptions.babelrc); | ||
| } | ||
| const loadedPlugin = /* @__PURE__ */ new Map(); | ||
| function loadPlugin(path) { | ||
| const cached = loadedPlugin.get(path); | ||
| if (cached) return cached; | ||
| const promise = import(path).then((module) => { | ||
| const value = module.default || module; | ||
| loadedPlugin.set(path, value); | ||
| return value; | ||
| }); | ||
| loadedPlugin.set(path, promise); | ||
| return promise; | ||
| } | ||
| function createBabelOptions(rawOptions) { | ||
| var _babelOptions$parserO; | ||
| const babelOptions = { | ||
| babelrc: false, | ||
| configFile: false, | ||
| ...rawOptions | ||
| }; | ||
| babelOptions.plugins || (babelOptions.plugins = []); | ||
| babelOptions.presets || (babelOptions.presets = []); | ||
| babelOptions.overrides || (babelOptions.overrides = []); | ||
| babelOptions.parserOpts || (babelOptions.parserOpts = {}); | ||
| (_babelOptions$parserO = babelOptions.parserOpts).plugins || (_babelOptions$parserO.plugins = []); | ||
| return babelOptions; | ||
| } | ||
| function defined(value) { | ||
| return value !== void 0; | ||
| } | ||
| function getReactCompilerPlugin(plugins) { | ||
| return plugins.find((p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler"); | ||
| } | ||
| function getReactCompilerRuntimeModule(plugin) { | ||
| let moduleName = "react/compiler-runtime"; | ||
| if (Array.isArray(plugin)) { | ||
| var _plugin$, _plugin$2, _plugin$3; | ||
| if (((_plugin$ = plugin[1]) === null || _plugin$ === void 0 ? void 0 : _plugin$.target) === "17" || ((_plugin$2 = plugin[1]) === null || _plugin$2 === void 0 ? void 0 : _plugin$2.target) === "18") moduleName = "react-compiler-runtime"; | ||
| else if (typeof ((_plugin$3 = plugin[1]) === null || _plugin$3 === void 0 ? void 0 : _plugin$3.runtimeModule) === "string") { | ||
| var _plugin$4; | ||
| moduleName = (_plugin$4 = plugin[1]) === null || _plugin$4 === void 0 ? void 0 : _plugin$4.runtimeModule; | ||
| } | ||
| } | ||
| return moduleName; | ||
| } | ||
| function ensureArray(value) { | ||
| return Array.isArray(value) ? value : [value]; | ||
| } | ||
| //#endregion | ||
| export { viteReact as default }; |
+269
-346
@@ -1,30 +0,35 @@ | ||
| 'use strict'; | ||
| //#region rolldown:runtime | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { | ||
| key = keys[i]; | ||
| if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { | ||
| get: ((k) => from[k]).bind(null, key), | ||
| enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable | ||
| }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { | ||
| value: mod, | ||
| enumerable: true | ||
| }) : target, mod)); | ||
| const node_path = require('node:path'); | ||
| const node_url = require('node:url'); | ||
| const node_fs = require('node:fs'); | ||
| const vite = require('vite'); | ||
| const pluginutils = require('@rolldown/pluginutils'); | ||
| //#endregion | ||
| const node_path = __toESM(require("node:path")); | ||
| const node_url = __toESM(require("node:url")); | ||
| const node_fs = __toESM(require("node:fs")); | ||
| const vite = __toESM(require("vite")); | ||
| const __rolldown_pluginutils = __toESM(require("@rolldown/pluginutils")); | ||
| var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; | ||
| function _interopNamespaceCompat(e) { | ||
| if (e && typeof e === 'object' && 'default' in e) return e; | ||
| const n = Object.create(null); | ||
| if (e) { | ||
| for (const k in e) { | ||
| n[k] = e[k]; | ||
| } | ||
| } | ||
| n.default = e; | ||
| return n; | ||
| } | ||
| const vite__namespace = /*#__PURE__*/_interopNamespaceCompat(vite); | ||
| //#region ../common/refresh-utils.ts | ||
| const runtimePublicPath = "/@react-refresh"; | ||
| const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/; | ||
| const refreshContentRE = /\$RefreshReg\$\(/; | ||
| const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice( | ||
| 1 | ||
| )}"; | ||
| const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice(1)}"; | ||
| injectIntoGlobalHook(window); | ||
@@ -36,12 +41,14 @@ window.$RefreshReg$ = () => {}; | ||
| function addRefreshWrapper(code, map, pluginName, id, reactRefreshHost = "") { | ||
| const hasRefresh = refreshContentRE.test(code); | ||
| const onlyReactComp = !hasRefresh && reactCompRE.test(code); | ||
| const normalizedMap = map === avoidSourceMapOption ? null : map; | ||
| if (!hasRefresh && !onlyReactComp) return { code, map: normalizedMap }; | ||
| const avoidSourceMap = map === avoidSourceMapOption; | ||
| const newMap = typeof normalizedMap === "string" ? JSON.parse(normalizedMap) : normalizedMap; | ||
| let newCode = code; | ||
| if (hasRefresh) { | ||
| const refreshHead = removeLineBreaksIfNeeded( | ||
| `let prevRefreshReg; | ||
| const hasRefresh = refreshContentRE.test(code); | ||
| const onlyReactComp = !hasRefresh && reactCompRE.test(code); | ||
| const normalizedMap = map === avoidSourceMapOption ? null : map; | ||
| if (!hasRefresh && !onlyReactComp) return { | ||
| code, | ||
| map: normalizedMap | ||
| }; | ||
| const avoidSourceMap = map === avoidSourceMapOption; | ||
| const newMap = typeof normalizedMap === "string" ? JSON.parse(normalizedMap) : normalizedMap; | ||
| let newCode = code; | ||
| if (hasRefresh) { | ||
| const refreshHead = removeLineBreaksIfNeeded(`let prevRefreshReg; | ||
| let prevRefreshSig; | ||
@@ -62,6 +69,4 @@ | ||
| `, | ||
| avoidSourceMap | ||
| ); | ||
| newCode = `${refreshHead}${newCode} | ||
| `, avoidSourceMap); | ||
| newCode = `${refreshHead}${newCode} | ||
@@ -73,25 +78,16 @@ if (import.meta.hot && !inWebWorker) { | ||
| `; | ||
| if (newMap) { | ||
| newMap.mappings = ";".repeat(16) + newMap.mappings; | ||
| } | ||
| } | ||
| const sharedHead = removeLineBreaksIfNeeded( | ||
| `import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}"; | ||
| if (newMap) newMap.mappings = ";".repeat(16) + newMap.mappings; | ||
| } | ||
| const sharedHead = removeLineBreaksIfNeeded(`import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}"; | ||
| const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; | ||
| `, | ||
| avoidSourceMap | ||
| ); | ||
| newCode = `${sharedHead}${newCode} | ||
| `, avoidSourceMap); | ||
| newCode = `${sharedHead}${newCode} | ||
| if (import.meta.hot && !inWebWorker) { | ||
| RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => { | ||
| RefreshRuntime.registerExportsForReactRefresh(${JSON.stringify( | ||
| id | ||
| )}, currentExports); | ||
| RefreshRuntime.registerExportsForReactRefresh(${JSON.stringify(id)}, currentExports); | ||
| import.meta.hot.accept((nextExports) => { | ||
| if (!nextExports) return; | ||
| const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(${JSON.stringify( | ||
| id | ||
| )}, currentExports, nextExports); | ||
| const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(${JSON.stringify(id)}, currentExports, nextExports); | ||
| if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage); | ||
@@ -102,37 +98,30 @@ }); | ||
| `; | ||
| if (newMap) { | ||
| newMap.mappings = ";;;" + newMap.mappings; | ||
| } | ||
| return { code: newCode, map: newMap }; | ||
| if (newMap) newMap.mappings = ";;;" + newMap.mappings; | ||
| return { | ||
| code: newCode, | ||
| map: newMap | ||
| }; | ||
| } | ||
| function removeLineBreaksIfNeeded(code, enabled) { | ||
| return enabled ? code.replace(/\n/g, "") : code; | ||
| return enabled ? code.replace(/\n/g, "") : code; | ||
| } | ||
| const silenceUseClientWarning = (userConfig) => ({ | ||
| rollupOptions: { | ||
| onwarn(warning, defaultHandler) { | ||
| if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message.includes("use client") || warning.message.includes("use server"))) { | ||
| return; | ||
| } | ||
| if (warning.code === "SOURCEMAP_ERROR" && warning.message.includes("resolve original location") && warning.pos === 0) { | ||
| return; | ||
| } | ||
| if (userConfig.build?.rollupOptions?.onwarn) { | ||
| userConfig.build.rollupOptions.onwarn(warning, defaultHandler); | ||
| } else { | ||
| defaultHandler(warning); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| //#endregion | ||
| //#region ../common/warning.ts | ||
| const silenceUseClientWarning = (userConfig) => ({ rollupOptions: { onwarn(warning, defaultHandler) { | ||
| var _userConfig$build; | ||
| if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message.includes("use client") || warning.message.includes("use server"))) return; | ||
| if (warning.code === "SOURCEMAP_ERROR" && warning.message.includes("resolve original location") && warning.pos === 0) return; | ||
| if ((_userConfig$build = userConfig.build) === null || _userConfig$build === void 0 || (_userConfig$build = _userConfig$build.rollupOptions) === null || _userConfig$build === void 0 ? void 0 : _userConfig$build.onwarn) userConfig.build.rollupOptions.onwarn(warning, defaultHandler); | ||
| else defaultHandler(warning); | ||
| } } }); | ||
| const _dirname = node_path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))); | ||
| const refreshRuntimePath = node_path.join(_dirname, "refresh-runtime.js") ; | ||
| //#endregion | ||
| //#region src/index.ts | ||
| const _dirname = (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href)); | ||
| const refreshRuntimePath = (0, node_path.join)(_dirname, "refresh-runtime.js"); | ||
| let babel; | ||
| async function loadBabel() { | ||
| if (!babel) { | ||
| babel = await import('@babel/core'); | ||
| } | ||
| return babel; | ||
| if (!babel) babel = await import("@babel/core"); | ||
| return babel; | ||
| } | ||
@@ -142,284 +131,218 @@ const defaultIncludeRE = /\.[tj]sx?$/; | ||
| function viteReact(opts = {}) { | ||
| const include = opts.include ?? defaultIncludeRE; | ||
| const exclude = opts.exclude; | ||
| const filter = vite.createFilter(include, exclude); | ||
| const jsxImportSource = opts.jsxImportSource ?? "react"; | ||
| const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`; | ||
| const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`; | ||
| let runningInVite = false; | ||
| let isProduction = true; | ||
| let projectRoot = process.cwd(); | ||
| let skipFastRefresh = true; | ||
| let runPluginOverrides; | ||
| let staticBabelOptions; | ||
| const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/; | ||
| const viteBabel = { | ||
| name: "vite:react-babel", | ||
| enforce: "pre", | ||
| config() { | ||
| if (opts.jsxRuntime === "classic") { | ||
| if ("rolldownVersion" in vite__namespace) { | ||
| return { | ||
| oxc: { | ||
| jsx: { | ||
| runtime: "classic", | ||
| // disable __self and __source injection even in dev | ||
| // as this plugin injects them by babel and oxc will throw | ||
| // if development is enabled and those properties are already present | ||
| development: false | ||
| } | ||
| } | ||
| }; | ||
| } else { | ||
| return { | ||
| esbuild: { | ||
| jsx: "transform" | ||
| } | ||
| }; | ||
| } | ||
| } else { | ||
| return { | ||
| esbuild: { | ||
| jsx: "automatic", | ||
| jsxImportSource: opts.jsxImportSource | ||
| }, | ||
| optimizeDeps: "rolldownVersion" in vite__namespace ? { rollupOptions: { jsx: { mode: "automatic" } } } : { esbuildOptions: { jsx: "automatic" } } | ||
| }; | ||
| } | ||
| }, | ||
| configResolved(config) { | ||
| runningInVite = true; | ||
| projectRoot = config.root; | ||
| isProduction = config.isProduction; | ||
| skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false; | ||
| if ("jsxPure" in opts) { | ||
| config.logger.warnOnce( | ||
| "[@vitejs/plugin-react] jsxPure was removed. You can configure esbuild.jsxSideEffects directly." | ||
| ); | ||
| } | ||
| const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(defined); | ||
| if ("rolldownVersion" in vite__namespace && !opts.babel && !hooks.length && !opts.disableOxcRecommendation) { | ||
| config.logger.warn( | ||
| "[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown" | ||
| ); | ||
| } | ||
| if (hooks.length > 0) { | ||
| runPluginOverrides = (babelOptions, context) => { | ||
| hooks.forEach((hook) => hook(babelOptions, context, config)); | ||
| }; | ||
| } else if (typeof opts.babel !== "function") { | ||
| staticBabelOptions = createBabelOptions(opts.babel); | ||
| if (canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && skipFastRefresh && (opts.jsxRuntime === "classic" ? isProduction : true)) { | ||
| delete viteBabel.transform; | ||
| } | ||
| } | ||
| }, | ||
| options(options) { | ||
| if (!runningInVite) { | ||
| options.jsx = { | ||
| mode: opts.jsxRuntime, | ||
| importSource: opts.jsxImportSource | ||
| }; | ||
| return options; | ||
| } | ||
| }, | ||
| transform: { | ||
| filter: { | ||
| id: { | ||
| include: pluginutils.makeIdFiltersToMatchWithQuery(include), | ||
| exclude: [ | ||
| ...exclude ? pluginutils.makeIdFiltersToMatchWithQuery(ensureArray(exclude)) : [], | ||
| /\/node_modules\// | ||
| ] | ||
| } | ||
| }, | ||
| async handler(code, id, options) { | ||
| if (id.includes("/node_modules/")) return; | ||
| const [filepath] = id.split("?"); | ||
| if (!filter(filepath)) return; | ||
| const ssr = options?.ssr === true; | ||
| const babelOptions = (() => { | ||
| if (staticBabelOptions) return staticBabelOptions; | ||
| const newBabelOptions = createBabelOptions( | ||
| typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel | ||
| ); | ||
| runPluginOverrides?.(newBabelOptions, { id, ssr }); | ||
| return newBabelOptions; | ||
| })(); | ||
| const plugins = [...babelOptions.plugins]; | ||
| const isJSX = filepath.endsWith("x"); | ||
| const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime))); | ||
| if (useFastRefresh) { | ||
| plugins.push([ | ||
| await loadPlugin("react-refresh/babel"), | ||
| { skipEnvCheck: true } | ||
| ]); | ||
| } | ||
| if (opts.jsxRuntime === "classic" && isJSX) { | ||
| if (!isProduction) { | ||
| plugins.push( | ||
| await loadPlugin("@babel/plugin-transform-react-jsx-self"), | ||
| await loadPlugin("@babel/plugin-transform-react-jsx-source") | ||
| ); | ||
| } | ||
| } | ||
| if (canSkipBabel(plugins, babelOptions)) { | ||
| return; | ||
| } | ||
| const parserPlugins = [...babelOptions.parserOpts.plugins]; | ||
| if (!filepath.endsWith(".ts")) { | ||
| parserPlugins.push("jsx"); | ||
| } | ||
| if (tsRE.test(filepath)) { | ||
| parserPlugins.push("typescript"); | ||
| } | ||
| const babel2 = await loadBabel(); | ||
| const result = await babel2.transformAsync(code, { | ||
| ...babelOptions, | ||
| root: projectRoot, | ||
| filename: id, | ||
| sourceFileName: filepath, | ||
| // Required for esbuild.jsxDev to provide correct line numbers | ||
| // This creates issues the react compiler because the re-order is too important | ||
| // People should use @babel/plugin-transform-react-jsx-development to get back good line numbers | ||
| retainLines: getReactCompilerPlugin(plugins) != null ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic", | ||
| parserOpts: { | ||
| ...babelOptions.parserOpts, | ||
| sourceType: "module", | ||
| allowAwaitOutsideFunction: true, | ||
| plugins: parserPlugins | ||
| }, | ||
| generatorOpts: { | ||
| ...babelOptions.generatorOpts, | ||
| // import attributes parsing available without plugin since 7.26 | ||
| importAttributesKeyword: "with", | ||
| decoratorsBeforeExport: true | ||
| }, | ||
| plugins, | ||
| sourceMaps: true | ||
| }); | ||
| if (result) { | ||
| if (!useFastRefresh) { | ||
| return { code: result.code, map: result.map }; | ||
| } | ||
| return addRefreshWrapper( | ||
| result.code, | ||
| result.map, | ||
| "@vitejs/plugin-react", | ||
| id, | ||
| opts.reactRefreshHost | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const dependencies = [ | ||
| "react", | ||
| "react-dom", | ||
| jsxImportDevRuntime, | ||
| jsxImportRuntime | ||
| ]; | ||
| const staticBabelPlugins = typeof opts.babel === "object" ? opts.babel?.plugins ?? [] : []; | ||
| const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins); | ||
| if (reactCompilerPlugin != null) { | ||
| const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin); | ||
| dependencies.push(reactCompilerRuntimeModule); | ||
| } | ||
| const viteReactRefresh = { | ||
| name: "vite:react-refresh", | ||
| enforce: "pre", | ||
| config: (userConfig) => ({ | ||
| build: silenceUseClientWarning(userConfig), | ||
| optimizeDeps: { | ||
| include: dependencies | ||
| }, | ||
| resolve: { | ||
| dedupe: ["react", "react-dom"] | ||
| } | ||
| }), | ||
| resolveId: { | ||
| filter: { id: pluginutils.exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) { | ||
| return id; | ||
| } | ||
| } | ||
| }, | ||
| load: { | ||
| filter: { id: pluginutils.exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) { | ||
| return node_fs.readFileSync(refreshRuntimePath, "utf-8").replace( | ||
| /__README_URL__/g, | ||
| "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react" | ||
| ); | ||
| } | ||
| } | ||
| }, | ||
| transformIndexHtml(_, config) { | ||
| if (!skipFastRefresh) | ||
| return [ | ||
| { | ||
| tag: "script", | ||
| attrs: { type: "module" }, | ||
| children: getPreambleCode(config.server.config.base) | ||
| } | ||
| ]; | ||
| } | ||
| }; | ||
| return [viteBabel, viteReactRefresh]; | ||
| var _opts$babel; | ||
| const include = opts.include ?? defaultIncludeRE; | ||
| const exclude = opts.exclude; | ||
| const filter = (0, vite.createFilter)(include, exclude); | ||
| const jsxImportSource = opts.jsxImportSource ?? "react"; | ||
| const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`; | ||
| const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`; | ||
| let runningInVite = false; | ||
| let isProduction = true; | ||
| let projectRoot = process.cwd(); | ||
| let skipFastRefresh = true; | ||
| let runPluginOverrides; | ||
| let staticBabelOptions; | ||
| const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/; | ||
| const viteBabel = { | ||
| name: "vite:react-babel", | ||
| enforce: "pre", | ||
| config() { | ||
| if (opts.jsxRuntime === "classic") if ("rolldownVersion" in vite) return { oxc: { jsx: { | ||
| runtime: "classic", | ||
| development: false | ||
| } } }; | ||
| else return { esbuild: { jsx: "transform" } }; | ||
| else return { | ||
| esbuild: { | ||
| jsx: "automatic", | ||
| jsxImportSource: opts.jsxImportSource | ||
| }, | ||
| optimizeDeps: "rolldownVersion" in vite ? { rollupOptions: { jsx: { mode: "automatic" } } } : { esbuildOptions: { jsx: "automatic" } } | ||
| }; | ||
| }, | ||
| configResolved(config) { | ||
| runningInVite = true; | ||
| projectRoot = config.root; | ||
| isProduction = config.isProduction; | ||
| skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false; | ||
| if ("jsxPure" in opts) config.logger.warnOnce("[@vitejs/plugin-react] jsxPure was removed. You can configure esbuild.jsxSideEffects directly."); | ||
| const hooks = config.plugins.map((plugin) => { | ||
| var _plugin$api; | ||
| return (_plugin$api = plugin.api) === null || _plugin$api === void 0 ? void 0 : _plugin$api.reactBabel; | ||
| }).filter(defined); | ||
| if ("rolldownVersion" in vite && !opts.babel && !hooks.length && !opts.disableOxcRecommendation) config.logger.warn("[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown"); | ||
| if (hooks.length > 0) runPluginOverrides = (babelOptions, context) => { | ||
| hooks.forEach((hook) => hook(babelOptions, context, config)); | ||
| }; | ||
| else if (typeof opts.babel !== "function") { | ||
| staticBabelOptions = createBabelOptions(opts.babel); | ||
| if (canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && skipFastRefresh && (opts.jsxRuntime === "classic" ? isProduction : true)) delete viteBabel.transform; | ||
| } | ||
| }, | ||
| options(options) { | ||
| if (!runningInVite) { | ||
| options.jsx = { | ||
| mode: opts.jsxRuntime, | ||
| importSource: opts.jsxImportSource | ||
| }; | ||
| return options; | ||
| } | ||
| }, | ||
| transform: { | ||
| filter: { id: { | ||
| include: (0, __rolldown_pluginutils.makeIdFiltersToMatchWithQuery)(include), | ||
| exclude: [...exclude ? (0, __rolldown_pluginutils.makeIdFiltersToMatchWithQuery)(ensureArray(exclude)) : [], /\/node_modules\//] | ||
| } }, | ||
| async handler(code, id, options) { | ||
| if (id.includes("/node_modules/")) return; | ||
| const [filepath] = id.split("?"); | ||
| if (!filter(filepath)) return; | ||
| const ssr = (options === null || options === void 0 ? void 0 : options.ssr) === true; | ||
| const babelOptions = (() => { | ||
| if (staticBabelOptions) return staticBabelOptions; | ||
| const newBabelOptions = createBabelOptions(typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel); | ||
| runPluginOverrides === null || runPluginOverrides === void 0 || runPluginOverrides(newBabelOptions, { | ||
| id, | ||
| ssr | ||
| }); | ||
| return newBabelOptions; | ||
| })(); | ||
| const plugins = [...babelOptions.plugins]; | ||
| const isJSX = filepath.endsWith("x"); | ||
| const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime))); | ||
| if (useFastRefresh) plugins.push([await loadPlugin("react-refresh/babel"), { skipEnvCheck: true }]); | ||
| if (opts.jsxRuntime === "classic" && isJSX) { | ||
| if (!isProduction) plugins.push(await loadPlugin("@babel/plugin-transform-react-jsx-self"), await loadPlugin("@babel/plugin-transform-react-jsx-source")); | ||
| } | ||
| if (canSkipBabel(plugins, babelOptions)) return; | ||
| const parserPlugins = [...babelOptions.parserOpts.plugins]; | ||
| if (!filepath.endsWith(".ts")) parserPlugins.push("jsx"); | ||
| if (tsRE.test(filepath)) parserPlugins.push("typescript"); | ||
| const babel$1 = await loadBabel(); | ||
| const result = await babel$1.transformAsync(code, { | ||
| ...babelOptions, | ||
| root: projectRoot, | ||
| filename: id, | ||
| sourceFileName: filepath, | ||
| retainLines: getReactCompilerPlugin(plugins) != null ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic", | ||
| parserOpts: { | ||
| ...babelOptions.parserOpts, | ||
| sourceType: "module", | ||
| allowAwaitOutsideFunction: true, | ||
| plugins: parserPlugins | ||
| }, | ||
| generatorOpts: { | ||
| ...babelOptions.generatorOpts, | ||
| importAttributesKeyword: "with", | ||
| decoratorsBeforeExport: true | ||
| }, | ||
| plugins, | ||
| sourceMaps: true | ||
| }); | ||
| if (result) { | ||
| if (!useFastRefresh) return { | ||
| code: result.code, | ||
| map: result.map | ||
| }; | ||
| return addRefreshWrapper(result.code, result.map, "@vitejs/plugin-react", id, opts.reactRefreshHost); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const dependencies = [ | ||
| "react", | ||
| "react-dom", | ||
| jsxImportDevRuntime, | ||
| jsxImportRuntime | ||
| ]; | ||
| const staticBabelPlugins = typeof opts.babel === "object" ? ((_opts$babel = opts.babel) === null || _opts$babel === void 0 ? void 0 : _opts$babel.plugins) ?? [] : []; | ||
| const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins); | ||
| if (reactCompilerPlugin != null) { | ||
| const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin); | ||
| dependencies.push(reactCompilerRuntimeModule); | ||
| } | ||
| const viteReactRefresh = { | ||
| name: "vite:react-refresh", | ||
| enforce: "pre", | ||
| config: (userConfig) => ({ | ||
| build: silenceUseClientWarning(userConfig), | ||
| optimizeDeps: { include: dependencies }, | ||
| resolve: { dedupe: ["react", "react-dom"] } | ||
| }), | ||
| resolveId: { | ||
| filter: { id: (0, __rolldown_pluginutils.exactRegex)(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) return id; | ||
| } | ||
| }, | ||
| load: { | ||
| filter: { id: (0, __rolldown_pluginutils.exactRegex)(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) return (0, node_fs.readFileSync)(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react"); | ||
| } | ||
| }, | ||
| transformIndexHtml(_, config) { | ||
| if (!skipFastRefresh) return [{ | ||
| tag: "script", | ||
| attrs: { type: "module" }, | ||
| children: getPreambleCode(config.server.config.base) | ||
| }]; | ||
| } | ||
| }; | ||
| return [viteBabel, viteReactRefresh]; | ||
| } | ||
| viteReact.preambleCode = preambleCode; | ||
| function canSkipBabel(plugins, babelOptions) { | ||
| return !(plugins.length || babelOptions.presets.length || babelOptions.configFile || babelOptions.babelrc); | ||
| return !(plugins.length || babelOptions.presets.length || babelOptions.configFile || babelOptions.babelrc); | ||
| } | ||
| const loadedPlugin = /* @__PURE__ */ new Map(); | ||
| function loadPlugin(path) { | ||
| const cached = loadedPlugin.get(path); | ||
| if (cached) return cached; | ||
| const promise = import(path).then((module) => { | ||
| const value = module.default || module; | ||
| loadedPlugin.set(path, value); | ||
| return value; | ||
| }); | ||
| loadedPlugin.set(path, promise); | ||
| return promise; | ||
| const cached = loadedPlugin.get(path); | ||
| if (cached) return cached; | ||
| const promise = import(path).then((module$1) => { | ||
| const value = module$1.default || module$1; | ||
| loadedPlugin.set(path, value); | ||
| return value; | ||
| }); | ||
| loadedPlugin.set(path, promise); | ||
| return promise; | ||
| } | ||
| function createBabelOptions(rawOptions) { | ||
| const babelOptions = { | ||
| babelrc: false, | ||
| configFile: false, | ||
| ...rawOptions | ||
| }; | ||
| babelOptions.plugins ||= []; | ||
| babelOptions.presets ||= []; | ||
| babelOptions.overrides ||= []; | ||
| babelOptions.parserOpts ||= {}; | ||
| babelOptions.parserOpts.plugins ||= []; | ||
| return babelOptions; | ||
| var _babelOptions$parserO; | ||
| const babelOptions = { | ||
| babelrc: false, | ||
| configFile: false, | ||
| ...rawOptions | ||
| }; | ||
| babelOptions.plugins || (babelOptions.plugins = []); | ||
| babelOptions.presets || (babelOptions.presets = []); | ||
| babelOptions.overrides || (babelOptions.overrides = []); | ||
| babelOptions.parserOpts || (babelOptions.parserOpts = {}); | ||
| (_babelOptions$parserO = babelOptions.parserOpts).plugins || (_babelOptions$parserO.plugins = []); | ||
| return babelOptions; | ||
| } | ||
| function defined(value) { | ||
| return value !== void 0; | ||
| return value !== void 0; | ||
| } | ||
| function getReactCompilerPlugin(plugins) { | ||
| return plugins.find( | ||
| (p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler" | ||
| ); | ||
| return plugins.find((p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler"); | ||
| } | ||
| function getReactCompilerRuntimeModule(plugin) { | ||
| let moduleName = "react/compiler-runtime"; | ||
| if (Array.isArray(plugin)) { | ||
| if (plugin[1]?.target === "17" || plugin[1]?.target === "18") { | ||
| moduleName = "react-compiler-runtime"; | ||
| } else if (typeof plugin[1]?.runtimeModule === "string") { | ||
| moduleName = plugin[1]?.runtimeModule; | ||
| } | ||
| } | ||
| return moduleName; | ||
| let moduleName = "react/compiler-runtime"; | ||
| if (Array.isArray(plugin)) { | ||
| var _plugin$, _plugin$2, _plugin$3; | ||
| if (((_plugin$ = plugin[1]) === null || _plugin$ === void 0 ? void 0 : _plugin$.target) === "17" || ((_plugin$2 = plugin[1]) === null || _plugin$2 === void 0 ? void 0 : _plugin$2.target) === "18") moduleName = "react-compiler-runtime"; | ||
| else if (typeof ((_plugin$3 = plugin[1]) === null || _plugin$3 === void 0 ? void 0 : _plugin$3.runtimeModule) === "string") { | ||
| var _plugin$4; | ||
| moduleName = (_plugin$4 = plugin[1]) === null || _plugin$4 === void 0 ? void 0 : _plugin$4.runtimeModule; | ||
| } | ||
| } | ||
| return moduleName; | ||
| } | ||
| function ensureArray(value) { | ||
| return Array.isArray(value) ? value : [value]; | ||
| return Array.isArray(value) ? value : [value]; | ||
| } | ||
| //#endregion | ||
| module.exports = viteReact; | ||
| module.exports.default = viteReact; | ||
| module.exports.default = module.exports |
+50
-50
@@ -1,36 +0,37 @@ | ||
| import { TransformOptions, ParserOptions } from '@babel/core'; | ||
| import { PluginOption, ResolvedConfig } from 'vite'; | ||
| import { ParserOptions, TransformOptions } from "@babel/core"; | ||
| import { Plugin, ResolvedConfig } from "vite"; | ||
| //#region src/index.d.ts | ||
| interface Options { | ||
| include?: string | RegExp | Array<string | RegExp>; | ||
| exclude?: string | RegExp | Array<string | RegExp>; | ||
| /** | ||
| * Control where the JSX factory is imported from. | ||
| * https://esbuild.github.io/api/#jsx-import-source | ||
| * @default 'react' | ||
| */ | ||
| jsxImportSource?: string; | ||
| /** | ||
| * Note: Skipping React import with classic runtime is not supported from v4 | ||
| * @default "automatic" | ||
| */ | ||
| jsxRuntime?: 'classic' | 'automatic'; | ||
| /** | ||
| * Babel configuration applied in both dev and prod. | ||
| */ | ||
| babel?: BabelOptions | ((id: string, options: { | ||
| ssr?: boolean; | ||
| }) => BabelOptions); | ||
| /** | ||
| * React Fast Refresh runtime URL prefix. | ||
| * Useful in a module federation context to enable HMR by specifying | ||
| * the host application URL in the Vite config of a remote application. | ||
| * @example | ||
| * reactRefreshHost: 'http://localhost:3000' | ||
| */ | ||
| reactRefreshHost?: string; | ||
| /** | ||
| * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` | ||
| */ | ||
| disableOxcRecommendation?: boolean; | ||
| include?: string | RegExp | Array<string | RegExp>; | ||
| exclude?: string | RegExp | Array<string | RegExp>; | ||
| /** | ||
| * Control where the JSX factory is imported from. | ||
| * https://esbuild.github.io/api/#jsx-import-source | ||
| * @default 'react' | ||
| */ | ||
| jsxImportSource?: string; | ||
| /** | ||
| * Note: Skipping React import with classic runtime is not supported from v4 | ||
| * @default "automatic" | ||
| */ | ||
| jsxRuntime?: 'classic' | 'automatic'; | ||
| /** | ||
| * Babel configuration applied in both dev and prod. | ||
| */ | ||
| babel?: BabelOptions | ((id: string, options: { | ||
| ssr?: boolean; | ||
| }) => BabelOptions); | ||
| /** | ||
| * React Fast Refresh runtime URL prefix. | ||
| * Useful in a module federation context to enable HMR by specifying | ||
| * the host application URL in the Vite config of a remote application. | ||
| * @example | ||
| * reactRefreshHost: 'http://localhost:3000' | ||
| */ | ||
| reactRefreshHost?: string; | ||
| /** | ||
| * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` | ||
| */ | ||
| disableOxcRecommendation?: boolean; | ||
| } | ||
@@ -43,26 +44,25 @@ type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>; | ||
| interface ReactBabelOptions extends BabelOptions { | ||
| plugins: Extract<BabelOptions['plugins'], any[]>; | ||
| presets: Extract<BabelOptions['presets'], any[]>; | ||
| overrides: Extract<BabelOptions['overrides'], any[]>; | ||
| parserOpts: ParserOptions & { | ||
| plugins: Extract<ParserOptions['plugins'], any[]>; | ||
| }; | ||
| plugins: Extract<BabelOptions['plugins'], any[]>; | ||
| presets: Extract<BabelOptions['presets'], any[]>; | ||
| overrides: Extract<BabelOptions['overrides'], any[]>; | ||
| parserOpts: ParserOptions & { | ||
| plugins: Extract<ParserOptions['plugins'], any[]>; | ||
| }; | ||
| } | ||
| type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void; | ||
| type ReactBabelHookContext = { | ||
| ssr: boolean; | ||
| id: string; | ||
| ssr: boolean; | ||
| id: string; | ||
| }; | ||
| type ViteReactPluginApi = { | ||
| /** | ||
| * Manipulate the Babel options of `@vitejs/plugin-react` | ||
| */ | ||
| reactBabel?: ReactBabelHook; | ||
| /** | ||
| * Manipulate the Babel options of `@vitejs/plugin-react` | ||
| */ | ||
| reactBabel?: ReactBabelHook; | ||
| }; | ||
| declare function viteReact(opts?: Options): PluginOption[]; | ||
| declare function viteReact(opts?: Options): Plugin[]; | ||
| declare namespace viteReact { | ||
| var preambleCode: string; | ||
| var preambleCode: string; | ||
| } | ||
| export = viteReact; | ||
| export type { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi }; | ||
| //#endregion | ||
| export { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi, viteReact as default }; |
+50
-50
@@ -1,36 +0,37 @@ | ||
| import { TransformOptions, ParserOptions } from '@babel/core'; | ||
| import { PluginOption, ResolvedConfig } from 'vite'; | ||
| import { Plugin, ResolvedConfig } from "vite"; | ||
| import { ParserOptions, TransformOptions } from "@babel/core"; | ||
| //#region src/index.d.ts | ||
| interface Options { | ||
| include?: string | RegExp | Array<string | RegExp>; | ||
| exclude?: string | RegExp | Array<string | RegExp>; | ||
| /** | ||
| * Control where the JSX factory is imported from. | ||
| * https://esbuild.github.io/api/#jsx-import-source | ||
| * @default 'react' | ||
| */ | ||
| jsxImportSource?: string; | ||
| /** | ||
| * Note: Skipping React import with classic runtime is not supported from v4 | ||
| * @default "automatic" | ||
| */ | ||
| jsxRuntime?: 'classic' | 'automatic'; | ||
| /** | ||
| * Babel configuration applied in both dev and prod. | ||
| */ | ||
| babel?: BabelOptions | ((id: string, options: { | ||
| ssr?: boolean; | ||
| }) => BabelOptions); | ||
| /** | ||
| * React Fast Refresh runtime URL prefix. | ||
| * Useful in a module federation context to enable HMR by specifying | ||
| * the host application URL in the Vite config of a remote application. | ||
| * @example | ||
| * reactRefreshHost: 'http://localhost:3000' | ||
| */ | ||
| reactRefreshHost?: string; | ||
| /** | ||
| * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` | ||
| */ | ||
| disableOxcRecommendation?: boolean; | ||
| include?: string | RegExp | Array<string | RegExp>; | ||
| exclude?: string | RegExp | Array<string | RegExp>; | ||
| /** | ||
| * Control where the JSX factory is imported from. | ||
| * https://esbuild.github.io/api/#jsx-import-source | ||
| * @default 'react' | ||
| */ | ||
| jsxImportSource?: string; | ||
| /** | ||
| * Note: Skipping React import with classic runtime is not supported from v4 | ||
| * @default "automatic" | ||
| */ | ||
| jsxRuntime?: 'classic' | 'automatic'; | ||
| /** | ||
| * Babel configuration applied in both dev and prod. | ||
| */ | ||
| babel?: BabelOptions | ((id: string, options: { | ||
| ssr?: boolean; | ||
| }) => BabelOptions); | ||
| /** | ||
| * React Fast Refresh runtime URL prefix. | ||
| * Useful in a module federation context to enable HMR by specifying | ||
| * the host application URL in the Vite config of a remote application. | ||
| * @example | ||
| * reactRefreshHost: 'http://localhost:3000' | ||
| */ | ||
| reactRefreshHost?: string; | ||
| /** | ||
| * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` | ||
| */ | ||
| disableOxcRecommendation?: boolean; | ||
| } | ||
@@ -43,26 +44,25 @@ type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>; | ||
| interface ReactBabelOptions extends BabelOptions { | ||
| plugins: Extract<BabelOptions['plugins'], any[]>; | ||
| presets: Extract<BabelOptions['presets'], any[]>; | ||
| overrides: Extract<BabelOptions['overrides'], any[]>; | ||
| parserOpts: ParserOptions & { | ||
| plugins: Extract<ParserOptions['plugins'], any[]>; | ||
| }; | ||
| plugins: Extract<BabelOptions['plugins'], any[]>; | ||
| presets: Extract<BabelOptions['presets'], any[]>; | ||
| overrides: Extract<BabelOptions['overrides'], any[]>; | ||
| parserOpts: ParserOptions & { | ||
| plugins: Extract<ParserOptions['plugins'], any[]>; | ||
| }; | ||
| } | ||
| type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void; | ||
| type ReactBabelHookContext = { | ||
| ssr: boolean; | ||
| id: string; | ||
| ssr: boolean; | ||
| id: string; | ||
| }; | ||
| type ViteReactPluginApi = { | ||
| /** | ||
| * Manipulate the Babel options of `@vitejs/plugin-react` | ||
| */ | ||
| reactBabel?: ReactBabelHook; | ||
| /** | ||
| * Manipulate the Babel options of `@vitejs/plugin-react` | ||
| */ | ||
| reactBabel?: ReactBabelHook; | ||
| }; | ||
| declare function viteReact(opts?: Options): PluginOption[]; | ||
| declare function viteReact(opts?: Options): Plugin[]; | ||
| declare namespace viteReact { | ||
| var preambleCode: string; | ||
| var preambleCode: string; | ||
| } | ||
| export = viteReact; | ||
| export type { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi }; | ||
| //#endregion | ||
| export { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi, viteReact as default }; |
@@ -548,2 +548,17 @@ /* global window */ | ||
| function isCompoundComponent(type) { | ||
| if (!isPlainObject(type)) return false | ||
| for (const key in type) { | ||
| if (!isLikelyComponentType(type[key])) return false | ||
| } | ||
| return true | ||
| } | ||
| function isPlainObject(obj) { | ||
| return ( | ||
| Object.prototype.toString.call(obj) === '[object Object]' && | ||
| (obj.constructor === Object || obj.constructor === undefined) | ||
| ) | ||
| } | ||
| /** | ||
@@ -569,2 +584,9 @@ * Plugin utils | ||
| register(exportValue, filename + ' export ' + key) | ||
| } else if (isCompoundComponent(exportValue)) { | ||
| for (const subKey in exportValue) { | ||
| register( | ||
| exportValue[subKey], | ||
| filename + ' export ' + key + '-' + subKey, | ||
| ) | ||
| } | ||
| } | ||
@@ -623,2 +645,3 @@ } | ||
| if (isLikelyComponentType(value)) return true | ||
| if (isCompoundComponent(value)) return true | ||
| return prevExports[key] === nextExports[key] | ||
@@ -625,0 +648,0 @@ }, |
+11
-12
| { | ||
| "name": "@vitejs/plugin-react", | ||
| "version": "4.6.0", | ||
| "version": "4.7.0", | ||
| "license": "MIT", | ||
@@ -24,7 +24,7 @@ "author": "Evan You", | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.mjs", | ||
| "types": "./dist/index.d.mts", | ||
| "module": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": { | ||
| "import": "./dist/index.mjs", | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs" | ||
@@ -34,5 +34,4 @@ } | ||
| "scripts": { | ||
| "dev": "unbuild --stub", | ||
| "build": "unbuild && pnpm run patch-cjs && tsx scripts/copyRefreshRuntime.ts", | ||
| "patch-cjs": "tsx ../../scripts/patchCJS.ts", | ||
| "dev": "tsdown --watch", | ||
| "build": "tsdown", | ||
| "prepublishOnly": "npm run build", | ||
@@ -54,6 +53,6 @@ "test-unit": "vitest run" | ||
| "dependencies": { | ||
| "@babel/core": "^7.27.4", | ||
| "@babel/core": "^7.28.0", | ||
| "@babel/plugin-transform-react-jsx-self": "^7.27.1", | ||
| "@babel/plugin-transform-react-jsx-source": "^7.27.1", | ||
| "@rolldown/pluginutils": "1.0.0-beta.19", | ||
| "@rolldown/pluginutils": "1.0.0-beta.27", | ||
| "@types/babel__core": "^7.20.5", | ||
@@ -63,3 +62,3 @@ "react-refresh": "^0.17.0" | ||
| "peerDependencies": { | ||
| "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" | ||
| "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" | ||
| }, | ||
@@ -71,6 +70,6 @@ "devDependencies": { | ||
| "react-dom": "^19.1.0", | ||
| "rolldown": "1.0.0-beta.19", | ||
| "unbuild": "^3.5.0", | ||
| "rolldown": "1.0.0-beta.27", | ||
| "tsdown": "^0.12.9", | ||
| "vitest": "^3.2.4" | ||
| } | ||
| } |
| import { TransformOptions, ParserOptions } from '@babel/core'; | ||
| import { PluginOption, ResolvedConfig } from 'vite'; | ||
| interface Options { | ||
| include?: string | RegExp | Array<string | RegExp>; | ||
| exclude?: string | RegExp | Array<string | RegExp>; | ||
| /** | ||
| * Control where the JSX factory is imported from. | ||
| * https://esbuild.github.io/api/#jsx-import-source | ||
| * @default 'react' | ||
| */ | ||
| jsxImportSource?: string; | ||
| /** | ||
| * Note: Skipping React import with classic runtime is not supported from v4 | ||
| * @default "automatic" | ||
| */ | ||
| jsxRuntime?: 'classic' | 'automatic'; | ||
| /** | ||
| * Babel configuration applied in both dev and prod. | ||
| */ | ||
| babel?: BabelOptions | ((id: string, options: { | ||
| ssr?: boolean; | ||
| }) => BabelOptions); | ||
| /** | ||
| * React Fast Refresh runtime URL prefix. | ||
| * Useful in a module federation context to enable HMR by specifying | ||
| * the host application URL in the Vite config of a remote application. | ||
| * @example | ||
| * reactRefreshHost: 'http://localhost:3000' | ||
| */ | ||
| reactRefreshHost?: string; | ||
| /** | ||
| * If set, disables the recommendation to use `@vitejs/plugin-react-oxc` | ||
| */ | ||
| disableOxcRecommendation?: boolean; | ||
| } | ||
| type BabelOptions = Omit<TransformOptions, 'ast' | 'filename' | 'root' | 'sourceFileName' | 'sourceMaps' | 'inputSourceMap'>; | ||
| /** | ||
| * The object type used by the `options` passed to plugins with | ||
| * an `api.reactBabel` method. | ||
| */ | ||
| interface ReactBabelOptions extends BabelOptions { | ||
| plugins: Extract<BabelOptions['plugins'], any[]>; | ||
| presets: Extract<BabelOptions['presets'], any[]>; | ||
| overrides: Extract<BabelOptions['overrides'], any[]>; | ||
| parserOpts: ParserOptions & { | ||
| plugins: Extract<ParserOptions['plugins'], any[]>; | ||
| }; | ||
| } | ||
| type ReactBabelHook = (babelConfig: ReactBabelOptions, context: ReactBabelHookContext, config: ResolvedConfig) => void; | ||
| type ReactBabelHookContext = { | ||
| ssr: boolean; | ||
| id: string; | ||
| }; | ||
| type ViteReactPluginApi = { | ||
| /** | ||
| * Manipulate the Babel options of `@vitejs/plugin-react` | ||
| */ | ||
| reactBabel?: ReactBabelHook; | ||
| }; | ||
| declare function viteReact(opts?: Options): PluginOption[]; | ||
| declare namespace viteReact { | ||
| var preambleCode: string; | ||
| } | ||
| export { viteReact as default }; | ||
| export type { BabelOptions, Options, ReactBabelOptions, ViteReactPluginApi }; |
-403
| import { dirname, join } from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import { readFileSync } from 'node:fs'; | ||
| import * as vite from 'vite'; | ||
| import { createFilter } from 'vite'; | ||
| import { makeIdFiltersToMatchWithQuery, exactRegex } from '@rolldown/pluginutils'; | ||
| const runtimePublicPath = "/@react-refresh"; | ||
| const reactCompRE = /extends\s+(?:React\.)?(?:Pure)?Component/; | ||
| const refreshContentRE = /\$RefreshReg\$\(/; | ||
| const preambleCode = `import { injectIntoGlobalHook } from "__BASE__${runtimePublicPath.slice( | ||
| 1 | ||
| )}"; | ||
| injectIntoGlobalHook(window); | ||
| window.$RefreshReg$ = () => {}; | ||
| window.$RefreshSig$ = () => (type) => type;`; | ||
| const getPreambleCode = (base) => preambleCode.replace("__BASE__", base); | ||
| const avoidSourceMapOption = Symbol(); | ||
| function addRefreshWrapper(code, map, pluginName, id, reactRefreshHost = "") { | ||
| const hasRefresh = refreshContentRE.test(code); | ||
| const onlyReactComp = !hasRefresh && reactCompRE.test(code); | ||
| const normalizedMap = map === avoidSourceMapOption ? null : map; | ||
| if (!hasRefresh && !onlyReactComp) return { code, map: normalizedMap }; | ||
| const avoidSourceMap = map === avoidSourceMapOption; | ||
| const newMap = typeof normalizedMap === "string" ? JSON.parse(normalizedMap) : normalizedMap; | ||
| let newCode = code; | ||
| if (hasRefresh) { | ||
| const refreshHead = removeLineBreaksIfNeeded( | ||
| `let prevRefreshReg; | ||
| let prevRefreshSig; | ||
| if (import.meta.hot && !inWebWorker) { | ||
| if (!window.$RefreshReg$) { | ||
| throw new Error( | ||
| "${pluginName} can't detect preamble. Something is wrong." | ||
| ); | ||
| } | ||
| prevRefreshReg = window.$RefreshReg$; | ||
| prevRefreshSig = window.$RefreshSig$; | ||
| window.$RefreshReg$ = RefreshRuntime.getRefreshReg(${JSON.stringify(id)}); | ||
| window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform; | ||
| } | ||
| `, | ||
| avoidSourceMap | ||
| ); | ||
| newCode = `${refreshHead}${newCode} | ||
| if (import.meta.hot && !inWebWorker) { | ||
| window.$RefreshReg$ = prevRefreshReg; | ||
| window.$RefreshSig$ = prevRefreshSig; | ||
| } | ||
| `; | ||
| if (newMap) { | ||
| newMap.mappings = ";".repeat(16) + newMap.mappings; | ||
| } | ||
| } | ||
| const sharedHead = removeLineBreaksIfNeeded( | ||
| `import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}"; | ||
| const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; | ||
| `, | ||
| avoidSourceMap | ||
| ); | ||
| newCode = `${sharedHead}${newCode} | ||
| if (import.meta.hot && !inWebWorker) { | ||
| RefreshRuntime.__hmr_import(import.meta.url).then((currentExports) => { | ||
| RefreshRuntime.registerExportsForReactRefresh(${JSON.stringify( | ||
| id | ||
| )}, currentExports); | ||
| import.meta.hot.accept((nextExports) => { | ||
| if (!nextExports) return; | ||
| const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(${JSON.stringify( | ||
| id | ||
| )}, currentExports, nextExports); | ||
| if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage); | ||
| }); | ||
| }); | ||
| } | ||
| `; | ||
| if (newMap) { | ||
| newMap.mappings = ";;;" + newMap.mappings; | ||
| } | ||
| return { code: newCode, map: newMap }; | ||
| } | ||
| function removeLineBreaksIfNeeded(code, enabled) { | ||
| return enabled ? code.replace(/\n/g, "") : code; | ||
| } | ||
| const silenceUseClientWarning = (userConfig) => ({ | ||
| rollupOptions: { | ||
| onwarn(warning, defaultHandler) { | ||
| if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message.includes("use client") || warning.message.includes("use server"))) { | ||
| return; | ||
| } | ||
| if (warning.code === "SOURCEMAP_ERROR" && warning.message.includes("resolve original location") && warning.pos === 0) { | ||
| return; | ||
| } | ||
| if (userConfig.build?.rollupOptions?.onwarn) { | ||
| userConfig.build.rollupOptions.onwarn(warning, defaultHandler); | ||
| } else { | ||
| defaultHandler(warning); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| const _dirname = dirname(fileURLToPath(import.meta.url)); | ||
| const refreshRuntimePath = join(_dirname, "refresh-runtime.js") ; | ||
| let babel; | ||
| async function loadBabel() { | ||
| if (!babel) { | ||
| babel = await import('@babel/core'); | ||
| } | ||
| return babel; | ||
| } | ||
| const defaultIncludeRE = /\.[tj]sx?$/; | ||
| const tsRE = /\.tsx?$/; | ||
| function viteReact(opts = {}) { | ||
| const include = opts.include ?? defaultIncludeRE; | ||
| const exclude = opts.exclude; | ||
| const filter = createFilter(include, exclude); | ||
| const jsxImportSource = opts.jsxImportSource ?? "react"; | ||
| const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`; | ||
| const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`; | ||
| let runningInVite = false; | ||
| let isProduction = true; | ||
| let projectRoot = process.cwd(); | ||
| let skipFastRefresh = true; | ||
| let runPluginOverrides; | ||
| let staticBabelOptions; | ||
| const importReactRE = /\bimport\s+(?:\*\s+as\s+)?React\b/; | ||
| const viteBabel = { | ||
| name: "vite:react-babel", | ||
| enforce: "pre", | ||
| config() { | ||
| if (opts.jsxRuntime === "classic") { | ||
| if ("rolldownVersion" in vite) { | ||
| return { | ||
| oxc: { | ||
| jsx: { | ||
| runtime: "classic", | ||
| // disable __self and __source injection even in dev | ||
| // as this plugin injects them by babel and oxc will throw | ||
| // if development is enabled and those properties are already present | ||
| development: false | ||
| } | ||
| } | ||
| }; | ||
| } else { | ||
| return { | ||
| esbuild: { | ||
| jsx: "transform" | ||
| } | ||
| }; | ||
| } | ||
| } else { | ||
| return { | ||
| esbuild: { | ||
| jsx: "automatic", | ||
| jsxImportSource: opts.jsxImportSource | ||
| }, | ||
| optimizeDeps: "rolldownVersion" in vite ? { rollupOptions: { jsx: { mode: "automatic" } } } : { esbuildOptions: { jsx: "automatic" } } | ||
| }; | ||
| } | ||
| }, | ||
| configResolved(config) { | ||
| runningInVite = true; | ||
| projectRoot = config.root; | ||
| isProduction = config.isProduction; | ||
| skipFastRefresh = isProduction || config.command === "build" || config.server.hmr === false; | ||
| if ("jsxPure" in opts) { | ||
| config.logger.warnOnce( | ||
| "[@vitejs/plugin-react] jsxPure was removed. You can configure esbuild.jsxSideEffects directly." | ||
| ); | ||
| } | ||
| const hooks = config.plugins.map((plugin) => plugin.api?.reactBabel).filter(defined); | ||
| if ("rolldownVersion" in vite && !opts.babel && !hooks.length && !opts.disableOxcRecommendation) { | ||
| config.logger.warn( | ||
| "[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown" | ||
| ); | ||
| } | ||
| if (hooks.length > 0) { | ||
| runPluginOverrides = (babelOptions, context) => { | ||
| hooks.forEach((hook) => hook(babelOptions, context, config)); | ||
| }; | ||
| } else if (typeof opts.babel !== "function") { | ||
| staticBabelOptions = createBabelOptions(opts.babel); | ||
| if (canSkipBabel(staticBabelOptions.plugins, staticBabelOptions) && skipFastRefresh && (opts.jsxRuntime === "classic" ? isProduction : true)) { | ||
| delete viteBabel.transform; | ||
| } | ||
| } | ||
| }, | ||
| options(options) { | ||
| if (!runningInVite) { | ||
| options.jsx = { | ||
| mode: opts.jsxRuntime, | ||
| importSource: opts.jsxImportSource | ||
| }; | ||
| return options; | ||
| } | ||
| }, | ||
| transform: { | ||
| filter: { | ||
| id: { | ||
| include: makeIdFiltersToMatchWithQuery(include), | ||
| exclude: [ | ||
| ...exclude ? makeIdFiltersToMatchWithQuery(ensureArray(exclude)) : [], | ||
| /\/node_modules\// | ||
| ] | ||
| } | ||
| }, | ||
| async handler(code, id, options) { | ||
| if (id.includes("/node_modules/")) return; | ||
| const [filepath] = id.split("?"); | ||
| if (!filter(filepath)) return; | ||
| const ssr = options?.ssr === true; | ||
| const babelOptions = (() => { | ||
| if (staticBabelOptions) return staticBabelOptions; | ||
| const newBabelOptions = createBabelOptions( | ||
| typeof opts.babel === "function" ? opts.babel(id, { ssr }) : opts.babel | ||
| ); | ||
| runPluginOverrides?.(newBabelOptions, { id, ssr }); | ||
| return newBabelOptions; | ||
| })(); | ||
| const plugins = [...babelOptions.plugins]; | ||
| const isJSX = filepath.endsWith("x"); | ||
| const useFastRefresh = !skipFastRefresh && !ssr && (isJSX || (opts.jsxRuntime === "classic" ? importReactRE.test(code) : code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime))); | ||
| if (useFastRefresh) { | ||
| plugins.push([ | ||
| await loadPlugin("react-refresh/babel"), | ||
| { skipEnvCheck: true } | ||
| ]); | ||
| } | ||
| if (opts.jsxRuntime === "classic" && isJSX) { | ||
| if (!isProduction) { | ||
| plugins.push( | ||
| await loadPlugin("@babel/plugin-transform-react-jsx-self"), | ||
| await loadPlugin("@babel/plugin-transform-react-jsx-source") | ||
| ); | ||
| } | ||
| } | ||
| if (canSkipBabel(plugins, babelOptions)) { | ||
| return; | ||
| } | ||
| const parserPlugins = [...babelOptions.parserOpts.plugins]; | ||
| if (!filepath.endsWith(".ts")) { | ||
| parserPlugins.push("jsx"); | ||
| } | ||
| if (tsRE.test(filepath)) { | ||
| parserPlugins.push("typescript"); | ||
| } | ||
| const babel2 = await loadBabel(); | ||
| const result = await babel2.transformAsync(code, { | ||
| ...babelOptions, | ||
| root: projectRoot, | ||
| filename: id, | ||
| sourceFileName: filepath, | ||
| // Required for esbuild.jsxDev to provide correct line numbers | ||
| // This creates issues the react compiler because the re-order is too important | ||
| // People should use @babel/plugin-transform-react-jsx-development to get back good line numbers | ||
| retainLines: getReactCompilerPlugin(plugins) != null ? false : !isProduction && isJSX && opts.jsxRuntime !== "classic", | ||
| parserOpts: { | ||
| ...babelOptions.parserOpts, | ||
| sourceType: "module", | ||
| allowAwaitOutsideFunction: true, | ||
| plugins: parserPlugins | ||
| }, | ||
| generatorOpts: { | ||
| ...babelOptions.generatorOpts, | ||
| // import attributes parsing available without plugin since 7.26 | ||
| importAttributesKeyword: "with", | ||
| decoratorsBeforeExport: true | ||
| }, | ||
| plugins, | ||
| sourceMaps: true | ||
| }); | ||
| if (result) { | ||
| if (!useFastRefresh) { | ||
| return { code: result.code, map: result.map }; | ||
| } | ||
| return addRefreshWrapper( | ||
| result.code, | ||
| result.map, | ||
| "@vitejs/plugin-react", | ||
| id, | ||
| opts.reactRefreshHost | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| const dependencies = [ | ||
| "react", | ||
| "react-dom", | ||
| jsxImportDevRuntime, | ||
| jsxImportRuntime | ||
| ]; | ||
| const staticBabelPlugins = typeof opts.babel === "object" ? opts.babel?.plugins ?? [] : []; | ||
| const reactCompilerPlugin = getReactCompilerPlugin(staticBabelPlugins); | ||
| if (reactCompilerPlugin != null) { | ||
| const reactCompilerRuntimeModule = getReactCompilerRuntimeModule(reactCompilerPlugin); | ||
| dependencies.push(reactCompilerRuntimeModule); | ||
| } | ||
| const viteReactRefresh = { | ||
| name: "vite:react-refresh", | ||
| enforce: "pre", | ||
| config: (userConfig) => ({ | ||
| build: silenceUseClientWarning(userConfig), | ||
| optimizeDeps: { | ||
| include: dependencies | ||
| }, | ||
| resolve: { | ||
| dedupe: ["react", "react-dom"] | ||
| } | ||
| }), | ||
| resolveId: { | ||
| filter: { id: exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) { | ||
| return id; | ||
| } | ||
| } | ||
| }, | ||
| load: { | ||
| filter: { id: exactRegex(runtimePublicPath) }, | ||
| handler(id) { | ||
| if (id === runtimePublicPath) { | ||
| return readFileSync(refreshRuntimePath, "utf-8").replace( | ||
| /__README_URL__/g, | ||
| "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react" | ||
| ); | ||
| } | ||
| } | ||
| }, | ||
| transformIndexHtml(_, config) { | ||
| if (!skipFastRefresh) | ||
| return [ | ||
| { | ||
| tag: "script", | ||
| attrs: { type: "module" }, | ||
| children: getPreambleCode(config.server.config.base) | ||
| } | ||
| ]; | ||
| } | ||
| }; | ||
| return [viteBabel, viteReactRefresh]; | ||
| } | ||
| viteReact.preambleCode = preambleCode; | ||
| function canSkipBabel(plugins, babelOptions) { | ||
| return !(plugins.length || babelOptions.presets.length || babelOptions.configFile || babelOptions.babelrc); | ||
| } | ||
| const loadedPlugin = /* @__PURE__ */ new Map(); | ||
| function loadPlugin(path) { | ||
| const cached = loadedPlugin.get(path); | ||
| if (cached) return cached; | ||
| const promise = import(path).then((module) => { | ||
| const value = module.default || module; | ||
| loadedPlugin.set(path, value); | ||
| return value; | ||
| }); | ||
| loadedPlugin.set(path, promise); | ||
| return promise; | ||
| } | ||
| function createBabelOptions(rawOptions) { | ||
| const babelOptions = { | ||
| babelrc: false, | ||
| configFile: false, | ||
| ...rawOptions | ||
| }; | ||
| babelOptions.plugins ||= []; | ||
| babelOptions.presets ||= []; | ||
| babelOptions.overrides ||= []; | ||
| babelOptions.parserOpts ||= {}; | ||
| babelOptions.parserOpts.plugins ||= []; | ||
| return babelOptions; | ||
| } | ||
| function defined(value) { | ||
| return value !== void 0; | ||
| } | ||
| function getReactCompilerPlugin(plugins) { | ||
| return plugins.find( | ||
| (p) => p === "babel-plugin-react-compiler" || Array.isArray(p) && p[0] === "babel-plugin-react-compiler" | ||
| ); | ||
| } | ||
| function getReactCompilerRuntimeModule(plugin) { | ||
| let moduleName = "react/compiler-runtime"; | ||
| if (Array.isArray(plugin)) { | ||
| if (plugin[1]?.target === "17" || plugin[1]?.target === "18") { | ||
| moduleName = "react-compiler-runtime"; | ||
| } else if (typeof plugin[1]?.runtimeModule === "string") { | ||
| moduleName = plugin[1]?.runtimeModule; | ||
| } | ||
| } | ||
| return moduleName; | ||
| } | ||
| function ensureArray(value) { | ||
| return Array.isArray(value) ? value : [value]; | ||
| } | ||
| export { viteReact as default }; |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
60271
-5.32%8
-11.11%1314
-9.63%+ Added
- Removed
Updated