@wevu/compiler 6.6.15 → 6.7.0
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.
- package/dist/index.mjs +216 -7
- 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
|
|
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,
|