UNPKG

@vitejs/plugin-react-oxc

Version:
164 lines (158 loc) 5.85 kB
import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { readFileSync } from "node:fs"; import { exactRegex } 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); function addRefreshWrapper(code, pluginName, id, reactRefreshHost = "") { const hasRefresh = refreshContentRE.test(code); const onlyReactComp = !hasRefresh && reactCompRE.test(code); if (!hasRefresh && !onlyReactComp) return void 0; let newCode = code; newCode += ` import * as RefreshRuntime from "${reactRefreshHost}${runtimePublicPath}"; const inWebWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; if (import.meta.hot && !inWebWorker) { if (!window.$RefreshReg$) { throw new Error( "${pluginName} can't detect preamble. Something is wrong." ); } 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 (hasRefresh) newCode += `function $RefreshReg$(type, id) { return RefreshRuntime.register(type, ${JSON.stringify(id)} + ' ' + id) } function $RefreshSig$() { return RefreshRuntime.createSignatureFunctionForTransform(); } `; return newCode; } //#endregion //#region ../common/warning.ts 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 src/index.ts const _dirname = dirname(fileURLToPath(import.meta.url)); const refreshRuntimePath = join(_dirname, "refresh-runtime.js"); const defaultIncludeRE = /\.[tj]sx?(?:$|\?)/; const defaultExcludeRE = /\/node_modules\//; function viteReact(opts = {}) { const include = opts.include ?? defaultIncludeRE; const exclude = opts.exclude ?? defaultExcludeRE; const jsxImportSource = opts.jsxImportSource ?? "react"; const jsxImportRuntime = `${jsxImportSource}/jsx-runtime`; const jsxImportDevRuntime = `${jsxImportSource}/jsx-dev-runtime`; const viteConfig = { name: "vite:react-oxc:config", config(userConfig, { command }) { return { build: silenceUseClientWarning(userConfig), oxc: { jsx: { runtime: "automatic", importSource: jsxImportSource, refresh: command === "serve", development: command === "serve" }, jsxRefreshInclude: include, jsxRefreshExclude: exclude }, optimizeDeps: { include: [ "react", "react-dom", jsxImportDevRuntime, jsxImportRuntime ], rollupOptions: { transform: { jsx: { runtime: "automatic" } } } } }; }, configResolved(config) { config.logger.warn("@vitejs/plugin-react-oxc is deprecated. Please use @vitejs/plugin-react instead. The changes of this plugin is now included in @vitejs/plugin-react."); }, options() { if (!this.meta.rolldownVersion) throw new Error("@vitejs/plugin-react-oxc requires rolldown-vite to be used. See https://vitejs.dev/guide/rolldown for more details about rolldown-vite."); } }; const viteConfigPost = { name: "vite:react-oxc:config-post", enforce: "post", config(userConfig) { if (userConfig.server?.hmr === false) return { oxc: { jsx: { refresh: false } } }; } }; const viteRefreshRuntime = { name: "vite:react-oxc:refresh-runtime", enforce: "pre", resolveId: { filter: { id: exactRegex(runtimePublicPath) }, handler(id) { return id; } }, load: { filter: { id: exactRegex(runtimePublicPath) }, handler(_id) { return readFileSync(refreshRuntimePath, "utf-8").replace(/__README_URL__/g, "https://github.com/vitejs/vite-plugin-react/tree/main/packages/plugin-react-oxc"); } } }; let skipFastRefresh = false; return [ viteConfig, viteConfigPost, viteRefreshRuntime, { name: "vite:react-oxc:refresh-wrapper", apply: "serve", configResolved(config) { skipFastRefresh = config.isProduction || config.server.hmr === false; }, transform: { filter: { id: { include, exclude } }, handler(code, id, options) { const ssr = options?.ssr === true; const [filepath] = id.split("?"); const isJSX = filepath.endsWith("x"); if (!(!skipFastRefresh && !ssr && (isJSX || code.includes(jsxImportDevRuntime) || code.includes(jsxImportRuntime)))) return; const newCode = addRefreshWrapper(code, "@vitejs/plugin-react-oxc", id); return newCode ? { code: newCode, map: null } : void 0; } }, transformIndexHtml(_, config) { if (!skipFastRefresh) return [{ tag: "script", attrs: { type: "module" }, children: getPreambleCode(config.server.config.base) }]; } } ]; } //#endregion export { viteReact as default };