|
1 | 1 | import fs from 'node:fs' |
2 | 2 | import path from 'node:path' |
3 | 3 | import { createRequire } from 'node:module' |
4 | | -import type { types as t } from '@babel/core' |
5 | 4 |
|
6 | 5 | export const runtimePublicPath = '/@react-refresh' |
7 | 6 |
|
@@ -67,14 +66,6 @@ const timeout = ` |
67 | 66 | } |
68 | 67 | ` |
69 | 68 |
|
70 | | -const footer = ` |
71 | | -if (import.meta.hot) { |
72 | | - window.$RefreshReg$ = prevRefreshReg; |
73 | | - window.$RefreshSig$ = prevRefreshSig; |
74 | | -
|
75 | | - __ACCEPT__ |
76 | | -}` |
77 | | - |
78 | 69 | const checkAndAccept = ` |
79 | 70 | function isReactRefreshBoundary(mod) { |
80 | 71 | if (mod == null || typeof mod !== 'object') { |
@@ -109,47 +100,14 @@ import.meta.hot.accept(mod => { |
109 | 100 | }); |
110 | 101 | ` |
111 | 102 |
|
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; |
148 | 107 |
|
149 | | -function isComponentLikeIdentifier(node: t.Node): boolean { |
150 | | - return node.type === 'Identifier' && isComponentLikeName(node.name) |
151 | | -} |
| 108 | + ${checkAndAccept} |
| 109 | +}` |
152 | 110 |
|
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 |
155 | 113 | } |
0 commit comments