Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions packages/common/refresh-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ function performReactRefresh() {
}
}

function register(type, id) {
export function register(type, id) {
if (type === null) {
return
}
Expand Down Expand Up @@ -564,10 +564,6 @@ function isPlainObject(obj) {
* Plugin utils
*/

export function getRefreshReg(filename) {
return (type, id) => register(type, filename + ' ' + id)
}

// Taken from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/lib/runtime/RefreshUtils.js#L141
// This allows to resister components not detected by SWC like styled component
export function registerExportsForReactRefresh(filename, moduleExports) {
Expand Down
69 changes: 12 additions & 57 deletions packages/common/refresh-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,73 +14,29 @@ window.$RefreshSig$ = () => (type) => type;`
export const getPreambleCode = (base: string): string =>
preambleCode.replace('__BASE__', base)

export const avoidSourceMapOption = Symbol()

export function addRefreshWrapper<M extends { mappings: string }>(
export function addRefreshWrapper(
code: string,
map: M | string | typeof avoidSourceMapOption,
pluginName: string,
id: string,
reactRefreshHost = '',
): { code: string; map: M | null | string } {
): string | undefined {
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) as M)
: normalizedMap
if (!hasRefresh && !onlyReactComp) return undefined

let newCode = code
if (hasRefresh) {
const refreshHead = removeLineBreaksIfNeeded(
`let prevRefreshReg;
let prevRefreshSig;
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."
);
}

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,
Expand All @@ -95,13 +51,12 @@ if (import.meta.hot && !inWebWorker) {
});
}
`
if (newMap) {
newMap.mappings = ';;;' + newMap.mappings
}

return { code: newCode, map: newMap }
}
if (hasRefresh) {
newCode += `function $RefreshReg$(type, id) { return RefreshRuntime.register(type, ${JSON.stringify(id)} + ' ' + id) }
function $RefreshSig$() { return RefreshRuntime.createSignatureFunctionForTransform(); }
`
}

function removeLineBreaksIfNeeded(code: string, enabled: boolean): string {
return enabled ? code.replace(/\n/g, '') : code
return newCode
}
10 changes: 2 additions & 8 deletions packages/plugin-react-oxc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { readFileSync } from 'node:fs'
import type { BuildOptions, Plugin } from 'vite'
import {
addRefreshWrapper,
avoidSourceMapOption,
getPreambleCode,
runtimePublicPath,
silenceUseClientWarning,
Expand Down Expand Up @@ -140,13 +139,8 @@ export default function viteReact(opts: Options = {}): Plugin[] {
code.includes(jsxImportRuntime))
if (!useFastRefresh) return

const { code: newCode } = addRefreshWrapper(
code,
avoidSourceMapOption,
'@vitejs/plugin-react-oxc',
id,
)
return { code: newCode, map: null }
const newCode = addRefreshWrapper(code, '@vitejs/plugin-react-oxc', id)
return newCode ? { code: newCode, map: null } : undefined
},
},
transformIndexHtml(_, config) {
Expand Down
5 changes: 2 additions & 3 deletions packages/plugin-react-swc/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { readFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import type { SourceMapPayload } from 'node:module'
import { createRequire } from 'node:module'
import {
type JscTarget,
Expand Down Expand Up @@ -197,13 +196,13 @@ const react = (_options?: Options): Plugin[] => {
if (!result) return
if (!refresh) return result

return addRefreshWrapper<SourceMapPayload>(
const newCode = addRefreshWrapper(
result.code,
result.map!,
'@vitejs/plugin-react-swc',
id,
options.reactRefreshHost,
)
return { code: newCode ?? result.code, map: result.map }
},
},
options.plugins
Expand Down
10 changes: 4 additions & 6 deletions packages/plugin-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as vite from 'vite'
import type { Plugin, ResolvedConfig } from 'vite'
import {
addRefreshWrapper,
avoidSourceMapOption,
getPreambleCode,
preambleCode,
runtimePublicPath,
Expand Down Expand Up @@ -340,13 +339,13 @@ export default function viteReact(opts: Options = {}): Plugin[] {
if (!useFastRefresh) {
return { code: result.code!, map: result.map }
}
return addRefreshWrapper(
const code = addRefreshWrapper(
result.code!,
result.map!,
'@vitejs/plugin-react',
id,
opts.reactRefreshHost,
)
return { code: code ?? result.code!, map: result.map }
}
},
},
Expand Down Expand Up @@ -376,14 +375,13 @@ export default function viteReact(opts: Options = {}): Plugin[] {
code.includes(jsxImportRuntime))
if (!useFastRefresh) return

const { code: newCode } = addRefreshWrapper(
const newCode = addRefreshWrapper(
code,
avoidSourceMapOption,
'@vitejs/plugin-react',
id,
opts.reactRefreshHost,
)
return { code: newCode, map: null }
return newCode ? { code: newCode, map: null } : undefined
},
},
}
Expand Down
Loading