diff --git a/packages/plugin-react/src/fast-refresh.ts b/packages/plugin-react/src/fast-refresh.ts index cea3d24..2dc7694 100644 --- a/packages/plugin-react/src/fast-refresh.ts +++ b/packages/plugin-react/src/fast-refresh.ts @@ -1,7 +1,6 @@ import fs from 'node:fs' import path from 'node:path' import { createRequire } from 'node:module' -import type { types as t } from '@babel/core' export const runtimePublicPath = '/@react-refresh' @@ -67,14 +66,6 @@ const timeout = ` } ` -const footer = ` -if (import.meta.hot) { - window.$RefreshReg$ = prevRefreshReg; - window.$RefreshSig$ = prevRefreshSig; - - __ACCEPT__ -}` - const checkAndAccept = ` function isReactRefreshBoundary(mod) { if (mod == null || typeof mod !== 'object') { @@ -109,47 +100,14 @@ import.meta.hot.accept(mod => { }); ` -export function addRefreshWrapper( - code: string, - id: string, - accept: boolean, -): string { - return ( - header.replace('__SOURCE__', JSON.stringify(id)) + - code + - footer.replace('__ACCEPT__', accept ? checkAndAccept : timeout) - ) -} - -export function isRefreshBoundary(ast: t.File): boolean { - // Every export must be a potential React component. - // We'll also perform a runtime check that's more robust as well (isLikelyComponentType). - return ast.program.body.every((node) => { - if (node.type !== 'ExportNamedDeclaration') { - return true - } - const { declaration, specifiers } = node - if (declaration) { - if (declaration.type === 'ClassDeclaration') return false - if (declaration.type === 'VariableDeclaration') { - return declaration.declarations.every((variable) => - isComponentLikeIdentifier(variable.id), - ) - } - if (declaration.type === 'FunctionDeclaration') { - return !!declaration.id && isComponentLikeIdentifier(declaration.id) - } - } - return specifiers.every((spec) => { - return isComponentLikeIdentifier(spec.exported) - }) - }) -} +const footer = ` +if (import.meta.hot) { + window.$RefreshReg$ = prevRefreshReg; + window.$RefreshSig$ = prevRefreshSig; -function isComponentLikeIdentifier(node: t.Node): boolean { - return node.type === 'Identifier' && isComponentLikeName(node.name) -} + ${checkAndAccept} +}` -function isComponentLikeName(name: string): boolean { - return typeof name === 'string' && name[0] >= 'A' && name[0] <= 'Z' +export function addRefreshWrapper(code: string, id: string): string { + return header.replace('__SOURCE__', JSON.stringify(id)) + code + footer } diff --git a/packages/plugin-react/src/index.ts b/packages/plugin-react/src/index.ts index 95db673..314ac34 100644 --- a/packages/plugin-react/src/index.ts +++ b/packages/plugin-react/src/index.ts @@ -1,5 +1,5 @@ import path from 'node:path' -import type { ParserOptions, TransformOptions, types as t } from '@babel/core' +import type { ParserOptions, TransformOptions } from '@babel/core' import * as babel from '@babel/core' import { createFilter, loadEnv, normalizePath, resolveEnvPrefix } from 'vite' import type { Plugin, PluginOption, ResolvedConfig } from 'vite' @@ -7,7 +7,6 @@ import MagicString from 'magic-string' import type { SourceMap } from 'magic-string' import { addRefreshWrapper, - isRefreshBoundary, preambleCode, runtimeCode, runtimePublicPath, @@ -245,7 +244,6 @@ export default function viteReact(opts: Options = {}): PluginOption[] { } } - let ast: t.File | null | undefined let prependReactImport = false if (!isProjectFile || isJSX) { if (!useAutomaticRuntime && isProjectFile) { @@ -314,14 +312,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] { parserPlugins.push('typescript') } - const transformAsync = ast - ? babel.transformFromAstAsync.bind(babel, ast, code) - : babel.transformAsync.bind(babel, code) - - const isReasonReact = extension.endsWith('.bs.js') - const result = await transformAsync({ + const result = await babel.transformAsync(code, { ...babelOptions, - ast: !isReasonReact, root: projectRoot, filename: id, sourceFileName: filepath, @@ -344,8 +336,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] { if (result) { let code = result.code! if (useFastRefresh && /\$RefreshReg\$\(/.test(code)) { - const accept = isReasonReact || isRefreshBoundary(result.ast!) - code = addRefreshWrapper(code, id, accept) + code = addRefreshWrapper(code, id) } return { code,