@wevu/compiler 6.6.15 → 6.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +216 -7
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -895,19 +895,19 @@ function resolveWevuConfigTempDir(fromDir) {
895
895
 
896
896
  //#endregion
897
897
  //#region src/plugins/vue/transform/jsonMacros/execute.ts
898
- function normalizeScriptSetupLang(lang) {
898
+ function normalizeScriptSetupLang$1(lang) {
899
899
  if (!lang) return "ts";
900
900
  const lower = lang.toLowerCase();
901
901
  if (lower === "txt") return "ts";
902
902
  return lower;
903
903
  }
904
- function resolveScriptSetupExtension(lang) {
905
- const normalized = normalizeScriptSetupLang(lang);
904
+ function resolveScriptSetupExtension$1(lang) {
905
+ const normalized = normalizeScriptSetupLang$1(lang);
906
906
  if (normalized === "ts" || normalized === "tsx" || normalized === "cts" || normalized === "mts") return "ts";
907
907
  return "js";
908
908
  }
909
909
  function resolveMacroAlias(macroName) {
910
- return macroName === "defineAppJson" ? "__weapp_defineAppJson" : macroName === "definePageJson" ? "__weapp_definePageJson" : "__weapp_defineComponentJson";
910
+ return macroName === "defineAppJson" ? "__weapp_defineAppJson" : macroName === "definePageJson" ? "__weapp_definePageJson" : macroName === "defineComponentJson" ? "__weapp_defineComponentJson" : macroName === "defineSitemapJson" ? "__weapp_defineSitemapJson" : "__weapp_defineThemeJson";
911
911
  }
912
912
  async function evaluateScriptSetupJsonMacro(params) {
913
913
  const { originalContent, filename, lang, macroName, macroStatements, bodyPaths, keptStatementPaths, options } = params;
@@ -939,8 +939,10 @@ const __weapp_json_macro_values = []
939
939
  const __weapp_defineAppJson = (config) => (__weapp_json_macro_values.push(config), config)
940
940
  const __weapp_definePageJson = (config) => (__weapp_json_macro_values.push(config), config)
941
941
  const __weapp_defineComponentJson = (config) => (__weapp_json_macro_values.push(config), config)
942
+ const __weapp_defineSitemapJson = (config) => (__weapp_json_macro_values.push(config), config)
943
+ const __weapp_defineThemeJson = (config) => (__weapp_json_macro_values.push(config), config)
942
944
  `.trimStart() + ms.toString() + `\nexport default __weapp_json_macro_values\n`;
943
- const extension = resolveScriptSetupExtension(lang);
945
+ const extension = resolveScriptSetupExtension$1(lang);
944
946
  return await withTempDirLock(tempDir, async () => {
945
947
  await fs.ensureDir(tempDir);
946
948
  const basename = path.basename(filename, path.extname(filename));
@@ -988,7 +990,9 @@ const __weapp_defineComponentJson = (config) => (__weapp_json_macro_values.push(
988
990
  const JSON_MACROS = new Set([
989
991
  "defineAppJson",
990
992
  "definePageJson",
991
- "defineComponentJson"
993
+ "defineComponentJson",
994
+ "defineSitemapJson",
995
+ "defineThemeJson"
992
996
  ]);
993
997
  function parseScriptSetupAst(content, filename) {
994
998
  try {
@@ -6390,6 +6394,171 @@ function finalizeResult(result, options) {
6390
6394
  if (result.meta && options.defineOptionsHash) result.meta.defineOptionsHash = options.defineOptionsHash;
6391
6395
  }
6392
6396
 
6397
+ //#endregion
6398
+ //#region src/plugins/vue/transform/defineOptions/inline.ts
6399
+ function normalizeScriptSetupLang(lang) {
6400
+ if (!lang) return "ts";
6401
+ const lower = lang.toLowerCase();
6402
+ if (lower === "txt") return "ts";
6403
+ return lower;
6404
+ }
6405
+ function resolveScriptSetupExtension(lang) {
6406
+ const normalized = normalizeScriptSetupLang(lang);
6407
+ if (normalized === "ts" || normalized === "tsx" || normalized === "cts" || normalized === "mts") return "ts";
6408
+ return "js";
6409
+ }
6410
+ function isIdentifierLikeKey(key) {
6411
+ return /^[A-Z_$][\w$]*$/i.test(key);
6412
+ }
6413
+ function serializeStaticValueToExpression(value, seen = /* @__PURE__ */ new WeakSet()) {
6414
+ if (value === null) return "null";
6415
+ if (value === void 0) return "undefined";
6416
+ const valueType = typeof value;
6417
+ if (valueType === "string") return JSON.stringify(value);
6418
+ if (valueType === "boolean") return value ? "true" : "false";
6419
+ if (valueType === "number") {
6420
+ if (Number.isNaN(value)) return "Number.NaN";
6421
+ if (value === Number.POSITIVE_INFINITY) return "Number.POSITIVE_INFINITY";
6422
+ if (value === Number.NEGATIVE_INFINITY) return "Number.NEGATIVE_INFINITY";
6423
+ if (Object.is(value, -0)) return "-0";
6424
+ return String(value);
6425
+ }
6426
+ if (valueType === "bigint") return `${String(value)}n`;
6427
+ if (valueType === "symbol") throw new Error("defineOptions 的参数中不支持 Symbol 值。");
6428
+ if (valueType === "function") {
6429
+ const source = Function.prototype.toString.call(value);
6430
+ if (source.includes("[native code]")) throw new Error("defineOptions 的参数中不支持原生函数值。");
6431
+ return `(${source})`;
6432
+ }
6433
+ if (value instanceof Date) return `new Date(${JSON.stringify(value.toISOString())})`;
6434
+ if (value instanceof RegExp) return value.toString();
6435
+ if (Array.isArray(value)) return `[${value.map((item) => serializeStaticValueToExpression(item, seen)).join(", ")}]`;
6436
+ if (value && typeof value === "object") {
6437
+ if (seen.has(value)) throw new Error("defineOptions 的参数中不支持循环引用。");
6438
+ seen.add(value);
6439
+ const proto = Object.getPrototypeOf(value);
6440
+ if (proto !== Object.prototype && proto !== null) throw new Error("defineOptions 的参数仅支持普通对象。");
6441
+ const objectValue = value;
6442
+ return `{ ${Object.keys(objectValue).map((key) => {
6443
+ return `${isIdentifierLikeKey(key) ? key : JSON.stringify(key)}: ${serializeStaticValueToExpression(objectValue[key], seen)}`;
6444
+ }).join(", ")} }`;
6445
+ }
6446
+ throw new Error(`defineOptions 的参数中包含不支持的值类型:${valueType}`);
6447
+ }
6448
+ function collectDefineOptionsStatements(content, filename) {
6449
+ const ast = parse$2(content, BABEL_TS_MODULE_PARSER_OPTIONS);
6450
+ const statements = [];
6451
+ traverse(ast, { CallExpression(path) {
6452
+ const callee = path.node.callee;
6453
+ if (!t.isIdentifier(callee, { name: "defineOptions" })) return;
6454
+ if (!(path.parentPath?.isExpressionStatement() && path.parentPath.parentPath?.isProgram())) return;
6455
+ if (path.node.arguments.length !== 1) throw new Error(`defineOptions() 在 ${filename} 中必须且只能传 1 个参数。`);
6456
+ statements.push({
6457
+ statementPath: path.parentPath,
6458
+ callPath: path,
6459
+ argPath: path.get("arguments.0")
6460
+ });
6461
+ } });
6462
+ return { statements };
6463
+ }
6464
+ async function evaluateDefineOptionsValues(params) {
6465
+ const { content, filename, lang, statements } = params;
6466
+ const ms = new MagicString(content);
6467
+ const dir = path.dirname(filename);
6468
+ const tempDir = resolveWevuConfigTempDir(dir);
6469
+ const programPath = statements[0]?.statementPath.parentPath;
6470
+ if (!programPath) return {
6471
+ values: [],
6472
+ dependencies: []
6473
+ };
6474
+ const bodyPaths = programPath?.get("body") ?? [];
6475
+ const macroStatementPaths = statements.map((item) => item.statementPath);
6476
+ const { keptStatementPaths } = collectKeptStatementPaths(programPath, macroStatementPaths);
6477
+ for (const statementPath of keptStatementPaths) {
6478
+ if (!statementPath.isImportDeclaration()) continue;
6479
+ const sourceNode = statementPath.node.source;
6480
+ if (!sourceNode || !t.isStringLiteral(sourceNode)) continue;
6481
+ const originalSource = sourceNode.value;
6482
+ if (!originalSource.startsWith(".")) continue;
6483
+ const next = rewriteRelativeImportSource(originalSource, dir, tempDir);
6484
+ if (typeof sourceNode.start === "number" && typeof sourceNode.end === "number") ms.overwrite(sourceNode.start, sourceNode.end, JSON.stringify(next));
6485
+ }
6486
+ for (const statementPath of macroStatementPaths) {
6487
+ const calleePath = statementPath.get("expression").get("callee");
6488
+ if (calleePath?.isIdentifier() && typeof calleePath.node.start === "number" && typeof calleePath.node.end === "number") ms.overwrite(calleePath.node.start, calleePath.node.end, "__weapp_defineOptions");
6489
+ }
6490
+ for (const statementPath of bodyPaths) {
6491
+ if (keptStatementPaths.has(statementPath)) continue;
6492
+ const start = statementPath.node.start;
6493
+ const end = statementPath.node.end;
6494
+ if (typeof start === "number" && typeof end === "number") ms.remove(start, end);
6495
+ }
6496
+ const extension = resolveScriptSetupExtension(lang);
6497
+ const evalSource = `
6498
+ const __weapp_define_options_values = []
6499
+ const __weapp_defineOptions = (value) => (__weapp_define_options_values.push(value), value)
6500
+ `.trimStart() + ms.toString() + "\nexport default __weapp_define_options_values\n";
6501
+ return await withTempDirLock(tempDir, async () => {
6502
+ await fs.ensureDir(tempDir);
6503
+ const basename = path.basename(filename, path.extname(filename));
6504
+ const unique = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
6505
+ const tempFile = path.join(tempDir, `${basename}.define-options.${unique}.${extension}`);
6506
+ await fs.writeFile(tempFile, evalSource, "utf8");
6507
+ try {
6508
+ const { mod, dependencies } = await bundleRequire({
6509
+ filepath: tempFile,
6510
+ cwd: dir
6511
+ });
6512
+ const exported = mod?.default ?? mod;
6513
+ return {
6514
+ values: Array.isArray(exported) ? exported : [exported],
6515
+ dependencies
6516
+ };
6517
+ } finally {
6518
+ try {
6519
+ await fs.remove(tempFile);
6520
+ } catch {}
6521
+ try {
6522
+ if ((await fs.readdir(tempDir)).length === 0) await fs.remove(tempDir);
6523
+ } catch {}
6524
+ }
6525
+ });
6526
+ }
6527
+ async function resolveDefineOptionsValue(raw) {
6528
+ let next = raw;
6529
+ if (typeof next === "function") next = next();
6530
+ if (next && typeof next.then === "function") next = await next;
6531
+ if (!next || typeof next !== "object" || Array.isArray(next)) throw new Error("defineOptions 的参数最终必须解析为对象。");
6532
+ return next;
6533
+ }
6534
+ /**
6535
+ * 将 defineOptions 的参数内联为静态字面量,允许参数引用局部变量或导入值。
6536
+ */
6537
+ async function inlineScriptSetupDefineOptionsArgs(content, filename, lang) {
6538
+ const { statements } = collectDefineOptionsStatements(content, filename);
6539
+ if (!statements.length) return {
6540
+ code: content,
6541
+ dependencies: []
6542
+ };
6543
+ const { values, dependencies } = await evaluateDefineOptionsValues({
6544
+ content,
6545
+ filename,
6546
+ lang,
6547
+ statements
6548
+ });
6549
+ const ms = new MagicString(content);
6550
+ for (let index = 0; index < statements.length; index += 1) {
6551
+ const argNode = statements[index].argPath?.node;
6552
+ if (!argNode || typeof argNode.start !== "number" || typeof argNode.end !== "number") continue;
6553
+ const literal = serializeStaticValueToExpression(await resolveDefineOptionsValue(values[index]));
6554
+ ms.overwrite(argNode.start, argNode.end, literal);
6555
+ }
6556
+ return {
6557
+ code: ms.toString(),
6558
+ dependencies: dependencies.filter(Boolean)
6559
+ };
6560
+ }
6561
+
6393
6562
  //#endregion
6394
6563
  //#region src/plugins/vue/transform/compileVueFile/parse.ts
6395
6564
  function extractDefineOptionsHash(content) {
@@ -6413,6 +6582,7 @@ function extractDefineOptionsHash(content) {
6413
6582
  async function parseVueFile(source, filename, options) {
6414
6583
  const normalizedInputSource = normalizeLineEndings(source);
6415
6584
  const normalizedSource = preprocessScriptSrc(preprocessScriptSetupSrc(normalizedInputSource));
6585
+ let descriptorForCompileSource = normalizedSource;
6416
6586
  const { descriptor, errors } = parse(normalizedSource, {
6417
6587
  filename,
6418
6588
  ignoreEmpty: normalizedSource === normalizedInputSource
@@ -6459,7 +6629,8 @@ async function parseVueFile(source, filename, options) {
6459
6629
  const setupLoc = scriptSetup.loc;
6460
6630
  const startOffset = setupLoc.start.offset;
6461
6631
  const endOffset = setupLoc.end.offset;
6462
- const { descriptor: nextDescriptor, errors: nextErrors } = parse(normalizedSource.slice(0, startOffset) + extracted.stripped + normalizedSource.slice(endOffset), {
6632
+ const nextSource = descriptorForCompileSource.slice(0, startOffset) + extracted.stripped + descriptorForCompileSource.slice(endOffset);
6633
+ const { descriptor: nextDescriptor, errors: nextErrors } = parse(nextSource, {
6463
6634
  filename,
6464
6635
  ignoreEmpty: false
6465
6636
  });
@@ -6478,11 +6649,49 @@ async function parseVueFile(source, filename, options) {
6478
6649
  meta.sfcSrcDeps = sfcSrcDeps;
6479
6650
  }
6480
6651
  } else descriptorForCompile = nextDescriptor;
6652
+ descriptorForCompileSource = nextSource;
6481
6653
  }
6482
6654
  scriptSetupMacroConfig = extracted.config;
6483
6655
  scriptSetupMacroHash = extracted.macroHash;
6484
6656
  defineOptionsHash = extractDefineOptionsHash(scriptSetup.content);
6485
6657
  }
6658
+ const compileScriptSetup = descriptorForCompile.scriptSetup;
6659
+ if (compileScriptSetup?.content && /\bdefineOptions\s*\(/.test(compileScriptSetup.content)) {
6660
+ const inlined = await inlineScriptSetupDefineOptionsArgs(compileScriptSetup.content, filename, compileScriptSetup.lang);
6661
+ if (inlined.code !== compileScriptSetup.content) if (compileScriptSetup.src) descriptorForCompile = {
6662
+ ...descriptorForCompile,
6663
+ scriptSetup: {
6664
+ ...compileScriptSetup,
6665
+ content: inlined.code
6666
+ }
6667
+ };
6668
+ else {
6669
+ const setupLoc = compileScriptSetup.loc;
6670
+ const startOffset = setupLoc.start.offset;
6671
+ const endOffset = setupLoc.end.offset;
6672
+ const nextSource = descriptorForCompileSource.slice(0, startOffset) + inlined.code + descriptorForCompileSource.slice(endOffset);
6673
+ const { descriptor: nextDescriptor, errors: nextErrors } = parse(nextSource, {
6674
+ filename,
6675
+ ignoreEmpty: false
6676
+ });
6677
+ restoreScriptSetupSrc(nextDescriptor);
6678
+ restoreScriptSrc(nextDescriptor);
6679
+ if (nextErrors.length > 0) {
6680
+ const error = nextErrors[0];
6681
+ throw new Error(`解析 ${filename} 失败:${error.message}`);
6682
+ }
6683
+ if (options?.sfcSrc) {
6684
+ const resolvedNext = await resolveSfcBlockSrc(nextDescriptor, filename, options.sfcSrc);
6685
+ descriptorForCompile = resolvedNext.descriptor;
6686
+ if (resolvedNext.deps.length) {
6687
+ const deps = new Set([...sfcSrcDeps ?? [], ...resolvedNext.deps]);
6688
+ sfcSrcDeps = Array.from(deps);
6689
+ meta.sfcSrcDeps = sfcSrcDeps;
6690
+ }
6691
+ } else descriptorForCompile = nextDescriptor;
6692
+ descriptorForCompileSource = nextSource;
6693
+ }
6694
+ }
6486
6695
  const isAppFile = /[\\/]app\.vue$/.test(filename);
6487
6696
  return {
6488
6697
  descriptor: resolvedDescriptor,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wevu/compiler",
3
3
  "type": "module",
4
- "version": "6.6.15",
4
+ "version": "6.6.16",
5
5
  "description": "wevu 编译器基础包,面向小程序模板的编译与转换",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",