index.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. "use strict";
  2. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  3. if (k2 === undefined) k2 = k;
  4. Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  5. }) : (function(o, m, k, k2) {
  6. if (k2 === undefined) k2 = k;
  7. o[k2] = m[k];
  8. }));
  9. var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
  10. Object.defineProperty(o, "default", { enumerable: true, value: v });
  11. }) : function(o, v) {
  12. o["default"] = v;
  13. });
  14. var __importStar = (this && this.__importStar) || function (mod) {
  15. if (mod && mod.__esModule) return mod;
  16. var result = {};
  17. if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  18. __setModuleDefault(result, mod);
  19. return result;
  20. };
  21. var __importDefault = (this && this.__importDefault) || function (mod) {
  22. return (mod && mod.__esModule) ? mod : { "default": mod };
  23. };
  24. Object.defineProperty(exports, "__esModule", { value: true });
  25. const t = __importStar(require("@babel/types"));
  26. const template_1 = __importDefault(require("@babel/template"));
  27. const plugin_syntax_jsx_1 = __importDefault(require("@babel/plugin-syntax-jsx"));
  28. const helper_module_imports_1 = require("@babel/helper-module-imports");
  29. const transform_vue_jsx_1 = __importDefault(require("./transform-vue-jsx"));
  30. const sugar_fragment_1 = __importDefault(require("./sugar-fragment"));
  31. const hasJSX = (parentPath) => {
  32. let fileHasJSX = false;
  33. parentPath.traverse({
  34. JSXElement(path) {
  35. fileHasJSX = true;
  36. path.stop();
  37. },
  38. JSXFragment(path) {
  39. fileHasJSX = true;
  40. path.stop();
  41. },
  42. });
  43. return fileHasJSX;
  44. };
  45. const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
  46. exports.default = ({ types }) => ({
  47. name: 'babel-plugin-jsx',
  48. inherits: plugin_syntax_jsx_1.default,
  49. visitor: Object.assign(Object.assign(Object.assign({}, transform_vue_jsx_1.default), sugar_fragment_1.default), { Program: {
  50. enter(path, state) {
  51. if (hasJSX(path)) {
  52. const importNames = [
  53. 'createVNode',
  54. 'Fragment',
  55. 'resolveComponent',
  56. 'withDirectives',
  57. 'vShow',
  58. 'vModelSelect',
  59. 'vModelText',
  60. 'vModelCheckbox',
  61. 'vModelRadio',
  62. 'vModelText',
  63. 'vModelDynamic',
  64. 'resolveDirective',
  65. 'mergeProps',
  66. 'createTextVNode',
  67. 'isVNode',
  68. ];
  69. if (helper_module_imports_1.isModule(path)) {
  70. // import { createVNode } from "vue";
  71. const importMap = {};
  72. importNames.forEach((name) => {
  73. state.set(name, () => {
  74. if (importMap[name]) {
  75. return types.cloneNode(importMap[name]);
  76. }
  77. const identifier = helper_module_imports_1.addNamed(path, name, 'vue', {
  78. ensureLiveReference: true,
  79. });
  80. importMap[name] = identifier;
  81. return identifier;
  82. });
  83. });
  84. const { enableObjectSlots = true } = state.opts;
  85. if (enableObjectSlots) {
  86. state.set('@vue/babel-plugin-jsx/runtimeIsSlot', () => {
  87. if (importMap.runtimeIsSlot) {
  88. return importMap.runtimeIsSlot;
  89. }
  90. const { name: isVNodeName } = state.get('isVNode')();
  91. const isSlot = path.scope.generateUidIdentifier('isSlot');
  92. const ast = template_1.default.ast `
  93. function ${isSlot.name}(s) {
  94. return typeof s === 'function' || (Object.prototype.toString.call(s) === '[object Object]' && !${isVNodeName}(s));
  95. }
  96. `;
  97. const lastImport = path.get('body').filter((p) => p.isImportDeclaration()).pop();
  98. if (lastImport) {
  99. lastImport.insertAfter(ast);
  100. }
  101. importMap.runtimeIsSlot = isSlot;
  102. return isSlot;
  103. });
  104. }
  105. }
  106. else {
  107. // var _vue = require('vue');
  108. let sourceName = '';
  109. importNames.forEach((name) => {
  110. state.set(name, () => {
  111. if (!sourceName) {
  112. sourceName = helper_module_imports_1.addNamespace(path, 'vue', {
  113. ensureLiveReference: true,
  114. }).name;
  115. }
  116. return t.memberExpression(t.identifier(sourceName), t.identifier(name));
  117. });
  118. });
  119. }
  120. const { opts: { pragma = '' }, file } = state;
  121. if (pragma) {
  122. state.set('createVNode', () => t.identifier(pragma));
  123. }
  124. if (file.ast.comments) {
  125. for (const comment of file.ast.comments) {
  126. const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
  127. if (jsxMatches) {
  128. state.set('createVNode', () => t.identifier(jsxMatches[1]));
  129. }
  130. }
  131. }
  132. }
  133. },
  134. exit(path) {
  135. const body = path.get('body');
  136. const specifiersMap = new Map();
  137. body.filter((nodePath) => t.isImportDeclaration(nodePath.node)
  138. && nodePath.node.source.value === 'vue')
  139. .forEach((nodePath) => {
  140. const { specifiers } = nodePath.node;
  141. let shouldRemove = false;
  142. specifiers.forEach((specifier) => {
  143. if (!specifier.loc && t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported)) {
  144. specifiersMap.set(specifier.imported.name, specifier);
  145. shouldRemove = true;
  146. }
  147. });
  148. if (shouldRemove) {
  149. nodePath.remove();
  150. }
  151. });
  152. const specifiers = [...specifiersMap.keys()].map((imported) => specifiersMap.get(imported));
  153. if (specifiers.length) {
  154. path.unshiftContainer('body', t.importDeclaration(specifiers, t.stringLiteral('vue')));
  155. }
  156. },
  157. } }),
  158. });