Skip to content

Commit e43bd76

Browse files
authoredDec 5, 2022
chore!: drop ast check for refresh boundary (#43)
1 parent dab77ea commit e43bd76

File tree

2 files changed

+11
-62
lines changed

2 files changed

+11
-62
lines changed
 

‎packages/plugin-react/src/fast-refresh.ts

+8-50
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
33
import { createRequire } from 'node:module'
4-
import type { types as t } from '@babel/core'
54

65
export const runtimePublicPath = '/@react-refresh'
76

@@ -67,14 +66,6 @@ const timeout = `
6766
}
6867
`
6968

70-
const footer = `
71-
if (import.meta.hot) {
72-
window.$RefreshReg$ = prevRefreshReg;
73-
window.$RefreshSig$ = prevRefreshSig;
74-
75-
__ACCEPT__
76-
}`
77-
7869
const checkAndAccept = `
7970
function isReactRefreshBoundary(mod) {
8071
if (mod == null || typeof mod !== 'object') {
@@ -109,47 +100,14 @@ import.meta.hot.accept(mod => {
109100
});
110101
`
111102

112-
export function addRefreshWrapper(
113-
code: string,
114-
id: string,
115-
accept: boolean,
116-
): string {
117-
return (
118-
header.replace('__SOURCE__', JSON.stringify(id)) +
119-
code +
120-
footer.replace('__ACCEPT__', accept ? checkAndAccept : timeout)
121-
)
122-
}
123-
124-
export function isRefreshBoundary(ast: t.File): boolean {
125-
// Every export must be a potential React component.
126-
// We'll also perform a runtime check that's more robust as well (isLikelyComponentType).
127-
return ast.program.body.every((node) => {
128-
if (node.type !== 'ExportNamedDeclaration') {
129-
return true
130-
}
131-
const { declaration, specifiers } = node
132-
if (declaration) {
133-
if (declaration.type === 'ClassDeclaration') return false
134-
if (declaration.type === 'VariableDeclaration') {
135-
return declaration.declarations.every((variable) =>
136-
isComponentLikeIdentifier(variable.id),
137-
)
138-
}
139-
if (declaration.type === 'FunctionDeclaration') {
140-
return !!declaration.id && isComponentLikeIdentifier(declaration.id)
141-
}
142-
}
143-
return specifiers.every((spec) => {
144-
return isComponentLikeIdentifier(spec.exported)
145-
})
146-
})
147-
}
103+
const footer = `
104+
if (import.meta.hot) {
105+
window.$RefreshReg$ = prevRefreshReg;
106+
window.$RefreshSig$ = prevRefreshSig;
148107
149-
function isComponentLikeIdentifier(node: t.Node): boolean {
150-
return node.type === 'Identifier' && isComponentLikeName(node.name)
151-
}
108+
${checkAndAccept}
109+
}`
152110

153-
function isComponentLikeName(name: string): boolean {
154-
return typeof name === 'string' && name[0] >= 'A' && name[0] <= 'Z'
111+
export function addRefreshWrapper(code: string, id: string): string {
112+
return header.replace('__SOURCE__', JSON.stringify(id)) + code + footer
155113
}

‎packages/plugin-react/src/index.ts

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import path from 'node:path'
2-
import type { ParserOptions, TransformOptions, types as t } from '@babel/core'
2+
import type { ParserOptions, TransformOptions } from '@babel/core'
33
import * as babel from '@babel/core'
44
import { createFilter, loadEnv, normalizePath, resolveEnvPrefix } from 'vite'
55
import type { Plugin, PluginOption, ResolvedConfig } from 'vite'
66
import MagicString from 'magic-string'
77
import type { SourceMap } from 'magic-string'
88
import {
99
addRefreshWrapper,
10-
isRefreshBoundary,
1110
preambleCode,
1211
runtimeCode,
1312
runtimePublicPath,
@@ -245,7 +244,6 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
245244
}
246245
}
247246

248-
let ast: t.File | null | undefined
249247
let prependReactImport = false
250248
if (!isProjectFile || isJSX) {
251249
if (!useAutomaticRuntime && isProjectFile) {
@@ -314,14 +312,8 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
314312
parserPlugins.push('typescript')
315313
}
316314

317-
const transformAsync = ast
318-
? babel.transformFromAstAsync.bind(babel, ast, code)
319-
: babel.transformAsync.bind(babel, code)
320-
321-
const isReasonReact = extension.endsWith('.bs.js')
322-
const result = await transformAsync({
315+
const result = await babel.transformAsync(code, {
323316
...babelOptions,
324-
ast: !isReasonReact,
325317
root: projectRoot,
326318
filename: id,
327319
sourceFileName: filepath,
@@ -344,8 +336,7 @@ export default function viteReact(opts: Options = {}): PluginOption[] {
344336
if (result) {
345337
let code = result.code!
346338
if (useFastRefresh && /\$RefreshReg\$\(/.test(code)) {
347-
const accept = isReasonReact || isRefreshBoundary(result.ast!)
348-
code = addRefreshWrapper(code, id, accept)
339+
code = addRefreshWrapper(code, id)
349340
}
350341
return {
351342
code,

0 commit comments

Comments
 (0)
Please sign in to comment.