@wevu/compiler 6.7.4 → 6.7.5
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 +357 -175
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -159,11 +159,12 @@ const RESERVED_VUE_COMPONENT_TAGS = new Set([
|
|
|
159
159
|
"suspense"
|
|
160
160
|
]);
|
|
161
161
|
const VUE_COMPONENT_TAG_RE = /^[A-Z_$][\w$]*$/i;
|
|
162
|
+
const PASCAL_CASE_TAG_RE = /^[A-Z][\w$]*$/;
|
|
162
163
|
/**
|
|
163
164
|
* 判断模板标签是否可能需要自动导入。
|
|
164
165
|
*/
|
|
165
166
|
function isAutoImportCandidateTag(tag) {
|
|
166
|
-
return tag.includes("-") ||
|
|
167
|
+
return tag.includes("-") || PASCAL_CASE_TAG_RE.test(tag);
|
|
167
168
|
}
|
|
168
169
|
/**
|
|
169
170
|
* 收集 Vue 模板中的自定义组件标签。
|
|
@@ -365,12 +366,12 @@ function parseJsLike(source) {
|
|
|
365
366
|
}
|
|
366
367
|
//#endregion
|
|
367
368
|
//#region src/utils/path.ts
|
|
368
|
-
const BACKSLASH_RE$
|
|
369
|
+
const BACKSLASH_RE$4 = /\\/g;
|
|
369
370
|
const LEADING_SLASH_RE = /^[\\/]+/;
|
|
370
371
|
const DUPLICATE_SLASH_RE = /\/{2,}/g;
|
|
371
372
|
const TRIM_SLASH_RE = /^\/+|\/+$/g;
|
|
372
373
|
function toPosixPath(value) {
|
|
373
|
-
return value.replace(BACKSLASH_RE$
|
|
374
|
+
return value.replace(BACKSLASH_RE$4, "/");
|
|
374
375
|
}
|
|
375
376
|
function stripLeadingSlashes(value) {
|
|
376
377
|
return value.replace(LEADING_SLASH_RE, "");
|
|
@@ -513,7 +514,7 @@ const __weapp_defineThemeJson = (config) => (__weapp_json_macro_values.push(conf
|
|
|
513
514
|
if (typeof next === "function") next = next();
|
|
514
515
|
if (next && typeof next.then === "function") next = await next;
|
|
515
516
|
if (!next || typeof next !== "object" || Array.isArray(next)) throw new Error("宏的返回值必须解析为对象。");
|
|
516
|
-
if (Object.
|
|
517
|
+
if (Object.hasOwn(next, "$schema")) delete next.$schema;
|
|
517
518
|
if (options?.merge) {
|
|
518
519
|
const merged = options.merge(accumulator, next);
|
|
519
520
|
if (merged && typeof merged === "object" && !Array.isArray(merged)) accumulator = merged;
|
|
@@ -568,7 +569,7 @@ function collectMacroCallPaths(ast, filename) {
|
|
|
568
569
|
};
|
|
569
570
|
}
|
|
570
571
|
function assertSingleMacro(macroNames, filename) {
|
|
571
|
-
if (macroNames.size > 1) throw new Error(`同一个 <script setup> 仅能使用 ${
|
|
572
|
+
if (macroNames.size > 1) throw new Error(`同一个 <script setup> 仅能使用 ${[...JSON_MACROS].join(", ")} 中的一个(${filename})。`);
|
|
572
573
|
return macroNames.values().next().value;
|
|
573
574
|
}
|
|
574
575
|
function findProgramPath(ast) {
|
|
@@ -734,7 +735,7 @@ function getObjectPropertyByKey$2(node, key) {
|
|
|
734
735
|
return null;
|
|
735
736
|
}
|
|
736
737
|
function buildInjectedFeaturesObject(enabled) {
|
|
737
|
-
return t.objectExpression(Array.from(enabled
|
|
738
|
+
return t.objectExpression(Array.from(enabled, (key) => {
|
|
738
739
|
return t.objectProperty(t.identifier(key), t.booleanLiteral(true));
|
|
739
740
|
}));
|
|
740
741
|
}
|
|
@@ -808,7 +809,7 @@ function collectWevuPageFeatureFlags(ast) {
|
|
|
808
809
|
*/
|
|
809
810
|
function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject, enabled) {
|
|
810
811
|
if (!enabled.size) return false;
|
|
811
|
-
const expectedKeys =
|
|
812
|
+
const expectedKeys = [...enabled];
|
|
812
813
|
const existingFeaturesProp = getObjectPropertyByKey$2(optionsObject, "features");
|
|
813
814
|
let changed = false;
|
|
814
815
|
if (!existingFeaturesProp) {
|
|
@@ -2076,7 +2077,7 @@ function stripVirtualHostFromDefaults(defaults) {
|
|
|
2076
2077
|
const next = { ...defaults };
|
|
2077
2078
|
const options = next.options;
|
|
2078
2079
|
if (!isPlainRecord(options)) return next;
|
|
2079
|
-
if (!Object.
|
|
2080
|
+
if (!Object.hasOwn(options, "virtualHost")) return next;
|
|
2080
2081
|
const copiedOptions = { ...options };
|
|
2081
2082
|
delete copiedOptions.virtualHost;
|
|
2082
2083
|
if (Object.keys(copiedOptions).length > 0) next.options = copiedOptions;
|
|
@@ -2269,6 +2270,110 @@ function injectInlineExpressions(componentExpr, inlineExpressions) {
|
|
|
2269
2270
|
return false;
|
|
2270
2271
|
}
|
|
2271
2272
|
//#endregion
|
|
2273
|
+
//#region src/plugins/vue/transform/transformScript/rewrite/setupInitialData.ts
|
|
2274
|
+
function unwrapExpression(node) {
|
|
2275
|
+
if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node) || t.isTypeCastExpression(node) || t.isParenthesizedExpression(node)) return unwrapExpression(node.expression);
|
|
2276
|
+
return node;
|
|
2277
|
+
}
|
|
2278
|
+
function resolveSetupFunction(componentOptionsObject) {
|
|
2279
|
+
for (const prop of componentOptionsObject.properties) {
|
|
2280
|
+
if (t.isObjectMethod(prop) && !prop.computed && isStaticObjectKeyMatch(prop.key, "setup")) return prop;
|
|
2281
|
+
if (!t.isObjectProperty(prop) || prop.computed || !isStaticObjectKeyMatch(prop.key, "setup")) continue;
|
|
2282
|
+
const value = unwrapExpression(prop.value);
|
|
2283
|
+
if (t.isFunctionExpression(value) || t.isArrowFunctionExpression(value)) return value;
|
|
2284
|
+
}
|
|
2285
|
+
return null;
|
|
2286
|
+
}
|
|
2287
|
+
function isComponentMetaObject(node) {
|
|
2288
|
+
return node.properties.some((prop) => {
|
|
2289
|
+
return t.isObjectProperty(prop) && !prop.computed && isStaticObjectKeyMatch(prop.key, "__weappViteUsingComponent") && t.isBooleanLiteral(prop.value, { value: true });
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2292
|
+
function isSerializableSeed(node) {
|
|
2293
|
+
const normalized = unwrapExpression(node);
|
|
2294
|
+
if (t.isStringLiteral(normalized) || t.isNumericLiteral(normalized) || t.isBooleanLiteral(normalized) || t.isNullLiteral(normalized)) return true;
|
|
2295
|
+
if (t.isTemplateLiteral(normalized)) return normalized.expressions.length === 0;
|
|
2296
|
+
if (t.isArrayExpression(normalized)) return normalized.elements.every((element) => !!element && !t.isSpreadElement(element) && isSerializableSeed(element));
|
|
2297
|
+
if (t.isObjectExpression(normalized)) {
|
|
2298
|
+
if (isComponentMetaObject(normalized)) return false;
|
|
2299
|
+
return normalized.properties.every((prop) => {
|
|
2300
|
+
return t.isObjectProperty(prop) && !prop.computed && !t.isPatternLike(prop.value) && isSerializableSeed(prop.value);
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2305
|
+
function extractSeedExpression(node) {
|
|
2306
|
+
const normalized = unwrapExpression(node);
|
|
2307
|
+
if (t.isCallExpression(normalized) && t.isIdentifier(normalized.callee) && [
|
|
2308
|
+
"ref",
|
|
2309
|
+
"shallowRef",
|
|
2310
|
+
"reactive"
|
|
2311
|
+
].includes(normalized.callee.name)) {
|
|
2312
|
+
const firstArg = normalized.arguments[0];
|
|
2313
|
+
if (firstArg && !t.isSpreadElement(firstArg) && t.isExpression(firstArg) && isSerializableSeed(firstArg)) return t.cloneNode(unwrapExpression(firstArg), true);
|
|
2314
|
+
return null;
|
|
2315
|
+
}
|
|
2316
|
+
if (!isSerializableSeed(normalized)) return null;
|
|
2317
|
+
return t.cloneNode(normalized, true);
|
|
2318
|
+
}
|
|
2319
|
+
function collectSetupInitializers(setupBody) {
|
|
2320
|
+
const initializers = /* @__PURE__ */ new Map();
|
|
2321
|
+
for (const statement of setupBody.body) {
|
|
2322
|
+
if (!t.isVariableDeclaration(statement)) continue;
|
|
2323
|
+
for (const declarator of statement.declarations) {
|
|
2324
|
+
if (!t.isIdentifier(declarator.id) || !declarator.init || !t.isExpression(declarator.init)) continue;
|
|
2325
|
+
initializers.set(declarator.id.name, declarator.init);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
return initializers;
|
|
2329
|
+
}
|
|
2330
|
+
function resolveReturnedObjectExpression(setupBody, initializers) {
|
|
2331
|
+
for (let index = setupBody.body.length - 1; index >= 0; index -= 1) {
|
|
2332
|
+
const statement = setupBody.body[index];
|
|
2333
|
+
if (!t.isReturnStatement(statement) || !statement.argument || !t.isExpression(statement.argument)) continue;
|
|
2334
|
+
const returned = unwrapExpression(statement.argument);
|
|
2335
|
+
if (t.isObjectExpression(returned)) return returned;
|
|
2336
|
+
if (t.isIdentifier(returned)) {
|
|
2337
|
+
const initializer = initializers.get(returned.name);
|
|
2338
|
+
if (initializer) {
|
|
2339
|
+
const normalized = unwrapExpression(initializer);
|
|
2340
|
+
if (t.isObjectExpression(normalized)) return normalized;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
return null;
|
|
2345
|
+
}
|
|
2346
|
+
function resolvePropertyName(node) {
|
|
2347
|
+
if (t.isIdentifier(node.key) && !node.computed) return node.key.name;
|
|
2348
|
+
if (t.isStringLiteral(node.key) && !node.computed) return node.key.value;
|
|
2349
|
+
return null;
|
|
2350
|
+
}
|
|
2351
|
+
function injectSetupInitialData(componentOptionsObject) {
|
|
2352
|
+
if (getObjectPropertyByKey$1(componentOptionsObject, "data")) return false;
|
|
2353
|
+
const setupFn = resolveSetupFunction(componentOptionsObject);
|
|
2354
|
+
if (!setupFn || !t.isBlockStatement(setupFn.body)) return false;
|
|
2355
|
+
const initializers = collectSetupInitializers(setupFn.body);
|
|
2356
|
+
const returnedObject = resolveReturnedObjectExpression(setupFn.body, initializers);
|
|
2357
|
+
if (!returnedObject) return false;
|
|
2358
|
+
const seedProperties = [];
|
|
2359
|
+
for (const prop of returnedObject.properties) {
|
|
2360
|
+
if (!t.isObjectProperty(prop) || prop.computed) continue;
|
|
2361
|
+
const propertyName = resolvePropertyName(prop);
|
|
2362
|
+
if (!propertyName) continue;
|
|
2363
|
+
let sourceExpression = null;
|
|
2364
|
+
if (prop.shorthand && t.isIdentifier(prop.value)) sourceExpression = initializers.get(prop.value.name) ?? null;
|
|
2365
|
+
else if (t.isIdentifier(prop.value)) sourceExpression = initializers.get(prop.value.name) ?? prop.value;
|
|
2366
|
+
else if (t.isExpression(prop.value)) sourceExpression = prop.value;
|
|
2367
|
+
if (!sourceExpression) continue;
|
|
2368
|
+
const seedExpression = extractSeedExpression(sourceExpression);
|
|
2369
|
+
if (!seedExpression) continue;
|
|
2370
|
+
seedProperties.push(t.objectProperty(createStaticObjectKey(propertyName), seedExpression));
|
|
2371
|
+
}
|
|
2372
|
+
if (!seedProperties.length) return false;
|
|
2373
|
+
componentOptionsObject.properties.unshift(t.objectMethod("method", createStaticObjectKey("data"), [], t.blockStatement([t.returnStatement(t.objectExpression(seedProperties))])));
|
|
2374
|
+
return true;
|
|
2375
|
+
}
|
|
2376
|
+
//#endregion
|
|
2272
2377
|
//#region src/plugins/vue/transform/transformScript/rewrite/templateRefs.ts
|
|
2273
2378
|
function buildTemplateRefEntry(binding) {
|
|
2274
2379
|
const props = [t.objectProperty(t.identifier("selector"), t.stringLiteral(binding.selector)), t.objectProperty(t.identifier("inFor"), t.booleanLiteral(binding.inFor))];
|
|
@@ -2331,7 +2436,7 @@ function resolveObjectExpressionFromProgram(program, name) {
|
|
|
2331
2436
|
const normalized = unwrapTypeLikeExpression(declarator.init);
|
|
2332
2437
|
if (t.isObjectExpression(normalized)) return normalized;
|
|
2333
2438
|
if (t.isCallExpression(normalized) && isObjectAssignCall(normalized)) {
|
|
2334
|
-
const lastArg = normalized.arguments
|
|
2439
|
+
const lastArg = normalized.arguments.at(-1);
|
|
2335
2440
|
if (lastArg && !t.isSpreadElement(lastArg) && t.isExpression(lastArg)) {
|
|
2336
2441
|
const lastNormalized = unwrapTypeLikeExpression(lastArg);
|
|
2337
2442
|
if (t.isObjectExpression(lastNormalized)) return lastNormalized;
|
|
@@ -2387,6 +2492,7 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
|
|
|
2387
2492
|
parsedWevuDefaults,
|
|
2388
2493
|
options
|
|
2389
2494
|
}) || transformed;
|
|
2495
|
+
if (componentOptionsObject) transformed = injectSetupInitialData(componentOptionsObject) || transformed;
|
|
2390
2496
|
const classStyleBindings = options?.classStyleBindings ?? [];
|
|
2391
2497
|
if (classStyleBindings.length) if (componentOptionsObject) {
|
|
2392
2498
|
ensureClassStyleRuntimeImports(ast.program);
|
|
@@ -2507,16 +2613,21 @@ function lowerOptionalChain(node) {
|
|
|
2507
2613
|
if (!chain) return t.cloneNode(node);
|
|
2508
2614
|
const segments = [chain.base];
|
|
2509
2615
|
for (const operation of chain.operations) {
|
|
2510
|
-
const currentBase = t.cloneNode(segments
|
|
2616
|
+
const currentBase = t.cloneNode(segments.at(-1));
|
|
2511
2617
|
segments.push(applyOptionalChainOperation(currentBase, operation));
|
|
2512
2618
|
}
|
|
2513
|
-
let lowered = t.cloneNode(segments
|
|
2619
|
+
let lowered = t.cloneNode(segments.at(-1));
|
|
2514
2620
|
for (let index = chain.operations.length - 1; index >= 0; index--) {
|
|
2515
2621
|
if (!chain.operations[index].optional) continue;
|
|
2516
2622
|
lowered = t.conditionalExpression(t.binaryExpression("==", t.cloneNode(segments[index]), t.nullLiteral()), t.identifier("undefined"), lowered);
|
|
2517
2623
|
}
|
|
2518
2624
|
return lowered;
|
|
2519
2625
|
}
|
|
2626
|
+
const TEMPLATE_INTERPOLATION_RE = /\$\{([^}]+)\}/g;
|
|
2627
|
+
const EMPTY_STRING_CONCAT_LEFT_RE = /'\s*\+\s*''/g;
|
|
2628
|
+
const EMPTY_STRING_CONCAT_RIGHT_RE = /''\s*\+\s*'/g;
|
|
2629
|
+
const LEADING_EMPTY_CONCAT_RE = /^\s*''\s*\+\s*/g;
|
|
2630
|
+
const TRAILING_EMPTY_CONCAT_RE = /\s*\+\s*''\s*$/g;
|
|
2520
2631
|
function normalizeWxmlExpression(exp) {
|
|
2521
2632
|
if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.")) return exp;
|
|
2522
2633
|
try {
|
|
@@ -2554,9 +2665,9 @@ function normalizeWxmlExpression(exp) {
|
|
|
2554
2665
|
return generateExpression(normalized);
|
|
2555
2666
|
} catch {
|
|
2556
2667
|
if (exp.startsWith("`") && exp.endsWith("`")) {
|
|
2557
|
-
let rewritten = `'${exp.slice(1, -1).replace(
|
|
2558
|
-
rewritten = rewritten.replace(
|
|
2559
|
-
rewritten = rewritten.replace(
|
|
2668
|
+
let rewritten = `'${exp.slice(1, -1).replace(TEMPLATE_INTERPOLATION_RE, "' + ($1) + '")}'`;
|
|
2669
|
+
rewritten = rewritten.replace(EMPTY_STRING_CONCAT_LEFT_RE, "'").replace(EMPTY_STRING_CONCAT_RIGHT_RE, "'");
|
|
2670
|
+
rewritten = rewritten.replace(LEADING_EMPTY_CONCAT_RE, "").replace(TRAILING_EMPTY_CONCAT_RE, "");
|
|
2560
2671
|
return rewritten;
|
|
2561
2672
|
}
|
|
2562
2673
|
return exp;
|
|
@@ -2583,8 +2694,9 @@ function escapeText(value) {
|
|
|
2583
2694
|
function escapeAttr(value) {
|
|
2584
2695
|
return value.replace(ESCAPED_ATTR_RE, (ch) => ESCAPED_ATTR_MAP[ch] || ch);
|
|
2585
2696
|
}
|
|
2697
|
+
const WHITESPACE_RE = /\s+/g;
|
|
2586
2698
|
function normalizeJsxText(value) {
|
|
2587
|
-
return value.replace(
|
|
2699
|
+
return value.replace(WHITESPACE_RE, " ");
|
|
2588
2700
|
}
|
|
2589
2701
|
function printExpression(exp) {
|
|
2590
2702
|
return generate(exp).code;
|
|
@@ -2795,8 +2907,9 @@ function toOnEventName(eventName) {
|
|
|
2795
2907
|
if (!eventName) return "on";
|
|
2796
2908
|
return `on${(eventName[0] ?? "").toUpperCase()}${eventName.slice(1)}`;
|
|
2797
2909
|
}
|
|
2910
|
+
const EVENT_BINDING_PREFIX_RE$3 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2798
2911
|
function parseEventBinding$3(eventName) {
|
|
2799
|
-
const prefixed =
|
|
2912
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$3.exec(eventName);
|
|
2800
2913
|
if (prefixed) return {
|
|
2801
2914
|
prefix: prefixed[1],
|
|
2802
2915
|
name: prefixed[2]
|
|
@@ -2863,8 +2976,9 @@ const eventMap$2 = {
|
|
|
2863
2976
|
longtap: "longtap",
|
|
2864
2977
|
longpress: "longpress"
|
|
2865
2978
|
};
|
|
2979
|
+
const EVENT_BINDING_PREFIX_RE$2 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2866
2980
|
function parseEventBinding$2(eventName) {
|
|
2867
|
-
const prefixed =
|
|
2981
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$2.exec(eventName);
|
|
2868
2982
|
if (prefixed) return {
|
|
2869
2983
|
prefix: prefixed[1],
|
|
2870
2984
|
name: prefixed[2]
|
|
@@ -2929,8 +3043,9 @@ const eventMap$1 = {
|
|
|
2929
3043
|
longtap: "longtap",
|
|
2930
3044
|
longpress: "longpress"
|
|
2931
3045
|
};
|
|
3046
|
+
const EVENT_BINDING_PREFIX_RE$1 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2932
3047
|
function parseEventBinding$1(eventName) {
|
|
2933
|
-
const prefixed =
|
|
3048
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$1.exec(eventName);
|
|
2934
3049
|
if (prefixed) return {
|
|
2935
3050
|
prefix: prefixed[1],
|
|
2936
3051
|
name: prefixed[2]
|
|
@@ -2995,8 +3110,9 @@ const eventMap = {
|
|
|
2995
3110
|
longtap: "longtap",
|
|
2996
3111
|
longpress: "longpress"
|
|
2997
3112
|
};
|
|
3113
|
+
const EVENT_BINDING_PREFIX_RE = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2998
3114
|
function parseEventBinding(eventName) {
|
|
2999
|
-
const prefixed =
|
|
3115
|
+
const prefixed = EVENT_BINDING_PREFIX_RE.exec(eventName);
|
|
3000
3116
|
if (prefixed) return {
|
|
3001
3117
|
prefix: prefixed[1],
|
|
3002
3118
|
name: prefixed[2]
|
|
@@ -3072,19 +3188,47 @@ function resolveRenderExpression(componentExpr, context) {
|
|
|
3072
3188
|
}
|
|
3073
3189
|
return resolveRenderableExpression(renderNode);
|
|
3074
3190
|
}
|
|
3075
|
-
|
|
3191
|
+
/**
|
|
3192
|
+
* 单次遍历同时收集导入组件信息和默认导出表达式,避免多次 traverse 开销。
|
|
3193
|
+
*/
|
|
3194
|
+
function collectImportsAndExportDefault(ast) {
|
|
3076
3195
|
const defineComponentAliases = new Set(["defineComponent", "_defineComponent"]);
|
|
3077
3196
|
const defineComponentDecls = /* @__PURE__ */ new Map();
|
|
3197
|
+
const imports = /* @__PURE__ */ new Map();
|
|
3078
3198
|
let exportDefaultExpression = null;
|
|
3079
3199
|
traverse(ast, {
|
|
3080
3200
|
ImportDeclaration(path) {
|
|
3081
3201
|
const source = path.node.source.value;
|
|
3082
|
-
if (source
|
|
3083
|
-
for (const specifier of path.node.specifiers) {
|
|
3202
|
+
if (source === "wevu" || source === "vue") for (const specifier of path.node.specifiers) {
|
|
3084
3203
|
if (!t.isImportSpecifier(specifier)) continue;
|
|
3085
3204
|
if (!t.isIdentifier(specifier.imported, { name: "defineComponent" })) continue;
|
|
3086
3205
|
defineComponentAliases.add(specifier.local.name);
|
|
3087
3206
|
}
|
|
3207
|
+
if (path.node.importKind === "type") return;
|
|
3208
|
+
if (!t.isStringLiteral(path.node.source)) return;
|
|
3209
|
+
const importSource = path.node.source.value;
|
|
3210
|
+
for (const specifier of path.node.specifiers) {
|
|
3211
|
+
if ("importKind" in specifier && specifier.importKind === "type") continue;
|
|
3212
|
+
if (!("local" in specifier) || !t.isIdentifier(specifier.local)) continue;
|
|
3213
|
+
const localName = specifier.local.name;
|
|
3214
|
+
if (t.isImportDefaultSpecifier(specifier)) {
|
|
3215
|
+
imports.set(localName, {
|
|
3216
|
+
localName,
|
|
3217
|
+
importSource,
|
|
3218
|
+
importedName: "default",
|
|
3219
|
+
kind: "default"
|
|
3220
|
+
});
|
|
3221
|
+
continue;
|
|
3222
|
+
}
|
|
3223
|
+
if (!t.isImportSpecifier(specifier)) continue;
|
|
3224
|
+
const importedName = t.isIdentifier(specifier.imported) ? specifier.imported.name : t.isStringLiteral(specifier.imported) ? specifier.imported.value : void 0;
|
|
3225
|
+
imports.set(localName, {
|
|
3226
|
+
localName,
|
|
3227
|
+
importSource,
|
|
3228
|
+
importedName,
|
|
3229
|
+
kind: "named"
|
|
3230
|
+
});
|
|
3231
|
+
}
|
|
3088
3232
|
},
|
|
3089
3233
|
VariableDeclarator(path) {
|
|
3090
3234
|
if (!t.isIdentifier(path.node.id) || !path.node.init) return;
|
|
@@ -3104,120 +3248,122 @@ function findExportDefaultExpression(ast) {
|
|
|
3104
3248
|
exportDefaultExpression = resolveComponentExpression(declaration, defineComponentDecls, defineComponentAliases);
|
|
3105
3249
|
}
|
|
3106
3250
|
});
|
|
3107
|
-
return
|
|
3251
|
+
return {
|
|
3252
|
+
importedComponents: [...imports.values()],
|
|
3253
|
+
exportDefaultExpression
|
|
3254
|
+
};
|
|
3108
3255
|
}
|
|
3109
3256
|
function isCollectableJsxTemplateTag(tag) {
|
|
3110
3257
|
if (!tag) return false;
|
|
3111
3258
|
if (RESERVED_VUE_COMPONENT_TAGS.has(tag)) return false;
|
|
3112
3259
|
return !isBuiltinComponent(tag);
|
|
3113
3260
|
}
|
|
3261
|
+
/**
|
|
3262
|
+
* 递归收集 JSX 表达式中的自定义组件标签名。
|
|
3263
|
+
* 直接遍历 AST 节点,无需 cloneNode 和 Babel traverse。
|
|
3264
|
+
*/
|
|
3114
3265
|
function collectJsxTemplateTags(renderExpression) {
|
|
3115
3266
|
const tags = /* @__PURE__ */ new Set();
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
} });
|
|
3125
|
-
return tags;
|
|
3126
|
-
}
|
|
3127
|
-
function collectImportedComponents(ast) {
|
|
3128
|
-
const imports = /* @__PURE__ */ new Map();
|
|
3129
|
-
traverse(ast, { ImportDeclaration(path) {
|
|
3130
|
-
if (path.node.importKind === "type") return;
|
|
3131
|
-
if (!t.isStringLiteral(path.node.source)) return;
|
|
3132
|
-
const importSource = path.node.source.value;
|
|
3133
|
-
for (const specifier of path.node.specifiers) {
|
|
3134
|
-
if ("importKind" in specifier && specifier.importKind === "type") continue;
|
|
3135
|
-
if (!("local" in specifier) || !t.isIdentifier(specifier.local)) continue;
|
|
3136
|
-
const localName = specifier.local.name;
|
|
3137
|
-
if (t.isImportDefaultSpecifier(specifier)) {
|
|
3138
|
-
imports.set(localName, {
|
|
3139
|
-
localName,
|
|
3140
|
-
importSource,
|
|
3141
|
-
importedName: "default",
|
|
3142
|
-
kind: "default"
|
|
3143
|
-
});
|
|
3144
|
-
continue;
|
|
3267
|
+
function walk(node) {
|
|
3268
|
+
if (t.isJSXElement(node)) {
|
|
3269
|
+
const { name } = node.openingElement;
|
|
3270
|
+
if (!t.isJSXMemberExpression(name)) {
|
|
3271
|
+
let tag = null;
|
|
3272
|
+
if (t.isJSXIdentifier(name)) tag = name.name;
|
|
3273
|
+
else if (t.isJSXNamespacedName(name)) tag = `${name.namespace.name}:${name.name.name}`;
|
|
3274
|
+
if (tag && isCollectableJsxTemplateTag(tag)) tags.add(tag);
|
|
3145
3275
|
}
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
imports.set(localName, {
|
|
3149
|
-
localName,
|
|
3150
|
-
importSource,
|
|
3151
|
-
importedName,
|
|
3152
|
-
kind: "named"
|
|
3153
|
-
});
|
|
3276
|
+
for (const child of node.children) walk(child);
|
|
3277
|
+
return;
|
|
3154
3278
|
}
|
|
3155
|
-
|
|
3156
|
-
|
|
3279
|
+
if (t.isJSXFragment(node)) {
|
|
3280
|
+
for (const child of node.children) walk(child);
|
|
3281
|
+
return;
|
|
3282
|
+
}
|
|
3283
|
+
if (t.isJSXExpressionContainer(node) && !t.isJSXEmptyExpression(node.expression)) {
|
|
3284
|
+
walk(node.expression);
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
if (t.isConditionalExpression(node)) {
|
|
3288
|
+
walk(node.consequent);
|
|
3289
|
+
walk(node.alternate);
|
|
3290
|
+
return;
|
|
3291
|
+
}
|
|
3292
|
+
if (t.isLogicalExpression(node)) {
|
|
3293
|
+
walk(node.left);
|
|
3294
|
+
walk(node.right);
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
if (t.isCallExpression(node)) {
|
|
3298
|
+
for (const arg of node.arguments) if (t.isExpression(arg)) walk(arg);
|
|
3299
|
+
return;
|
|
3300
|
+
}
|
|
3301
|
+
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
3302
|
+
if (t.isBlockStatement(node.body)) {
|
|
3303
|
+
for (const stmt of node.body.body) if (t.isReturnStatement(stmt) && stmt.argument) walk(stmt.argument);
|
|
3304
|
+
} else walk(node.body);
|
|
3305
|
+
return;
|
|
3306
|
+
}
|
|
3307
|
+
if (t.isArrayExpression(node)) {
|
|
3308
|
+
for (const element of node.elements) if (element && t.isExpression(element)) walk(element);
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3311
|
+
if (t.isParenthesizedExpression(node) || t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node)) walk(node.expression);
|
|
3312
|
+
}
|
|
3313
|
+
walk(renderExpression);
|
|
3314
|
+
return tags;
|
|
3157
3315
|
}
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
}
|
|
3171
|
-
const importedComponents = collectImportedComponents(ast);
|
|
3172
|
-
const componentExpr = findExportDefaultExpression(ast);
|
|
3173
|
-
if (!componentExpr) return {
|
|
3174
|
-
templateTags: /* @__PURE__ */ new Set(),
|
|
3175
|
-
importedComponents
|
|
3176
|
-
};
|
|
3177
|
-
const renderExpression = resolveRenderExpression(componentExpr, context);
|
|
3178
|
-
if (!renderExpression) return {
|
|
3179
|
-
templateTags: /* @__PURE__ */ new Set(),
|
|
3180
|
-
importedComponents
|
|
3181
|
-
};
|
|
3316
|
+
/**
|
|
3317
|
+
* 从已解析的 AST 中一次性提取 render 表达式和自动组件上下文。
|
|
3318
|
+
* 内部只调用一次 collectImportsAndExportDefault,避免重复遍历。
|
|
3319
|
+
*/
|
|
3320
|
+
function analyzeJsxAst(ast, context) {
|
|
3321
|
+
const { importedComponents, exportDefaultExpression } = collectImportsAndExportDefault(ast);
|
|
3322
|
+
let renderExpression = null;
|
|
3323
|
+
let templateTags = /* @__PURE__ */ new Set();
|
|
3324
|
+
if (exportDefaultExpression) {
|
|
3325
|
+
renderExpression = resolveRenderExpression(exportDefaultExpression, context);
|
|
3326
|
+
if (renderExpression) templateTags = collectJsxTemplateTags(renderExpression);
|
|
3327
|
+
}
|
|
3182
3328
|
return {
|
|
3183
|
-
|
|
3184
|
-
|
|
3329
|
+
renderExpression,
|
|
3330
|
+
autoComponentContext: {
|
|
3331
|
+
templateTags,
|
|
3332
|
+
importedComponents
|
|
3333
|
+
}
|
|
3185
3334
|
};
|
|
3186
3335
|
}
|
|
3187
|
-
function findJsxRenderExpression(ast, context) {
|
|
3188
|
-
const componentExpr = findExportDefaultExpression(ast);
|
|
3189
|
-
if (!componentExpr) {
|
|
3190
|
-
context.warnings.push("未识别到默认导出组件。");
|
|
3191
|
-
return null;
|
|
3192
|
-
}
|
|
3193
|
-
const renderExpression = resolveRenderExpression(componentExpr, context);
|
|
3194
|
-
if (!renderExpression) return null;
|
|
3195
|
-
return renderExpression;
|
|
3196
|
-
}
|
|
3197
3336
|
//#endregion
|
|
3198
3337
|
//#region src/plugins/jsx/compileJsx/attributes.ts
|
|
3338
|
+
const ON_EVENT_RE = /^on[A-Z]/;
|
|
3339
|
+
const CATCH_EVENT_RE = /^catch[A-Z]/;
|
|
3340
|
+
const CAPTURE_BIND_EVENT_RE = /^captureBind[A-Z]/;
|
|
3341
|
+
const CAPTURE_CATCH_EVENT_RE = /^captureCatch[A-Z]/;
|
|
3342
|
+
const MUT_BIND_EVENT_RE = /^mutBind[A-Z]/;
|
|
3199
3343
|
function isEventBinding(name) {
|
|
3200
|
-
return
|
|
3344
|
+
return ON_EVENT_RE.test(name) || CATCH_EVENT_RE.test(name) || CAPTURE_BIND_EVENT_RE.test(name) || CAPTURE_CATCH_EVENT_RE.test(name) || MUT_BIND_EVENT_RE.test(name);
|
|
3201
3345
|
}
|
|
3346
|
+
const LEADING_UPPER_RE = /^[A-Z]/;
|
|
3347
|
+
const UPPER_CHAR_RE = /[A-Z]/g;
|
|
3202
3348
|
function lowerEventName(name) {
|
|
3203
3349
|
if (!name) return name;
|
|
3204
|
-
return name.replace(
|
|
3350
|
+
return name.replace(LEADING_UPPER_RE, (s) => s.toLowerCase()).replace(UPPER_CHAR_RE, (s) => s.toLowerCase());
|
|
3205
3351
|
}
|
|
3206
3352
|
function toEventBindingName(rawName, context) {
|
|
3207
3353
|
const resolveEvent = (name) => context.platform.mapEventName(lowerEventName(name));
|
|
3208
|
-
if (
|
|
3354
|
+
if (CAPTURE_BIND_EVENT_RE.test(rawName)) {
|
|
3209
3355
|
const eventName = resolveEvent(rawName.slice(11));
|
|
3210
3356
|
return context.platform.eventBindingAttr(`capture-bind:${eventName}`);
|
|
3211
3357
|
}
|
|
3212
|
-
if (
|
|
3358
|
+
if (CAPTURE_CATCH_EVENT_RE.test(rawName)) {
|
|
3213
3359
|
const eventName = resolveEvent(rawName.slice(12));
|
|
3214
3360
|
return context.platform.eventBindingAttr(`capture-catch:${eventName}`);
|
|
3215
3361
|
}
|
|
3216
|
-
if (
|
|
3362
|
+
if (MUT_BIND_EVENT_RE.test(rawName)) {
|
|
3217
3363
|
const eventName = resolveEvent(rawName.slice(7));
|
|
3218
3364
|
return context.platform.eventBindingAttr(`mut-bind:${eventName}`);
|
|
3219
3365
|
}
|
|
3220
|
-
if (
|
|
3366
|
+
if (CATCH_EVENT_RE.test(rawName)) {
|
|
3221
3367
|
const eventName = resolveEvent(rawName.slice(5));
|
|
3222
3368
|
return context.platform.eventBindingAttr(`catch:${eventName}`);
|
|
3223
3369
|
}
|
|
@@ -3417,29 +3563,27 @@ function createJsxCompileContext(options) {
|
|
|
3417
3563
|
scopeStack: []
|
|
3418
3564
|
};
|
|
3419
3565
|
}
|
|
3420
|
-
|
|
3566
|
+
/**
|
|
3567
|
+
* 单次解析同时编译模板和收集自动组件上下文,避免重复 babelParse 和 traverse。
|
|
3568
|
+
*/
|
|
3569
|
+
function compileJsxTemplateAndCollectComponents(source, filename, options) {
|
|
3421
3570
|
const ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
3422
3571
|
const context = createJsxCompileContext(options);
|
|
3423
|
-
const renderExpression =
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
template: void 0,
|
|
3428
|
-
warnings: context.warnings,
|
|
3429
|
-
inlineExpressions: context.inlineExpressions
|
|
3430
|
-
};
|
|
3431
|
-
}
|
|
3572
|
+
const { renderExpression, autoComponentContext } = analyzeJsxAst(ast, context);
|
|
3573
|
+
let template;
|
|
3574
|
+
if (renderExpression) template = compileRenderableExpression(renderExpression, context);
|
|
3575
|
+
else context.warnings = context.warnings.map((message) => message === "未识别到默认导出组件。" ? `未在 ${filename} 中识别到默认导出组件。` : message);
|
|
3432
3576
|
return {
|
|
3433
|
-
template
|
|
3577
|
+
template,
|
|
3434
3578
|
warnings: context.warnings,
|
|
3435
|
-
inlineExpressions: context.inlineExpressions
|
|
3579
|
+
inlineExpressions: context.inlineExpressions,
|
|
3580
|
+
autoComponentContext
|
|
3436
3581
|
};
|
|
3437
3582
|
}
|
|
3438
|
-
function collectJsxAutoComponents(source, filename, options) {
|
|
3439
|
-
return collectJsxAutoComponentContext(source, filename, createJsxCompileContext(options), options?.warn);
|
|
3440
|
-
}
|
|
3441
3583
|
//#endregion
|
|
3442
3584
|
//#region src/plugins/jsx/compileJsxFile.ts
|
|
3585
|
+
const LEADING_DOT_RE = /^\./;
|
|
3586
|
+
const SETUP_CALL_RE$1 = /\bsetup\s*\(/;
|
|
3443
3587
|
/**
|
|
3444
3588
|
* 编译 JSX/TSX 文件,输出 wevu 脚本与 WXML 模板。
|
|
3445
3589
|
*/
|
|
@@ -3453,7 +3597,7 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3453
3597
|
let scriptSource = source;
|
|
3454
3598
|
let scriptMacroConfig;
|
|
3455
3599
|
let scriptMacroHash;
|
|
3456
|
-
const scriptLang = path.extname(filename).replace(
|
|
3600
|
+
const scriptLang = path.extname(filename).replace(LEADING_DOT_RE, "") || void 0;
|
|
3457
3601
|
try {
|
|
3458
3602
|
const extracted = await extractJsonMacroFromScriptSetup(source, filename, scriptLang, { merge: (target, incoming) => mergeJson(target, incoming, "macro") });
|
|
3459
3603
|
scriptSource = extracted.stripped;
|
|
@@ -3463,8 +3607,7 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3463
3607
|
const message = error instanceof Error ? error.message : String(error);
|
|
3464
3608
|
throw new Error(`解析 ${filename} 失败:${message}`);
|
|
3465
3609
|
}
|
|
3466
|
-
const
|
|
3467
|
-
const autoComponentContext = collectJsxAutoComponents(source, filename, options);
|
|
3610
|
+
const { template: compiledTemplateStr, warnings: templateWarnings, inlineExpressions, autoComponentContext } = compileJsxTemplateAndCollectComponents(source, filename, options);
|
|
3468
3611
|
const autoUsingComponentsMap = {};
|
|
3469
3612
|
if (options?.autoUsingComponents?.resolveUsingComponentPath && autoComponentContext.templateTags.size > 0) for (const imported of autoComponentContext.importedComponents) {
|
|
3470
3613
|
if (!autoComponentContext.templateTags.has(imported.localName)) continue;
|
|
@@ -3496,9 +3639,9 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3496
3639
|
isPage: options?.isPage,
|
|
3497
3640
|
warn: options?.warn,
|
|
3498
3641
|
wevuDefaults: options?.wevuDefaults,
|
|
3499
|
-
inlineExpressions
|
|
3642
|
+
inlineExpressions
|
|
3500
3643
|
});
|
|
3501
|
-
if (
|
|
3644
|
+
if (templateWarnings.length && options?.warn) templateWarnings.forEach((message) => options.warn?.(`[JSX 编译] ${message}`));
|
|
3502
3645
|
let configObj;
|
|
3503
3646
|
if (Object.keys(autoUsingComponentsMap).length > 0 || Object.keys(autoImportTagsMap).length > 0) {
|
|
3504
3647
|
const existingRaw = configObj?.usingComponents;
|
|
@@ -3517,23 +3660,24 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3517
3660
|
if (scriptMacroConfig && Object.keys(scriptMacroConfig).length > 0) configObj = mergeJson(configObj ?? {}, scriptMacroConfig, "macro");
|
|
3518
3661
|
return {
|
|
3519
3662
|
script: transformedScript.code,
|
|
3520
|
-
template:
|
|
3663
|
+
template: compiledTemplateStr,
|
|
3521
3664
|
config: configObj && Object.keys(configObj).length > 0 ? JSON.stringify(configObj, null, 2) : void 0,
|
|
3522
3665
|
meta: {
|
|
3523
3666
|
hasScriptSetup: false,
|
|
3524
|
-
hasSetupOption:
|
|
3667
|
+
hasSetupOption: SETUP_CALL_RE$1.test(normalizedScriptSource),
|
|
3525
3668
|
jsonMacroHash: scriptMacroHash
|
|
3526
3669
|
}
|
|
3527
3670
|
};
|
|
3528
3671
|
}
|
|
3529
3672
|
//#endregion
|
|
3530
3673
|
//#region src/utils/text.ts
|
|
3674
|
+
const CRLF_RE = /\r\n?/g;
|
|
3531
3675
|
/**
|
|
3532
3676
|
* 统一文本换行符为 LF,消除不同系统(CRLF/CR/LF)差异。
|
|
3533
3677
|
*/
|
|
3534
3678
|
function normalizeLineEndings(source) {
|
|
3535
3679
|
if (!source.includes("\r")) return source;
|
|
3536
|
-
return source.replace(
|
|
3680
|
+
return source.replace(CRLF_RE, "\n");
|
|
3537
3681
|
}
|
|
3538
3682
|
//#endregion
|
|
3539
3683
|
//#region src/plugins/utils/cache.ts
|
|
@@ -3623,7 +3767,7 @@ function getReadFileCheckMtime(config) {
|
|
|
3623
3767
|
//#endregion
|
|
3624
3768
|
//#region src/utils/viteId.ts
|
|
3625
3769
|
const VUE_VIRTUAL_MODULE_PREFIX = "\0vue:";
|
|
3626
|
-
const BACKSLASH_RE = /\\/g;
|
|
3770
|
+
const BACKSLASH_RE$3 = /\\/g;
|
|
3627
3771
|
function normalizeViteId(id, options) {
|
|
3628
3772
|
const stripQuery = options?.stripQuery !== false;
|
|
3629
3773
|
const fileProtocolToPathEnabled = options?.fileProtocolToPath !== false;
|
|
@@ -3632,7 +3776,7 @@ function normalizeViteId(id, options) {
|
|
|
3632
3776
|
const stripLeadingNullByte = options?.stripLeadingNullByte === true;
|
|
3633
3777
|
let clean = id;
|
|
3634
3778
|
if (stripVueVirtualPrefix && clean.startsWith(VUE_VIRTUAL_MODULE_PREFIX)) clean = clean.slice(5);
|
|
3635
|
-
if (clean.includes("\\")) clean = clean.replace(BACKSLASH_RE, "/");
|
|
3779
|
+
if (clean.includes("\\")) clean = clean.replace(BACKSLASH_RE$3, "/");
|
|
3636
3780
|
if (stripQuery) clean = clean.split("?", 1)[0];
|
|
3637
3781
|
if (fileProtocolToPathEnabled && clean.startsWith("file://")) try {
|
|
3638
3782
|
clean = fileURLToPath(clean);
|
|
@@ -3760,7 +3904,7 @@ async function resolveSfcBlockSrc(descriptor, filename, options) {
|
|
|
3760
3904
|
if (nextDescriptor.styles.length) nextDescriptor.styles = await Promise.all(nextDescriptor.styles.map((style) => resolveBlock(style, "style")));
|
|
3761
3905
|
return {
|
|
3762
3906
|
descriptor: nextDescriptor,
|
|
3763
|
-
deps:
|
|
3907
|
+
deps: [...deps]
|
|
3764
3908
|
};
|
|
3765
3909
|
}
|
|
3766
3910
|
//#endregion
|
|
@@ -3769,14 +3913,17 @@ const sfcParseCache = new LRUCache({ max: 512 });
|
|
|
3769
3913
|
const SCRIPT_SETUP_SRC_ATTR = "data-weapp-vite-src";
|
|
3770
3914
|
const SCRIPT_SRC_ATTR = "data-weapp-vite-script-src";
|
|
3771
3915
|
const SCRIPT_SETUP_TAG_RE = /<script\b([^>]*)>/gi;
|
|
3916
|
+
const SETUP_WORD_RE = /\bsetup\b/i;
|
|
3917
|
+
const SRC_WORD_RE = /\bsrc\b/i;
|
|
3918
|
+
const SRC_ATTR_RE = /\bsrc(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))/i;
|
|
3772
3919
|
/**
|
|
3773
3920
|
* 预处理 `<script setup src>`,避免编译器丢失 src。
|
|
3774
3921
|
*/
|
|
3775
3922
|
function preprocessScriptSetupSrc(source) {
|
|
3776
3923
|
if (!source.includes("<script") || !source.includes("setup") || !source.includes("src")) return source;
|
|
3777
3924
|
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
3778
|
-
if (
|
|
3779
|
-
return `<script${attrs.replace(
|
|
3925
|
+
if (!SETUP_WORD_RE.test(attrs) || !SRC_WORD_RE.test(attrs)) return full;
|
|
3926
|
+
return `<script${attrs.replace(SRC_ATTR_RE, `${SCRIPT_SETUP_SRC_ATTR}$1`)}>`;
|
|
3780
3927
|
});
|
|
3781
3928
|
}
|
|
3782
3929
|
/**
|
|
@@ -3785,8 +3932,8 @@ function preprocessScriptSetupSrc(source) {
|
|
|
3785
3932
|
function preprocessScriptSrc(source) {
|
|
3786
3933
|
if (!source.includes("<script") || !source.includes("src")) return source;
|
|
3787
3934
|
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
3788
|
-
if (
|
|
3789
|
-
return `<script${attrs.replace(
|
|
3935
|
+
if (SETUP_WORD_RE.test(attrs) || !SRC_WORD_RE.test(attrs)) return full;
|
|
3936
|
+
return `<script${attrs.replace(SRC_ATTR_RE, `${SCRIPT_SRC_ATTR}$1`)}>`;
|
|
3790
3937
|
});
|
|
3791
3938
|
}
|
|
3792
3939
|
/**
|
|
@@ -3867,6 +4014,8 @@ function getSfcCheckMtime(config) {
|
|
|
3867
4014
|
}
|
|
3868
4015
|
//#endregion
|
|
3869
4016
|
//#region src/plugins/vue/compiler/style.ts
|
|
4017
|
+
const CSS_RULE_RE = /([^{]+)(\{[^}]*\})/g;
|
|
4018
|
+
const CSS_CLASS_RE = /\.([a-z_][\w-]*)(?:\[[^\]]+\])?\s*\{/gi;
|
|
3870
4019
|
/**
|
|
3871
4020
|
* 将 Vue SFC 的 style 块转换为 WXSS
|
|
3872
4021
|
*/
|
|
@@ -3890,7 +4039,7 @@ function compileVueStyleToWxss(styleBlock, options) {
|
|
|
3890
4039
|
*/
|
|
3891
4040
|
function transformScopedCss(source, id) {
|
|
3892
4041
|
const scopedId = `data-v-${id}`;
|
|
3893
|
-
return source.replace(
|
|
4042
|
+
return source.replace(CSS_RULE_RE, (match, selector, rules) => {
|
|
3894
4043
|
const trimmedSelector = selector.trim();
|
|
3895
4044
|
if (!trimmedSelector) return match;
|
|
3896
4045
|
if (trimmedSelector.includes("[") || trimmedSelector.includes(":deep(") || trimmedSelector.includes(":slotted(")) return match;
|
|
@@ -3906,7 +4055,7 @@ function transformScopedCss(source, id) {
|
|
|
3906
4055
|
function transformCssModules(source, id) {
|
|
3907
4056
|
const classes = {};
|
|
3908
4057
|
const hash = generateHash(id);
|
|
3909
|
-
const classRegex =
|
|
4058
|
+
const classRegex = new RegExp(CSS_CLASS_RE.source, CSS_CLASS_RE.flags);
|
|
3910
4059
|
const foundClasses = [];
|
|
3911
4060
|
let result = classRegex.exec(source);
|
|
3912
4061
|
while (result !== null) {
|
|
@@ -4200,10 +4349,10 @@ function getClassStyleWxsSource(options = {}) {
|
|
|
4200
4349
|
}
|
|
4201
4350
|
//#endregion
|
|
4202
4351
|
//#region src/plugins/vue/compiler/template/elements/forExpression.ts
|
|
4203
|
-
const IDENTIFIER_RE$
|
|
4352
|
+
const IDENTIFIER_RE$4 = /^[A-Z_$][\w$]*$/i;
|
|
4204
4353
|
const FOR_ITEM_ALIAS_PLACEHOLDER = "__wv_for_item__";
|
|
4205
4354
|
function isIdentifier(value) {
|
|
4206
|
-
return IDENTIFIER_RE$
|
|
4355
|
+
return IDENTIFIER_RE$4.test(value);
|
|
4207
4356
|
}
|
|
4208
4357
|
function splitTopLevelByComma(input) {
|
|
4209
4358
|
const out = [];
|
|
@@ -4477,12 +4626,17 @@ function withSlotProps(context, mapping, fn) {
|
|
|
4477
4626
|
popSlotProps(context);
|
|
4478
4627
|
}
|
|
4479
4628
|
}
|
|
4629
|
+
const IDENTIFIER_RE$3 = /^[A-Z_$][\w$]*$/i;
|
|
4630
|
+
const BACKSLASH_RE$2 = /\\/g;
|
|
4631
|
+
const SINGLE_QUOTE_RE$2 = /'/g;
|
|
4632
|
+
const CR_RE$1 = /\r/g;
|
|
4633
|
+
const LF_RE$1 = /\n/g;
|
|
4480
4634
|
function collectScopePropMapping(context) {
|
|
4481
4635
|
const mapping = {};
|
|
4482
4636
|
if (!context.slotMultipleInstance) return mapping;
|
|
4483
4637
|
for (const scope of context.scopeStack) for (const name of scope) {
|
|
4484
|
-
if (
|
|
4485
|
-
if (!Object.
|
|
4638
|
+
if (!IDENTIFIER_RE$3.test(name)) continue;
|
|
4639
|
+
if (!Object.hasOwn(mapping, name)) mapping[name] = name;
|
|
4486
4640
|
}
|
|
4487
4641
|
return mapping;
|
|
4488
4642
|
}
|
|
@@ -4493,7 +4647,7 @@ function buildScopePropsExpression(context) {
|
|
|
4493
4647
|
return `[${keys.map((key) => `${toWxmlStringLiteral$1(key)},${key}`).join(",")}]`;
|
|
4494
4648
|
}
|
|
4495
4649
|
function toWxmlStringLiteral$1(value) {
|
|
4496
|
-
return `'${value.replace(
|
|
4650
|
+
return `'${value.replace(BACKSLASH_RE$2, "\\\\").replace(SINGLE_QUOTE_RE$2, "\\'").replace(CR_RE$1, "\\r").replace(LF_RE$1, "\\n")}'`;
|
|
4497
4651
|
}
|
|
4498
4652
|
function hashString(input) {
|
|
4499
4653
|
let hash = 0;
|
|
@@ -4570,6 +4724,7 @@ function replaceIdentifierWithExpression(path, replacement) {
|
|
|
4570
4724
|
}
|
|
4571
4725
|
path.replaceWith(replacement);
|
|
4572
4726
|
}
|
|
4727
|
+
const IDENTIFIER_RE$2 = /^[A-Z_$][\w$]*$/i;
|
|
4573
4728
|
function rewriteScopedSlotExpression(exp, context) {
|
|
4574
4729
|
const normalized = normalizeWxmlExpression(exp);
|
|
4575
4730
|
const parsed = parseBabelExpressionFile(normalized);
|
|
@@ -4580,7 +4735,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4580
4735
|
const forAliases = collectForAliasMapping$2(context);
|
|
4581
4736
|
const createMemberAccess = (target, prop) => {
|
|
4582
4737
|
if (!prop) return t.identifier(target);
|
|
4583
|
-
if (
|
|
4738
|
+
if (IDENTIFIER_RE$2.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
|
|
4584
4739
|
return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
|
|
4585
4740
|
};
|
|
4586
4741
|
traverse(ast, { Identifier(path) {
|
|
@@ -4588,7 +4743,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4588
4743
|
const name = path.node.name;
|
|
4589
4744
|
if (SCOPED_SLOT_GLOBALS.has(name)) return;
|
|
4590
4745
|
if (path.scope.hasBinding(name)) return;
|
|
4591
|
-
if (Object.
|
|
4746
|
+
if (Object.hasOwn(forAliases, name)) {
|
|
4592
4747
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
4593
4748
|
if (aliasExp) {
|
|
4594
4749
|
replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
|
|
@@ -4596,7 +4751,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4596
4751
|
}
|
|
4597
4752
|
}
|
|
4598
4753
|
if (locals.has(name)) return;
|
|
4599
|
-
if (Object.
|
|
4754
|
+
if (Object.hasOwn(slotProps, name)) {
|
|
4600
4755
|
replaceIdentifierWithExpression(path, createMemberAccess("__wvSlotPropsData", slotProps[name]));
|
|
4601
4756
|
return;
|
|
4602
4757
|
}
|
|
@@ -4617,7 +4772,7 @@ function rewriteForAliasExpression(exp, context) {
|
|
|
4617
4772
|
if (!path.isReferencedIdentifier()) return;
|
|
4618
4773
|
const name = path.node.name;
|
|
4619
4774
|
if (path.scope.hasBinding(name)) return;
|
|
4620
|
-
if (!Object.
|
|
4775
|
+
if (!Object.hasOwn(forAliases, name)) return;
|
|
4621
4776
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
4622
4777
|
if (!aliasExp) return;
|
|
4623
4778
|
replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
|
|
@@ -4778,14 +4933,14 @@ const INLINE_GLOBALS = new Set([
|
|
|
4778
4933
|
"ctx",
|
|
4779
4934
|
"scope"
|
|
4780
4935
|
]);
|
|
4781
|
-
const IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
4936
|
+
const IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
|
|
4782
4937
|
const SIMPLE_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
|
|
4783
4938
|
function createMemberAccess$1(target, prop) {
|
|
4784
|
-
if (IDENTIFIER_RE.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
|
|
4939
|
+
if (IDENTIFIER_RE$1.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
|
|
4785
4940
|
return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
|
|
4786
4941
|
}
|
|
4787
4942
|
function resolveSlotPropBinding(slotProps, name) {
|
|
4788
|
-
if (!Object.
|
|
4943
|
+
if (!Object.hasOwn(slotProps, name)) return null;
|
|
4789
4944
|
const prop = slotProps[name];
|
|
4790
4945
|
if (!prop) return "__wvSlotPropsData";
|
|
4791
4946
|
return generateExpression(createMemberAccess$1("__wvSlotPropsData", prop));
|
|
@@ -5015,7 +5170,7 @@ function normalizeJsExpressionWithContext(exp, context, options) {
|
|
|
5015
5170
|
const name = path.node.name;
|
|
5016
5171
|
if (JS_RUNTIME_GLOBALS.has(name)) return;
|
|
5017
5172
|
if (path.scope.hasBinding(name)) return;
|
|
5018
|
-
if (Object.
|
|
5173
|
+
if (Object.hasOwn(forAliases, name)) {
|
|
5019
5174
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
5020
5175
|
if (aliasExp) {
|
|
5021
5176
|
const replacement = t.cloneNode(aliasExp, true);
|
|
@@ -5031,7 +5186,7 @@ function normalizeJsExpressionWithContext(exp, context, options) {
|
|
|
5031
5186
|
}
|
|
5032
5187
|
if (locals.has(name)) return;
|
|
5033
5188
|
let replacement;
|
|
5034
|
-
if (context.rewriteScopedSlot) if (Object.
|
|
5189
|
+
if (context.rewriteScopedSlot) if (Object.hasOwn(slotProps, name)) {
|
|
5035
5190
|
const prop = slotProps[name];
|
|
5036
5191
|
const base = createThisMemberAccess("__wvSlotPropsData");
|
|
5037
5192
|
replacement = createUnrefCall(prop ? createMemberAccess(base, prop) : base);
|
|
@@ -5099,8 +5254,12 @@ function renderMustache(expression, context) {
|
|
|
5099
5254
|
}
|
|
5100
5255
|
//#endregion
|
|
5101
5256
|
//#region src/plugins/vue/compiler/template/attributes.ts
|
|
5257
|
+
const BACKSLASH_RE$1 = /\\/g;
|
|
5258
|
+
const SINGLE_QUOTE_RE$1 = /'/g;
|
|
5259
|
+
const CR_RE = /\r/g;
|
|
5260
|
+
const LF_RE = /\n/g;
|
|
5102
5261
|
function toWxmlStringLiteral(value) {
|
|
5103
|
-
return `'${value.replace(
|
|
5262
|
+
return `'${value.replace(BACKSLASH_RE$1, "\\\\").replace(SINGLE_QUOTE_RE$1, "\\'").replace(CR_RE, "\\r").replace(LF_RE, "\\n")}'`;
|
|
5104
5263
|
}
|
|
5105
5264
|
function cloneForStack(context) {
|
|
5106
5265
|
return context.forStack.map((info) => ({ ...info }));
|
|
@@ -5113,8 +5272,9 @@ function generateExpressionCode(exp) {
|
|
|
5113
5272
|
const { code } = generate(exp, { compact: true });
|
|
5114
5273
|
return code;
|
|
5115
5274
|
}
|
|
5275
|
+
const TRAILING_SEMICOLONS_RE = /;+\s*$/;
|
|
5116
5276
|
function normalizeStyleFallbackValue(value) {
|
|
5117
|
-
return value.trim().replace(
|
|
5277
|
+
return value.trim().replace(TRAILING_SEMICOLONS_RE, "");
|
|
5118
5278
|
}
|
|
5119
5279
|
function buildStyleErrorFallback(staticValue, shouldHideByDefault) {
|
|
5120
5280
|
const segments = [];
|
|
@@ -5151,7 +5311,10 @@ function shouldPreferJsClassStyleRuntime(exp) {
|
|
|
5151
5311
|
return false;
|
|
5152
5312
|
}
|
|
5153
5313
|
if (t.isConditionalExpression(current)) return visit(current.test) || visit(current.consequent) || visit(current.alternate);
|
|
5154
|
-
if (t.isLogicalExpression(current) || t.isBinaryExpression(current))
|
|
5314
|
+
if (t.isLogicalExpression(current) || t.isBinaryExpression(current)) {
|
|
5315
|
+
if (t.isPrivateName(current.left) || t.isPrivateName(current.right)) return true;
|
|
5316
|
+
return visit(current.left) || visit(current.right);
|
|
5317
|
+
}
|
|
5155
5318
|
if (t.isUnaryExpression(current)) return visit(current.argument);
|
|
5156
5319
|
return true;
|
|
5157
5320
|
};
|
|
@@ -5252,8 +5415,10 @@ function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
|
|
|
5252
5415
|
if (context.mustacheInterpolation === "spaced") return `${argValue}="${renderMustache(expValue, context)}"`;
|
|
5253
5416
|
return `${argValue}="{{ ${expValue} }}"`;
|
|
5254
5417
|
}
|
|
5255
|
-
const
|
|
5256
|
-
const
|
|
5418
|
+
const SIMPLE_IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
|
|
5419
|
+
const SIMPLE_MEMBER_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
|
|
5420
|
+
const isSimpleIdentifier = (value) => SIMPLE_IDENTIFIER_RE$1.test(value);
|
|
5421
|
+
const isSimpleMemberPath = (value) => SIMPLE_MEMBER_PATH_RE.test(value);
|
|
5257
5422
|
function transformBindDirective(node, context, forInfo) {
|
|
5258
5423
|
const { exp, arg } = node;
|
|
5259
5424
|
if (!arg) return null;
|
|
@@ -5298,6 +5463,7 @@ function transformBindDirective(node, context, forInfo) {
|
|
|
5298
5463
|
}
|
|
5299
5464
|
//#endregion
|
|
5300
5465
|
//#region src/plugins/vue/compiler/template/directives/custom.ts
|
|
5466
|
+
const IDENTIFIER_RE = /^[a-z_$][\w$]*$/i;
|
|
5301
5467
|
function transformCustomDirective(name, exp, arg, context) {
|
|
5302
5468
|
if (new Set([
|
|
5303
5469
|
"bind",
|
|
@@ -5317,7 +5483,7 @@ function transformCustomDirective(name, exp, arg, context) {
|
|
|
5317
5483
|
const dataAttrName = `data-v-${name}`;
|
|
5318
5484
|
if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5319
5485
|
const expValue = normalizeWxmlExpressionWithContext(exp.content, context);
|
|
5320
|
-
if (
|
|
5486
|
+
if (IDENTIFIER_RE.test(expValue)) return `${dataAttrName}="${renderMustache(expValue, context)}"`;
|
|
5321
5487
|
return `${dataAttrName}="${renderMustache(expValue, context)}"`;
|
|
5322
5488
|
}
|
|
5323
5489
|
if (arg && arg.type === NodeTypes.SIMPLE_EXPRESSION) return `${dataAttrName}="${arg.content}"`;
|
|
@@ -5333,8 +5499,9 @@ function getElementType(element) {
|
|
|
5333
5499
|
}
|
|
5334
5500
|
return "";
|
|
5335
5501
|
}
|
|
5502
|
+
const QUOTE_RE$1 = /"/g;
|
|
5336
5503
|
function transformVModel(element, expValue, context) {
|
|
5337
|
-
const escapedModel = expValue.replace(
|
|
5504
|
+
const escapedModel = expValue.replace(QUOTE_RE$1, """);
|
|
5338
5505
|
const bindModel = (event) => {
|
|
5339
5506
|
return `${context.platform.eventBindingAttr(event)}="__weapp_vite_model" data-wv-model="${escapedModel}"`;
|
|
5340
5507
|
};
|
|
@@ -5365,21 +5532,25 @@ function transformModelDirective(node, context, elementNode) {
|
|
|
5365
5532
|
}
|
|
5366
5533
|
//#endregion
|
|
5367
5534
|
//#region src/plugins/vue/compiler/template/directives/on.ts
|
|
5368
|
-
const
|
|
5535
|
+
const SIMPLE_IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
5536
|
+
const isSimpleHandler = (value) => SIMPLE_IDENTIFIER_RE.test(value);
|
|
5369
5537
|
function shouldUseDetailPayload(options) {
|
|
5370
5538
|
return options?.isComponent === true;
|
|
5371
5539
|
}
|
|
5540
|
+
const NON_ALNUM_RE = /[^a-z0-9]+/gi;
|
|
5541
|
+
const LEADING_TRAILING_DASH_RE = /^-+|-+$/g;
|
|
5372
5542
|
function normalizeEventDatasetSuffix(eventName) {
|
|
5373
|
-
return eventName.trim().replace(
|
|
5543
|
+
return eventName.trim().replace(NON_ALNUM_RE, "-").replace(LEADING_TRAILING_DASH_RE, "").toLowerCase() || "event";
|
|
5374
5544
|
}
|
|
5545
|
+
const QUOTE_RE = /"/g;
|
|
5375
5546
|
function buildInlineScopeAttrs(scopeBindings, context) {
|
|
5376
5547
|
return scopeBindings.map((binding, index) => {
|
|
5377
|
-
return `data-wv-s${index}="${renderMustache(binding.replace(
|
|
5548
|
+
return `data-wv-s${index}="${renderMustache(binding.replace(QUOTE_RE, """), context)}"`;
|
|
5378
5549
|
});
|
|
5379
5550
|
}
|
|
5380
5551
|
function buildInlineIndexAttrs(indexBindings, context) {
|
|
5381
5552
|
return indexBindings.map((binding, index) => {
|
|
5382
|
-
return `data-wv-i${index}="${renderMustache(binding.replace(
|
|
5553
|
+
return `data-wv-i${index}="${renderMustache(binding.replace(QUOTE_RE, """), context)}"`;
|
|
5383
5554
|
});
|
|
5384
5555
|
}
|
|
5385
5556
|
function resolveEventPrefix(modifiers) {
|
|
@@ -5444,7 +5615,7 @@ function transformOnDirective(node, context, options) {
|
|
|
5444
5615
|
}
|
|
5445
5616
|
if (isInlineExpression) return [
|
|
5446
5617
|
detailAttr,
|
|
5447
|
-
`data-wv-inline-${eventSuffix}="${inlineSource.replace(
|
|
5618
|
+
`data-wv-inline-${eventSuffix}="${inlineSource.replace(QUOTE_RE, """)}"`,
|
|
5448
5619
|
`${bindAttr}="__weapp_vite_inline"`
|
|
5449
5620
|
].filter(Boolean).join(" ");
|
|
5450
5621
|
return [detailAttr, `${bindAttr}="${expValue}"`].filter(Boolean).join(" ");
|
|
@@ -5567,6 +5738,8 @@ function collectElementAttributes(node, context, options) {
|
|
|
5567
5738
|
}
|
|
5568
5739
|
//#endregion
|
|
5569
5740
|
//#region src/plugins/vue/compiler/template/elements/slotProps.ts
|
|
5741
|
+
const BACKSLASH_RE = /\\/g;
|
|
5742
|
+
const SINGLE_QUOTE_RE = /'/g;
|
|
5570
5743
|
function parseSlotPropsExpression(exp, context) {
|
|
5571
5744
|
const trimmed = exp.trim();
|
|
5572
5745
|
if (!trimmed) return {};
|
|
@@ -5638,7 +5811,7 @@ function collectSlotBindingExpression(node, context) {
|
|
|
5638
5811
|
const literal = prop.value?.type === NodeTypes.TEXT ? prop.value.content : "";
|
|
5639
5812
|
if (literal) namedBindings.push({
|
|
5640
5813
|
key: prop.name,
|
|
5641
|
-
value: `'${literal.replace(
|
|
5814
|
+
value: `'${literal.replace(BACKSLASH_RE, "\\\\").replace(SINGLE_QUOTE_RE, "\\'")}'`
|
|
5642
5815
|
});
|
|
5643
5816
|
}
|
|
5644
5817
|
}
|
|
@@ -5959,6 +6132,7 @@ function transformNormalElement(node, context, transformNode) {
|
|
|
5959
6132
|
}
|
|
5960
6133
|
//#endregion
|
|
5961
6134
|
//#region src/plugins/vue/compiler/template/elements/tag-structural.ts
|
|
6135
|
+
const REGEX_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
|
|
5962
6136
|
function resolveConditionExpression$1(rawExpValue, context, hint) {
|
|
5963
6137
|
return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
5964
6138
|
}
|
|
@@ -5995,7 +6169,7 @@ function transformForElement(node, context, transformNode) {
|
|
|
5995
6169
|
const generatedItem = `__wv_item_${context.forIndexSeed++}`;
|
|
5996
6170
|
forInfo.item = generatedItem;
|
|
5997
6171
|
if (forInfo.itemAliases) {
|
|
5998
|
-
const escaped = FOR_ITEM_ALIAS_PLACEHOLDER.replace(
|
|
6172
|
+
const escaped = FOR_ITEM_ALIAS_PLACEHOLDER.replace(REGEX_SPECIAL_CHARS_RE, "\\$&");
|
|
5999
6173
|
const placeholderRE = new RegExp(`\\b${escaped}\\b`, "g");
|
|
6000
6174
|
forInfo.itemAliases = Object.fromEntries(Object.entries(forInfo.itemAliases).map(([alias, expression]) => {
|
|
6001
6175
|
return [alias, expression.replace(placeholderRE, generatedItem)];
|
|
@@ -6046,6 +6220,8 @@ function transformForElement(node, context, transformNode) {
|
|
|
6046
6220
|
}
|
|
6047
6221
|
//#endregion
|
|
6048
6222
|
//#region src/plugins/vue/compiler/template/elements/tag-builtin.ts
|
|
6223
|
+
const TEMPLATE_OPEN_RE = /<template/g;
|
|
6224
|
+
const TEMPLATE_CLOSE_RE = /<\/template>/g;
|
|
6049
6225
|
function resolveConditionExpression(rawExpValue, context, hint) {
|
|
6050
6226
|
return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
6051
6227
|
}
|
|
@@ -6104,7 +6280,7 @@ function transformTemplateElement(node, context, transformNode) {
|
|
|
6104
6280
|
if (dir.name === "else") return context.platform.wrapElse(children);
|
|
6105
6281
|
return transformIfElement(fakeNode, context, transformNode);
|
|
6106
6282
|
}
|
|
6107
|
-
if (hasOtherDirective) return transformNormalElement(node, context, transformNode).replace(
|
|
6283
|
+
if (hasOtherDirective) return transformNormalElement(node, context, transformNode).replace(TEMPLATE_OPEN_RE, "<block").replace(TEMPLATE_CLOSE_RE, "</block>");
|
|
6108
6284
|
return children;
|
|
6109
6285
|
}
|
|
6110
6286
|
const attrs = [];
|
|
@@ -6129,9 +6305,12 @@ function transformElement(node, context, transformNode) {
|
|
|
6129
6305
|
}
|
|
6130
6306
|
//#endregion
|
|
6131
6307
|
//#region src/plugins/vue/compiler/template/nodes.ts
|
|
6308
|
+
const AMP_RE = /&/g;
|
|
6309
|
+
const LT_RE = /</g;
|
|
6310
|
+
const GT_RE = />/g;
|
|
6132
6311
|
function escapeWxmlText(value) {
|
|
6133
6312
|
if (!value) return "";
|
|
6134
|
-
return value.replace(
|
|
6313
|
+
return value.replace(AMP_RE, "&").replace(LT_RE, "<").replace(GT_RE, ">");
|
|
6135
6314
|
}
|
|
6136
6315
|
function transformText(node, _context) {
|
|
6137
6316
|
return escapeWxmlText(node.content);
|
|
@@ -6403,9 +6582,10 @@ function getErrorMessage(error) {
|
|
|
6403
6582
|
if (error instanceof Error) return error.message;
|
|
6404
6583
|
return typeof error === "string" ? error : "";
|
|
6405
6584
|
}
|
|
6585
|
+
const BEHAVIOR_NOT_DEFINED_RE = /\bBehavior is not defined\b/;
|
|
6406
6586
|
function shouldFallbackToRawDefineOptions(error) {
|
|
6407
6587
|
const message = getErrorMessage(error);
|
|
6408
|
-
return
|
|
6588
|
+
return BEHAVIOR_NOT_DEFINED_RE.test(message);
|
|
6409
6589
|
}
|
|
6410
6590
|
function normalizeScriptSetupLang(lang) {
|
|
6411
6591
|
if (!lang) return "ts";
|
|
@@ -6418,8 +6598,9 @@ function resolveScriptSetupExtension(lang) {
|
|
|
6418
6598
|
if (normalized === "ts" || normalized === "tsx" || normalized === "cts" || normalized === "mts") return "ts";
|
|
6419
6599
|
return "js";
|
|
6420
6600
|
}
|
|
6601
|
+
const IDENTIFIER_LIKE_KEY_RE = /^[A-Z_$][\w$]*$/i;
|
|
6421
6602
|
function isIdentifierLikeKey(key) {
|
|
6422
|
-
return
|
|
6603
|
+
return IDENTIFIER_LIKE_KEY_RE.test(key);
|
|
6423
6604
|
}
|
|
6424
6605
|
const SERIALIZABLE_NATIVE_FUNCTIONS = new Map([
|
|
6425
6606
|
[String, "String"],
|
|
@@ -6632,6 +6813,9 @@ async function inlineScriptSetupDefineOptionsArgs(content, filename, lang) {
|
|
|
6632
6813
|
}
|
|
6633
6814
|
//#endregion
|
|
6634
6815
|
//#region src/plugins/vue/transform/compileVueFile/parse.ts
|
|
6816
|
+
const SETUP_CALL_RE = /\bsetup\s*\(/;
|
|
6817
|
+
const DEFINE_OPTIONS_CALL_RE = /\bdefineOptions\s*\(/;
|
|
6818
|
+
const APP_VUE_FILE_RE = /[\\/]app\.vue$/;
|
|
6635
6819
|
function extractDefineOptionsHash(content) {
|
|
6636
6820
|
let ast;
|
|
6637
6821
|
try {
|
|
@@ -6674,7 +6858,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6674
6858
|
let descriptorForCompile = resolvedDescriptor;
|
|
6675
6859
|
const meta = {
|
|
6676
6860
|
hasScriptSetup: !!resolvedDescriptor.scriptSetup,
|
|
6677
|
-
hasSetupOption: !!resolvedDescriptor.script &&
|
|
6861
|
+
hasSetupOption: !!resolvedDescriptor.script && SETUP_CALL_RE.test(resolvedDescriptor.script.content),
|
|
6678
6862
|
sfcSrcDeps
|
|
6679
6863
|
};
|
|
6680
6864
|
let scriptSetupMacroConfig;
|
|
@@ -6715,8 +6899,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6715
6899
|
const resolvedNext = await resolveSfcBlockSrc(nextDescriptor, filename, options.sfcSrc);
|
|
6716
6900
|
descriptorForCompile = resolvedNext.descriptor;
|
|
6717
6901
|
if (resolvedNext.deps.length) {
|
|
6718
|
-
|
|
6719
|
-
sfcSrcDeps = Array.from(deps);
|
|
6902
|
+
sfcSrcDeps = [...new Set([...sfcSrcDeps ?? [], ...resolvedNext.deps])];
|
|
6720
6903
|
meta.sfcSrcDeps = sfcSrcDeps;
|
|
6721
6904
|
}
|
|
6722
6905
|
} else descriptorForCompile = nextDescriptor;
|
|
@@ -6727,7 +6910,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6727
6910
|
defineOptionsHash = extractDefineOptionsHash(scriptSetup.content);
|
|
6728
6911
|
}
|
|
6729
6912
|
const compileScriptSetup = descriptorForCompile.scriptSetup;
|
|
6730
|
-
if (compileScriptSetup?.content &&
|
|
6913
|
+
if (compileScriptSetup?.content && DEFINE_OPTIONS_CALL_RE.test(compileScriptSetup.content)) {
|
|
6731
6914
|
const inlined = await inlineScriptSetupDefineOptionsArgs(compileScriptSetup.content, filename, compileScriptSetup.lang);
|
|
6732
6915
|
if (inlined.code !== compileScriptSetup.content) if (compileScriptSetup.src) descriptorForCompile = {
|
|
6733
6916
|
...descriptorForCompile,
|
|
@@ -6755,15 +6938,14 @@ async function parseVueFile(source, filename, options) {
|
|
|
6755
6938
|
const resolvedNext = await resolveSfcBlockSrc(nextDescriptor, filename, options.sfcSrc);
|
|
6756
6939
|
descriptorForCompile = resolvedNext.descriptor;
|
|
6757
6940
|
if (resolvedNext.deps.length) {
|
|
6758
|
-
|
|
6759
|
-
sfcSrcDeps = Array.from(deps);
|
|
6941
|
+
sfcSrcDeps = [...new Set([...sfcSrcDeps ?? [], ...resolvedNext.deps])];
|
|
6760
6942
|
meta.sfcSrcDeps = sfcSrcDeps;
|
|
6761
6943
|
}
|
|
6762
6944
|
} else descriptorForCompile = nextDescriptor;
|
|
6763
6945
|
descriptorForCompileSource = nextSource;
|
|
6764
6946
|
}
|
|
6765
6947
|
}
|
|
6766
|
-
const isAppFile =
|
|
6948
|
+
const isAppFile = APP_VUE_FILE_RE.test(filename);
|
|
6767
6949
|
return {
|
|
6768
6950
|
descriptor: resolvedDescriptor,
|
|
6769
6951
|
descriptorForCompile,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wevu/compiler",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.7.
|
|
4
|
+
"version": "6.7.5",
|
|
5
5
|
"description": "wevu 编译器基础包,面向小程序模板的编译与转换",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"@babel/parser": "^7.29.0",
|
|
46
46
|
"@babel/traverse": "^7.29.0",
|
|
47
47
|
"@babel/types": "^7.29.0",
|
|
48
|
-
"@vue/compiler-core": "^3.5.
|
|
48
|
+
"@vue/compiler-core": "^3.5.30",
|
|
49
49
|
"comment-json": "^4.6.2",
|
|
50
50
|
"fs-extra": "^11.3.4",
|
|
51
51
|
"lru-cache": "^11.2.6",
|
|
52
52
|
"magic-string": "^0.30.21",
|
|
53
53
|
"merge": "^2.1.1",
|
|
54
54
|
"pathe": "^2.0.3",
|
|
55
|
-
"vue": "^3.5.
|
|
55
|
+
"vue": "^3.5.30",
|
|
56
56
|
"@weapp-core/shared": "3.0.1",
|
|
57
57
|
"rolldown-require": "2.0.6"
|
|
58
58
|
},
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"build": "tsdown",
|
|
66
66
|
"test": "vitest run",
|
|
67
67
|
"test:dev": "vitest",
|
|
68
|
+
"typecheck": "tsc --noEmit",
|
|
68
69
|
"release": "pnpm publish",
|
|
69
70
|
"lint": "eslint .",
|
|
70
71
|
"lint:fix": "eslint . --fix"
|