版博士V2.0程序
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

chunk-NXJ7EWBD.mjs 7.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // src/core/constants.ts
  2. var SETUP_COMPONENT_ID_SUFFIX = "-setup-component-";
  3. var SETUP_COMPONENT_ID_REGEX = /-setup-component-(\d+).vue$/;
  4. var SETUP_COMPONENT_SUB_MODULE = /-setup-component-(\d+).vue.*/;
  5. var SETUP_COMPONENT_TYPE = "SetupFC";
  6. // src/core/sub-module.ts
  7. function isSubModule(id) {
  8. return SETUP_COMPONENT_SUB_MODULE.test(id);
  9. }
  10. function getMainModule(subModule, root) {
  11. return root + subModule.replace(SETUP_COMPONENT_SUB_MODULE, "");
  12. }
  13. // src/core/index.ts
  14. import {
  15. DEFINE_SETUP_COMPONENT,
  16. HELPER_PREFIX,
  17. MagicString,
  18. attachScopes,
  19. babelParse,
  20. getLang,
  21. getTransformResult,
  22. isCallOf,
  23. normalizePath,
  24. walkAST
  25. } from "@vue-macros/common";
  26. function scanSetupComponent(code, id) {
  27. let program;
  28. try {
  29. program = babelParse(code, getLang(id));
  30. } catch {
  31. return void 0;
  32. }
  33. const components = [];
  34. const imports = [];
  35. let scope = attachScopes(program, "scope");
  36. walkAST(program, {
  37. enter(node) {
  38. var _a;
  39. if (node.scope)
  40. scope = node.scope;
  41. const scopes = getScopeDecls(scope);
  42. if (isCallOf(node, DEFINE_SETUP_COMPONENT)) {
  43. components.push({
  44. fn: node,
  45. decl: node.arguments[0],
  46. scopes
  47. });
  48. } else if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && ((_a = node.id.typeAnnotation) == null ? void 0 : _a.type) === "TSTypeAnnotation" && node.id.typeAnnotation.typeAnnotation.type === "TSTypeReference" && node.id.typeAnnotation.typeAnnotation.typeName.type === "Identifier" && node.id.typeAnnotation.typeAnnotation.typeName.name === SETUP_COMPONENT_TYPE && node.init) {
  49. components.push({
  50. decl: node.init,
  51. scopes
  52. });
  53. } else if (node.type === "ImportDeclaration") {
  54. imports.push(code.slice(node.start, node.end));
  55. }
  56. },
  57. leave(node) {
  58. if (node.scope)
  59. scope = scope.parent;
  60. }
  61. });
  62. const ctxComponents = components.map(
  63. ({ decl, fn, scopes }) => {
  64. if (!["FunctionExpression", "ArrowFunctionExpression"].includes(decl.type))
  65. throw new SyntaxError(
  66. `${DEFINE_SETUP_COMPONENT}: invalid setup component definition`
  67. );
  68. const body = decl == null ? void 0 : decl.body;
  69. let bodyStart = body.start;
  70. let bodyEnd = body.end;
  71. if (body.type === "BlockStatement") {
  72. bodyStart++;
  73. bodyEnd--;
  74. }
  75. return {
  76. code: code.slice(decl.start, decl.end),
  77. body: code.slice(bodyStart, bodyEnd),
  78. node: fn || decl,
  79. scopes
  80. };
  81. }
  82. );
  83. return {
  84. components: ctxComponents,
  85. imports
  86. };
  87. }
  88. function transformSetupComponent(code, _id, ctx) {
  89. const id = normalizePath(_id);
  90. const s = new MagicString(code);
  91. const fileContext = scanSetupComponent(code, id);
  92. if (!fileContext)
  93. return;
  94. const { components } = fileContext;
  95. ctx[id] = fileContext;
  96. for (const [i, { node, scopes }] of components.entries()) {
  97. const importName = `${HELPER_PREFIX}setupComponent_${i}`;
  98. s.overwrite(
  99. node.start,
  100. node.end,
  101. `${importName}(() => ({ ${scopes.join(", ")} }))`
  102. );
  103. s.prepend(
  104. `import ${importName} from '${id}${SETUP_COMPONENT_ID_SUFFIX}${i}.vue'
  105. `
  106. );
  107. }
  108. return getTransformResult(s, id);
  109. }
  110. function loadSetupComponent(virtualId, ctx, root) {
  111. var _a;
  112. const index = +(((_a = SETUP_COMPONENT_ID_REGEX.exec(virtualId)) == null ? void 0 : _a[1]) ?? -1);
  113. const id = virtualId.replace(SETUP_COMPONENT_ID_REGEX, "");
  114. const { components, imports } = ctx[id] || ctx[root + id] || {};
  115. const component = components[index];
  116. if (!component)
  117. return;
  118. const { body, scopes } = component;
  119. const lang = getLang(id);
  120. const s = new MagicString(body);
  121. const program = babelParse(body, lang, {
  122. allowReturnOutsideFunction: true,
  123. allowImportExportEverywhere: true
  124. });
  125. for (const stmt of program.body) {
  126. if (stmt.type !== "ReturnStatement" || !stmt.argument)
  127. continue;
  128. s.overwriteNode(stmt, `defineRender(${s.sliceNode(stmt.argument)});`);
  129. }
  130. const rootVars = Object.keys(
  131. attachScopes(program, "scope").declarations
  132. );
  133. s.prepend(
  134. `const { ${scopes.filter((name) => !rootVars.includes(name)).join(", ")} } = ${HELPER_PREFIX}ctx();
  135. `
  136. );
  137. for (const i of imports)
  138. s.prepend(`${i}
  139. `);
  140. s.prepend(`<script setup${lang ? ` lang="${lang}"` : ""}>
  141. `);
  142. s.append(`</script>`);
  143. return s.toString();
  144. }
  145. async function hotUpdateSetupComponent({ file, modules, read }, ctx) {
  146. const getSubModule = (module2) => {
  147. const importedModules = Array.from(module2.importedModules);
  148. if (importedModules.length === 0)
  149. return [];
  150. return importedModules.filter(({ id }) => id && isSubModule(id)).flatMap((module3) => [module3, ...getSubModule(module3)]);
  151. };
  152. const module = modules.find((mod) => mod.file === file);
  153. if (!(module == null ? void 0 : module.id))
  154. return;
  155. const affectedModules = getSubModule(module);
  156. const normalizedId = normalizePath(file);
  157. const nodeContexts = scanSetupComponent(await read(), normalizedId);
  158. if (nodeContexts)
  159. ctx[normalizedId] = nodeContexts;
  160. return [...modules, ...affectedModules];
  161. }
  162. function transformPost(code, _id) {
  163. const s = new MagicString(code);
  164. const id = normalizePath(_id);
  165. if (id.endsWith(".vue")) {
  166. return transformMainEntry();
  167. } else if (id.includes("type=script")) {
  168. return transformScript();
  169. }
  170. function transformMainEntry() {
  171. const program = babelParse(code, "js");
  172. walkAST(program, {
  173. enter(node, parent) {
  174. var _a;
  175. if (node.type === "ExportDefaultDeclaration" && node.declaration) {
  176. const exportDefault = node.declaration;
  177. s.prependLeft(
  178. ((_a = exportDefault.leadingComments) == null ? void 0 : _a[0].start) ?? exportDefault.start,
  179. "(ctx) => "
  180. );
  181. } else if (node.type === "Identifier" && node.name === "_sfc_main" && (parent.type === "CallExpression" && parent.callee.type === "Identifier" && parent.callee.name === "_export_sfc" && node.name === "_sfc_main" || parent.type === "ExportDefaultDeclaration")) {
  182. s.appendLeft(node.end, "(ctx)");
  183. }
  184. }
  185. });
  186. return getTransformResult(s, id);
  187. }
  188. function transformScript() {
  189. const program = babelParse(code, getLang(id));
  190. walkAST(program, {
  191. enter(node) {
  192. var _a;
  193. if (node.type === "ExportDefaultDeclaration" && node.declaration) {
  194. const exportDefault = node.declaration;
  195. s.prependLeft(
  196. ((_a = exportDefault.leadingComments) == null ? void 0 : _a[0].start) ?? exportDefault.start,
  197. `(${HELPER_PREFIX}ctx) => `
  198. );
  199. }
  200. }
  201. });
  202. return getTransformResult(s, id);
  203. }
  204. }
  205. function getScopeDecls(scope) {
  206. const scopes = /* @__PURE__ */ new Set();
  207. do {
  208. if (!(scope == null ? void 0 : scope.declarations))
  209. continue;
  210. Object.keys(scope.declarations).forEach((name) => scopes.add(name));
  211. } while (scope = scope == null ? void 0 : scope.parent);
  212. return Array.from(scopes);
  213. }
  214. export {
  215. SETUP_COMPONENT_ID_SUFFIX,
  216. SETUP_COMPONENT_ID_REGEX,
  217. SETUP_COMPONENT_SUB_MODULE,
  218. SETUP_COMPONENT_TYPE,
  219. isSubModule,
  220. getMainModule,
  221. scanSetupComponent,
  222. transformSetupComponent,
  223. loadSetupComponent,
  224. hotUpdateSetupComponent,
  225. transformPost,
  226. getScopeDecls
  227. };