optimize-hook-destructuring.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = _default;
  6. // matches any hook-like (the default)
  7. const isHook = /^use[A-Z]/;
  8. // matches only built-in hooks provided by React et al
  9. const isBuiltInHook = /^use(Callback|Context|DebugValue|Effect|ImperativeHandle|LayoutEffect|Memo|Reducer|Ref|State)$/;
  10. function _default({ types: t }) {
  11. const visitor = {
  12. CallExpression (path, state) {
  13. const onlyBuiltIns = state.opts.onlyBuiltIns;
  14. // if specified, options.lib is a list of libraries that provide hook functions
  15. const libs = state.opts.lib && (state.opts.lib === true ? [
  16. "react",
  17. "preact/hooks"
  18. ] : [].concat(state.opts.lib));
  19. // skip function calls that are not the init of a variable declaration:
  20. if (!t.isVariableDeclarator(path.parent)) return;
  21. // skip function calls where the return value is not Array-destructured:
  22. if (!t.isArrayPattern(path.parent.id)) return;
  23. // name of the (hook) function being called:
  24. const hookName = path.node.callee.name;
  25. if (libs) {
  26. const binding = path.scope.getBinding(hookName);
  27. // not an import
  28. if (!binding || binding.kind !== "module") return;
  29. const specifier = binding.path.parent.source.value;
  30. // not a match
  31. if (!libs.some((lib)=>lib === specifier)) return;
  32. }
  33. // only match function calls with names that look like a hook
  34. if (!(onlyBuiltIns ? isBuiltInHook : isHook).test(hookName)) return;
  35. path.parent.id = t.objectPattern(path.parent.id.elements.reduce((patterns, element, i)=>{
  36. if (element === null) {
  37. return patterns;
  38. }
  39. return patterns.concat(t.objectProperty(t.numericLiteral(i), element));
  40. }, []));
  41. }
  42. };
  43. return {
  44. name: "optimize-hook-destructuring",
  45. visitor: {
  46. // this is a workaround to run before preset-env destroys destructured assignments
  47. Program (path, state) {
  48. path.traverse(visitor, state);
  49. }
  50. }
  51. };
  52. }
  53. //# sourceMappingURL=optimize-hook-destructuring.js.map