react-refresh-babel.production.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /**
  2. * @license React
  3. * react-refresh-babel.production.js
  4. *
  5. * Copyright (c) Meta Platforms, Inc. and affiliates.
  6. *
  7. * This source code is licensed under the MIT license found in the
  8. * LICENSE file in the root directory of this source tree.
  9. */
  10. "use strict";
  11. module.exports = function (babel) {
  12. function createRegistration(programPath, persistentID) {
  13. var handle = programPath.scope.generateUidIdentifier("c");
  14. registrationsByProgramPath.has(programPath) ||
  15. registrationsByProgramPath.set(programPath, []);
  16. registrationsByProgramPath
  17. .get(programPath)
  18. .push({ handle: handle, persistentID: persistentID });
  19. return handle;
  20. }
  21. function isComponentishName(name) {
  22. return "string" === typeof name && "A" <= name[0] && "Z" >= name[0];
  23. }
  24. function findInnerComponents(inferredName, path, callback) {
  25. var node = path.node;
  26. switch (node.type) {
  27. case "Identifier":
  28. if (!isComponentishName(node.name)) break;
  29. callback(inferredName, node, null);
  30. return !0;
  31. case "FunctionDeclaration":
  32. return callback(inferredName, node.id, null), !0;
  33. case "ArrowFunctionExpression":
  34. if ("ArrowFunctionExpression" === node.body.type) break;
  35. callback(inferredName, node, path);
  36. return !0;
  37. case "FunctionExpression":
  38. return callback(inferredName, node, path), !0;
  39. case "CallExpression":
  40. var argsPath = path.get("arguments");
  41. if (void 0 === argsPath || 0 === argsPath.length) break;
  42. var calleePath = path.get("callee");
  43. switch (calleePath.node.type) {
  44. case "MemberExpression":
  45. case "Identifier":
  46. calleePath = calleePath.getSource();
  47. if (
  48. !findInnerComponents(
  49. inferredName + "$" + calleePath,
  50. argsPath[0],
  51. callback
  52. )
  53. )
  54. return !1;
  55. callback(inferredName, node, path);
  56. return !0;
  57. default:
  58. return !1;
  59. }
  60. case "VariableDeclarator":
  61. if (
  62. ((argsPath = node.init),
  63. null !== argsPath &&
  64. ((calleePath = node.id.name), isComponentishName(calleePath)))
  65. ) {
  66. switch (argsPath.type) {
  67. case "ArrowFunctionExpression":
  68. case "FunctionExpression":
  69. break;
  70. case "CallExpression":
  71. node = argsPath.callee;
  72. var calleeType = node.type;
  73. if (
  74. "Import" === calleeType ||
  75. ("Identifier" === calleeType &&
  76. (0 === node.name.indexOf("require") ||
  77. 0 === node.name.indexOf("import")))
  78. )
  79. return !1;
  80. break;
  81. case "TaggedTemplateExpression":
  82. break;
  83. default:
  84. return !1;
  85. }
  86. node = path.get("init");
  87. if (findInnerComponents(inferredName, node, callback)) return !0;
  88. calleePath = path.scope.getBinding(calleePath);
  89. if (void 0 === calleePath) return;
  90. path = !1;
  91. calleePath = calleePath.referencePaths;
  92. for (calleeType = 0; calleeType < calleePath.length; calleeType++) {
  93. var ref = calleePath[calleeType];
  94. if (
  95. !ref.node ||
  96. "JSXIdentifier" === ref.node.type ||
  97. "Identifier" === ref.node.type
  98. ) {
  99. ref = ref.parent;
  100. if ("JSXOpeningElement" === ref.type) path = !0;
  101. else if ("CallExpression" === ref.type) {
  102. ref = ref.callee;
  103. var fnName = void 0;
  104. switch (ref.type) {
  105. case "Identifier":
  106. fnName = ref.name;
  107. break;
  108. case "MemberExpression":
  109. fnName = ref.property.name;
  110. }
  111. switch (fnName) {
  112. case "createElement":
  113. case "jsx":
  114. case "jsxDEV":
  115. case "jsxs":
  116. path = !0;
  117. }
  118. }
  119. if (path) return callback(inferredName, argsPath, node), !0;
  120. }
  121. }
  122. }
  123. }
  124. return !1;
  125. }
  126. function getHookCallsSignature(functionNode) {
  127. functionNode = hookCalls.get(functionNode);
  128. return void 0 === functionNode
  129. ? null
  130. : {
  131. key: functionNode
  132. .map(function (call) {
  133. return call.name + "{" + call.key + "}";
  134. })
  135. .join("\n"),
  136. customHooks: functionNode
  137. .filter(function (call) {
  138. a: switch (call.name) {
  139. case "useState":
  140. case "React.useState":
  141. case "useReducer":
  142. case "React.useReducer":
  143. case "useEffect":
  144. case "React.useEffect":
  145. case "useLayoutEffect":
  146. case "React.useLayoutEffect":
  147. case "useMemo":
  148. case "React.useMemo":
  149. case "useCallback":
  150. case "React.useCallback":
  151. case "useRef":
  152. case "React.useRef":
  153. case "useContext":
  154. case "React.useContext":
  155. case "useImperativeHandle":
  156. case "React.useImperativeHandle":
  157. case "useDebugValue":
  158. case "React.useDebugValue":
  159. case "useId":
  160. case "React.useId":
  161. case "useDeferredValue":
  162. case "React.useDeferredValue":
  163. case "useTransition":
  164. case "React.useTransition":
  165. case "useInsertionEffect":
  166. case "React.useInsertionEffect":
  167. case "useSyncExternalStore":
  168. case "React.useSyncExternalStore":
  169. case "useFormStatus":
  170. case "React.useFormStatus":
  171. case "useFormState":
  172. case "React.useFormState":
  173. case "useActionState":
  174. case "React.useActionState":
  175. case "useOptimistic":
  176. case "React.useOptimistic":
  177. call = !0;
  178. break a;
  179. default:
  180. call = !1;
  181. }
  182. return !call;
  183. })
  184. .map(function (call) {
  185. return t.cloneDeep(call.callee);
  186. })
  187. };
  188. }
  189. function hasForceResetComment(path) {
  190. path = path.hub.file;
  191. var hasForceReset = hasForceResetCommentByFile.get(path);
  192. if (void 0 !== hasForceReset) return hasForceReset;
  193. hasForceReset = !1;
  194. for (var comments = path.ast.comments, i = 0; i < comments.length; i++)
  195. if (-1 !== comments[i].value.indexOf("@refresh reset")) {
  196. hasForceReset = !0;
  197. break;
  198. }
  199. hasForceResetCommentByFile.set(path, hasForceReset);
  200. return hasForceReset;
  201. }
  202. function createArgumentsForSignature(node, signature, scope) {
  203. var key = signature.key;
  204. signature = signature.customHooks;
  205. var forceReset = hasForceResetComment(scope.path),
  206. customHooksInScope = [];
  207. signature.forEach(function (callee) {
  208. switch (callee.type) {
  209. case "MemberExpression":
  210. if ("Identifier" === callee.object.type)
  211. var bindingName = callee.object.name;
  212. break;
  213. case "Identifier":
  214. bindingName = callee.name;
  215. }
  216. scope.hasBinding(bindingName)
  217. ? customHooksInScope.push(callee)
  218. : (forceReset = !0);
  219. });
  220. signature = key;
  221. "function" !== typeof require ||
  222. opts.emitFullSignatures ||
  223. (signature = require("crypto")
  224. .createHash("sha1")
  225. .update(key)
  226. .digest("base64"));
  227. node = [node, t.stringLiteral(signature)];
  228. (forceReset || 0 < customHooksInScope.length) &&
  229. node.push(t.booleanLiteral(forceReset));
  230. 0 < customHooksInScope.length &&
  231. node.push(
  232. t.functionExpression(
  233. null,
  234. [],
  235. t.blockStatement([
  236. t.returnStatement(t.arrayExpression(customHooksInScope))
  237. ])
  238. )
  239. );
  240. return node;
  241. }
  242. function findHOCCallPathsAbove(path) {
  243. for (var calls = []; ; ) {
  244. if (!path) return calls;
  245. var parentPath = path.parentPath;
  246. if (!parentPath) return calls;
  247. if (
  248. "AssignmentExpression" === parentPath.node.type &&
  249. path.node === parentPath.node.right
  250. )
  251. path = parentPath;
  252. else if (
  253. "CallExpression" === parentPath.node.type &&
  254. path.node !== parentPath.node.callee
  255. )
  256. calls.push(parentPath), (path = parentPath);
  257. else return calls;
  258. }
  259. }
  260. var opts =
  261. 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {};
  262. if ("function" === typeof babel.env) {
  263. var env = babel.env();
  264. if ("development" !== env && !opts.skipEnvCheck)
  265. throw Error(
  266. 'React Refresh Babel transform should only be enabled in development environment. Instead, the environment is: "' +
  267. env +
  268. '". If you want to override this check, pass {skipEnvCheck: true} as plugin options.'
  269. );
  270. }
  271. var t = babel.types,
  272. refreshReg = t.identifier(opts.refreshReg || "$RefreshReg$"),
  273. refreshSig = t.identifier(opts.refreshSig || "$RefreshSig$"),
  274. registrationsByProgramPath = new Map(),
  275. hasForceResetCommentByFile = new WeakMap(),
  276. seenForRegistration = new WeakSet(),
  277. seenForSignature = new WeakSet(),
  278. seenForOutro = new WeakSet(),
  279. hookCalls = new WeakMap(),
  280. HookCallsVisitor = {
  281. CallExpression: function (path) {
  282. var callee = path.node.callee,
  283. name = null;
  284. switch (callee.type) {
  285. case "Identifier":
  286. name = callee.name;
  287. break;
  288. case "MemberExpression":
  289. name = callee.property.name;
  290. }
  291. if (
  292. null !== name &&
  293. /^use[A-Z]/.test(name) &&
  294. ((callee = path.scope.getFunctionParent()), null !== callee)
  295. ) {
  296. callee = callee.block;
  297. hookCalls.has(callee) || hookCalls.set(callee, []);
  298. callee = hookCalls.get(callee);
  299. var key = "";
  300. "VariableDeclarator" === path.parent.type &&
  301. (key = path.parentPath.get("id").getSource());
  302. var args = path.get("arguments");
  303. "useState" === name && 0 < args.length
  304. ? (key += "(" + args[0].getSource() + ")")
  305. : "useReducer" === name &&
  306. 1 < args.length &&
  307. (key += "(" + args[1].getSource() + ")");
  308. callee.push({ callee: path.node.callee, name: name, key: key });
  309. }
  310. }
  311. };
  312. return {
  313. visitor: {
  314. ExportDefaultDeclaration: function (path) {
  315. var node = path.node,
  316. decl = node.declaration,
  317. declPath = path.get("declaration");
  318. if ("CallExpression" === decl.type && !seenForRegistration.has(node)) {
  319. seenForRegistration.add(node);
  320. var programPath = path.parentPath;
  321. findInnerComponents(
  322. "%default%",
  323. declPath,
  324. function (persistentID, targetExpr, targetPath) {
  325. null !== targetPath &&
  326. ((persistentID = createRegistration(programPath, persistentID)),
  327. targetPath.replaceWith(
  328. t.assignmentExpression("=", persistentID, targetExpr)
  329. ));
  330. }
  331. );
  332. }
  333. },
  334. FunctionDeclaration: {
  335. enter: function (path) {
  336. var node = path.node,
  337. modulePrefix = "";
  338. switch (path.parent.type) {
  339. case "Program":
  340. var insertAfterPath = path;
  341. var programPath = path.parentPath;
  342. break;
  343. case "TSModuleBlock":
  344. insertAfterPath = path;
  345. programPath = insertAfterPath.parentPath.parentPath;
  346. break;
  347. case "ExportNamedDeclaration":
  348. insertAfterPath = path.parentPath;
  349. programPath = insertAfterPath.parentPath;
  350. break;
  351. case "ExportDefaultDeclaration":
  352. insertAfterPath = path.parentPath;
  353. programPath = insertAfterPath.parentPath;
  354. break;
  355. default:
  356. return;
  357. }
  358. if (
  359. "TSModuleBlock" === path.parent.type ||
  360. "ExportNamedDeclaration" === path.parent.type
  361. )
  362. for (; "Program" !== programPath.type; ) {
  363. if ("TSModuleDeclaration" === programPath.type) {
  364. if (
  365. "Program" !== programPath.parentPath.type &&
  366. "ExportNamedDeclaration" !== programPath.parentPath.type
  367. )
  368. return;
  369. modulePrefix = programPath.node.id.name + "$" + modulePrefix;
  370. }
  371. programPath = programPath.parentPath;
  372. }
  373. var id = node.id;
  374. null !== id &&
  375. ((id = id.name),
  376. isComponentishName(id) &&
  377. !seenForRegistration.has(node) &&
  378. (seenForRegistration.add(node),
  379. findInnerComponents(
  380. modulePrefix + id,
  381. path,
  382. function (persistentID, targetExpr) {
  383. persistentID = createRegistration(programPath, persistentID);
  384. insertAfterPath.insertAfter(
  385. t.expressionStatement(
  386. t.assignmentExpression("=", persistentID, targetExpr)
  387. )
  388. );
  389. }
  390. )));
  391. },
  392. exit: function (path) {
  393. var node = path.node,
  394. id = node.id;
  395. if (null !== id) {
  396. var signature = getHookCallsSignature(node);
  397. if (null !== signature && !seenForSignature.has(node)) {
  398. seenForSignature.add(node);
  399. node = path.scope.generateUidIdentifier("_s");
  400. path.scope.parent.push({
  401. id: node,
  402. init: t.callExpression(refreshSig, [])
  403. });
  404. path
  405. .get("body")
  406. .unshiftContainer(
  407. "body",
  408. t.expressionStatement(t.callExpression(node, []))
  409. );
  410. var insertAfterPath = null;
  411. path.find(function (p) {
  412. if (p.parentPath.isBlock()) return (insertAfterPath = p), !0;
  413. });
  414. null !== insertAfterPath &&
  415. insertAfterPath.insertAfter(
  416. t.expressionStatement(
  417. t.callExpression(
  418. node,
  419. createArgumentsForSignature(
  420. id,
  421. signature,
  422. insertAfterPath.scope
  423. )
  424. )
  425. )
  426. );
  427. }
  428. }
  429. }
  430. },
  431. "ArrowFunctionExpression|FunctionExpression": {
  432. exit: function (path) {
  433. var node = path.node,
  434. signature = getHookCallsSignature(node);
  435. if (null !== signature && !seenForSignature.has(node)) {
  436. seenForSignature.add(node);
  437. var sigCallID = path.scope.generateUidIdentifier("_s");
  438. path.scope.parent.push({
  439. id: sigCallID,
  440. init: t.callExpression(refreshSig, [])
  441. });
  442. "BlockStatement" !== path.node.body.type &&
  443. (path.node.body = t.blockStatement([
  444. t.returnStatement(path.node.body)
  445. ]));
  446. path
  447. .get("body")
  448. .unshiftContainer(
  449. "body",
  450. t.expressionStatement(t.callExpression(sigCallID, []))
  451. );
  452. if ("VariableDeclarator" === path.parent.type) {
  453. var insertAfterPath = null;
  454. path.find(function (p) {
  455. if (p.parentPath.isBlock()) return (insertAfterPath = p), !0;
  456. });
  457. null !== insertAfterPath &&
  458. insertAfterPath.insertAfter(
  459. t.expressionStatement(
  460. t.callExpression(
  461. sigCallID,
  462. createArgumentsForSignature(
  463. path.parent.id,
  464. signature,
  465. insertAfterPath.scope
  466. )
  467. )
  468. )
  469. );
  470. } else
  471. [path].concat(findHOCCallPathsAbove(path)).forEach(function (p) {
  472. p.replaceWith(
  473. t.callExpression(
  474. sigCallID,
  475. createArgumentsForSignature(p.node, signature, p.scope)
  476. )
  477. );
  478. });
  479. }
  480. }
  481. },
  482. VariableDeclaration: function (path) {
  483. var node = path.node,
  484. modulePrefix = "";
  485. switch (path.parent.type) {
  486. case "Program":
  487. var insertAfterPath = path;
  488. var programPath = path.parentPath;
  489. break;
  490. case "TSModuleBlock":
  491. insertAfterPath = path;
  492. programPath = insertAfterPath.parentPath.parentPath;
  493. break;
  494. case "ExportNamedDeclaration":
  495. insertAfterPath = path.parentPath;
  496. programPath = insertAfterPath.parentPath;
  497. break;
  498. case "ExportDefaultDeclaration":
  499. insertAfterPath = path.parentPath;
  500. programPath = insertAfterPath.parentPath;
  501. break;
  502. default:
  503. return;
  504. }
  505. if (
  506. "TSModuleBlock" === path.parent.type ||
  507. "ExportNamedDeclaration" === path.parent.type
  508. )
  509. for (; "Program" !== programPath.type; ) {
  510. if ("TSModuleDeclaration" === programPath.type) {
  511. if (
  512. "Program" !== programPath.parentPath.type &&
  513. "ExportNamedDeclaration" !== programPath.parentPath.type
  514. )
  515. return;
  516. modulePrefix = programPath.node.id.name + "$" + modulePrefix;
  517. }
  518. programPath = programPath.parentPath;
  519. }
  520. if (
  521. !seenForRegistration.has(node) &&
  522. (seenForRegistration.add(node),
  523. (path = path.get("declarations")),
  524. 1 === path.length)
  525. ) {
  526. var declPath = path[0];
  527. findInnerComponents(
  528. modulePrefix + declPath.node.id.name,
  529. declPath,
  530. function (persistentID, targetExpr, targetPath) {
  531. null !== targetPath &&
  532. ((persistentID = createRegistration(programPath, persistentID)),
  533. "VariableDeclarator" === targetPath.parent.type
  534. ? insertAfterPath.insertAfter(
  535. t.expressionStatement(
  536. t.assignmentExpression(
  537. "=",
  538. persistentID,
  539. declPath.node.id
  540. )
  541. )
  542. )
  543. : targetPath.replaceWith(
  544. t.assignmentExpression("=", persistentID, targetExpr)
  545. ));
  546. }
  547. );
  548. }
  549. },
  550. Program: {
  551. enter: function (path) {
  552. path.traverse(HookCallsVisitor);
  553. },
  554. exit: function (path) {
  555. var registrations = registrationsByProgramPath.get(path);
  556. if (void 0 !== registrations) {
  557. var node = path.node;
  558. if (!seenForOutro.has(node)) {
  559. seenForOutro.add(node);
  560. registrationsByProgramPath.delete(path);
  561. var declarators = [];
  562. path.pushContainer(
  563. "body",
  564. t.variableDeclaration("var", declarators)
  565. );
  566. registrations.forEach(function (_ref) {
  567. var handle = _ref.handle;
  568. path.pushContainer(
  569. "body",
  570. t.expressionStatement(
  571. t.callExpression(refreshReg, [
  572. handle,
  573. t.stringLiteral(_ref.persistentID)
  574. ])
  575. )
  576. );
  577. declarators.push(t.variableDeclarator(handle));
  578. });
  579. }
  580. }
  581. }
  582. }
  583. }
  584. };
  585. };