@wevu/compiler 6.7.3 → 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.d.mts +20 -17
- package/dist/index.mjs +1541 -1377
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import * as t from "@babel/types";
|
|
3
2
|
import { removeExtensionDeep } from "@weapp-core/shared";
|
|
4
3
|
import path from "pathe";
|
|
5
|
-
import { parse as parse$2 } from "@babel/parser";
|
|
6
4
|
import { NodeTypes, baseParse } from "@vue/compiler-core";
|
|
7
|
-
import { LRUCache } from "lru-cache";
|
|
8
5
|
import { createHash } from "node:crypto";
|
|
6
|
+
import * as t from "@babel/types";
|
|
9
7
|
import fs from "fs-extra";
|
|
10
8
|
import MagicString from "magic-string";
|
|
11
9
|
import { recursive } from "merge";
|
|
12
10
|
import { bundleRequire } from "rolldown-require";
|
|
11
|
+
import { parse as parse$2 } from "@babel/parser";
|
|
13
12
|
import fs$1 from "node:fs";
|
|
14
13
|
import os from "node:os";
|
|
15
14
|
import process from "node:process";
|
|
15
|
+
import { LRUCache } from "lru-cache";
|
|
16
16
|
import { compileScript, parse } from "vue/compiler-sfc";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { parse as parse$1 } from "comment-json";
|
|
19
|
-
|
|
20
19
|
//#region src/auto-import-components/builtin.auto.ts
|
|
21
20
|
const components = [
|
|
22
21
|
"wxs",
|
|
@@ -108,7 +107,6 @@ const components = [
|
|
|
108
107
|
"navigation-bar",
|
|
109
108
|
"page-meta"
|
|
110
109
|
];
|
|
111
|
-
|
|
112
110
|
//#endregion
|
|
113
111
|
//#region src/auto-import-components/builtin.ts
|
|
114
112
|
/**
|
|
@@ -121,7 +119,6 @@ const builtinComponentsSet = new Set(components);
|
|
|
121
119
|
function isBuiltinComponent(tag) {
|
|
122
120
|
return builtinComponentsSet.has(tag);
|
|
123
121
|
}
|
|
124
|
-
|
|
125
122
|
//#endregion
|
|
126
123
|
//#region src/constants.ts
|
|
127
124
|
const WE_VU_PAGE_HOOK_TO_FEATURE = {
|
|
@@ -150,59 +147,6 @@ const WE_VU_RUNTIME_APIS = {
|
|
|
150
147
|
defineComponent: "defineComponent",
|
|
151
148
|
setWevuDefaults: "setWevuDefaults"
|
|
152
149
|
};
|
|
153
|
-
|
|
154
|
-
//#endregion
|
|
155
|
-
//#region src/utils/babel.ts
|
|
156
|
-
const BABEL_TS_MODULE_PLUGINS = [
|
|
157
|
-
"typescript",
|
|
158
|
-
"decorators-legacy",
|
|
159
|
-
"classProperties",
|
|
160
|
-
"classPrivateProperties",
|
|
161
|
-
"classPrivateMethods",
|
|
162
|
-
"jsx"
|
|
163
|
-
];
|
|
164
|
-
const BABEL_TS_MODULE_PARSER_OPTIONS = {
|
|
165
|
-
sourceType: "module",
|
|
166
|
-
plugins: BABEL_TS_MODULE_PLUGINS
|
|
167
|
-
};
|
|
168
|
-
const nodeRequire = createRequire(import.meta.url);
|
|
169
|
-
let cachedTraverse;
|
|
170
|
-
let cachedGenerate;
|
|
171
|
-
function requireCallableDefault(id) {
|
|
172
|
-
const mod = nodeRequire(id);
|
|
173
|
-
if (typeof mod === "function") return mod;
|
|
174
|
-
if (mod && (typeof mod === "object" || typeof mod === "function") && "default" in mod) {
|
|
175
|
-
const candidate = mod.default;
|
|
176
|
-
if (typeof candidate === "function") return candidate;
|
|
177
|
-
}
|
|
178
|
-
throw new TypeError(`Invalid module shape for ${id}`);
|
|
179
|
-
}
|
|
180
|
-
function getTraverse() {
|
|
181
|
-
if (!cachedTraverse) cachedTraverse = requireCallableDefault("@babel/traverse");
|
|
182
|
-
return cachedTraverse;
|
|
183
|
-
}
|
|
184
|
-
function getGenerate() {
|
|
185
|
-
if (!cachedGenerate) cachedGenerate = requireCallableDefault("@babel/generator");
|
|
186
|
-
return cachedGenerate;
|
|
187
|
-
}
|
|
188
|
-
const traverse = (...args) => {
|
|
189
|
-
return getTraverse()(...args);
|
|
190
|
-
};
|
|
191
|
-
const generate = (...args) => {
|
|
192
|
-
return getGenerate()(...args);
|
|
193
|
-
};
|
|
194
|
-
function parseJsLike(source) {
|
|
195
|
-
return parse$2(source, {
|
|
196
|
-
sourceType: "module",
|
|
197
|
-
plugins: [
|
|
198
|
-
...BABEL_TS_MODULE_PLUGINS,
|
|
199
|
-
"dynamicImport",
|
|
200
|
-
"optionalChaining",
|
|
201
|
-
"nullishCoalescingOperator"
|
|
202
|
-
]
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
150
|
//#endregion
|
|
207
151
|
//#region src/utils/vueTemplateTags.ts
|
|
208
152
|
const RESERVED_VUE_COMPONENT_TAGS = new Set([
|
|
@@ -215,11 +159,12 @@ const RESERVED_VUE_COMPONENT_TAGS = new Set([
|
|
|
215
159
|
"suspense"
|
|
216
160
|
]);
|
|
217
161
|
const VUE_COMPONENT_TAG_RE = /^[A-Z_$][\w$]*$/i;
|
|
162
|
+
const PASCAL_CASE_TAG_RE = /^[A-Z][\w$]*$/;
|
|
218
163
|
/**
|
|
219
164
|
* 判断模板标签是否可能需要自动导入。
|
|
220
165
|
*/
|
|
221
166
|
function isAutoImportCandidateTag(tag) {
|
|
222
|
-
return tag.includes("-") ||
|
|
167
|
+
return tag.includes("-") || PASCAL_CASE_TAG_RE.test(tag);
|
|
223
168
|
}
|
|
224
169
|
/**
|
|
225
170
|
* 收集 Vue 模板中的自定义组件标签。
|
|
@@ -255,594 +200,185 @@ function collectVueTemplateTags(template, options) {
|
|
|
255
200
|
}
|
|
256
201
|
return tags;
|
|
257
202
|
}
|
|
258
|
-
|
|
259
203
|
//#endregion
|
|
260
|
-
//#region src/plugins/vue/
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
quotes: "single",
|
|
267
|
-
minimal: true
|
|
204
|
+
//#region src/plugins/vue/transform/jsonMacros/analyze.ts
|
|
205
|
+
function collectPatternNames(pattern, out) {
|
|
206
|
+
if (!pattern) return;
|
|
207
|
+
if (t.isIdentifier(pattern)) {
|
|
208
|
+
out.add(pattern.name);
|
|
209
|
+
return;
|
|
268
210
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
211
|
+
if (t.isRestElement(pattern)) {
|
|
212
|
+
collectPatternNames(pattern.argument, out);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (t.isAssignmentPattern(pattern)) {
|
|
216
|
+
collectPatternNames(pattern.left, out);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (t.isObjectPattern(pattern)) {
|
|
220
|
+
for (const prop of pattern.properties) if (t.isRestElement(prop)) collectPatternNames(prop.argument, out);
|
|
221
|
+
else if (t.isObjectProperty(prop)) collectPatternNames(prop.value, out);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (t.isArrayPattern(pattern)) for (const el of pattern.elements) collectPatternNames(el, out);
|
|
273
225
|
}
|
|
274
|
-
function
|
|
275
|
-
const
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
sourceType: "module",
|
|
280
|
-
plugins: ["typescript"]
|
|
281
|
-
}).program.body[0];
|
|
282
|
-
if (!stmt || !("expression" in stmt)) {
|
|
283
|
-
babelExpressionCache.set(exp, false);
|
|
284
|
-
return null;
|
|
226
|
+
function declaredNamesInStatement(statement) {
|
|
227
|
+
const out = /* @__PURE__ */ new Set();
|
|
228
|
+
if (t.isImportDeclaration(statement)) {
|
|
229
|
+
for (const specifier of statement.specifiers) if (t.isImportSpecifier(specifier) || t.isImportDefaultSpecifier(specifier) || t.isImportNamespaceSpecifier(specifier)) {
|
|
230
|
+
if (t.isIdentifier(specifier.local)) out.add(specifier.local.name);
|
|
285
231
|
}
|
|
286
|
-
|
|
287
|
-
babelExpressionCache.set(exp, expression);
|
|
288
|
-
return expression;
|
|
289
|
-
} catch {
|
|
290
|
-
babelExpressionCache.set(exp, false);
|
|
291
|
-
return null;
|
|
232
|
+
return out;
|
|
292
233
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const stmt = ast.program.body[0];
|
|
301
|
-
if (!stmt || !("expression" in stmt)) return null;
|
|
302
|
-
return {
|
|
303
|
-
ast,
|
|
304
|
-
expression: stmt.expression
|
|
305
|
-
};
|
|
306
|
-
} catch {
|
|
307
|
-
return null;
|
|
234
|
+
if (t.isVariableDeclaration(statement)) {
|
|
235
|
+
for (const decl of statement.declarations) collectPatternNames(decl.id, out);
|
|
236
|
+
return out;
|
|
237
|
+
}
|
|
238
|
+
if (t.isFunctionDeclaration(statement) || t.isClassDeclaration(statement)) {
|
|
239
|
+
if (statement.id && t.isIdentifier(statement.id)) out.add(statement.id.name);
|
|
240
|
+
return out;
|
|
308
241
|
}
|
|
242
|
+
if (t.isExportNamedDeclaration(statement) && statement.declaration) return declaredNamesInStatement(statement.declaration);
|
|
243
|
+
return out;
|
|
309
244
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
const
|
|
317
|
-
if (
|
|
318
|
-
if (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
245
|
+
function collectTopLevelReferencedNames(path) {
|
|
246
|
+
const names = /* @__PURE__ */ new Set();
|
|
247
|
+
if (!path) return names;
|
|
248
|
+
const addIfTopLevelReferenced = (p) => {
|
|
249
|
+
if (!p?.isReferencedIdentifier?.()) return;
|
|
250
|
+
const name = p.node.name;
|
|
251
|
+
const binding = p.scope?.getBinding(name);
|
|
252
|
+
if (!binding) return;
|
|
253
|
+
if (binding.scope?.block?.type === "Program") names.add(name);
|
|
254
|
+
};
|
|
255
|
+
addIfTopLevelReferenced(path);
|
|
256
|
+
path.traverse({
|
|
257
|
+
Function(p) {
|
|
258
|
+
if (p.node !== path.node) p.skip();
|
|
259
|
+
},
|
|
260
|
+
Class(p) {
|
|
261
|
+
if (p.node !== path.node) p.skip();
|
|
262
|
+
},
|
|
263
|
+
Identifier(p) {
|
|
264
|
+
addIfTopLevelReferenced(p);
|
|
322
265
|
}
|
|
323
266
|
});
|
|
324
|
-
|
|
325
|
-
if (segments.length === 1) return segments[0];
|
|
326
|
-
return segments.reduce((acc, cur) => t.binaryExpression("+", acc, cur));
|
|
327
|
-
}
|
|
328
|
-
function isOptionalChainNode(node) {
|
|
329
|
-
return Boolean(node && (t.isOptionalMemberExpression(node) || t.isOptionalCallExpression(node)));
|
|
267
|
+
return names;
|
|
330
268
|
}
|
|
331
|
-
function
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
type: "member",
|
|
338
|
-
optional: current.optional === true,
|
|
339
|
-
computed: current.computed,
|
|
340
|
-
property: t.cloneNode(current.property)
|
|
341
|
-
});
|
|
342
|
-
current = current.object;
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
operations.push({
|
|
346
|
-
type: "call",
|
|
347
|
-
optional: current.optional === true,
|
|
348
|
-
args: current.arguments.map((arg) => t.cloneNode(arg))
|
|
349
|
-
});
|
|
350
|
-
current = current.callee;
|
|
269
|
+
function collectKeptStatementPaths(programPath, macroStatements) {
|
|
270
|
+
const bodyPaths = programPath.get("body");
|
|
271
|
+
const nameToStatementPath = /* @__PURE__ */ new Map();
|
|
272
|
+
for (const statementPath of bodyPaths) {
|
|
273
|
+
const declared = declaredNamesInStatement(statementPath.node);
|
|
274
|
+
for (const name of declared) if (!nameToStatementPath.has(name)) nameToStatementPath.set(name, statementPath);
|
|
351
275
|
}
|
|
352
|
-
|
|
276
|
+
const neededNames = /* @__PURE__ */ new Set();
|
|
277
|
+
for (const statementPath of macroStatements) {
|
|
278
|
+
const deps = collectTopLevelReferencedNames(statementPath.get("expression").get("arguments.0"));
|
|
279
|
+
for (const dep of deps) neededNames.add(dep);
|
|
280
|
+
}
|
|
281
|
+
const keptStatementPaths = /* @__PURE__ */ new Set();
|
|
282
|
+
const queue = [...neededNames];
|
|
283
|
+
while (queue.length) {
|
|
284
|
+
const name = queue.pop();
|
|
285
|
+
const declPath = nameToStatementPath.get(name);
|
|
286
|
+
if (!declPath || keptStatementPaths.has(declPath)) continue;
|
|
287
|
+
keptStatementPaths.add(declPath);
|
|
288
|
+
const deps = collectTopLevelReferencedNames(declPath);
|
|
289
|
+
for (const dep of deps) if (dep !== name) queue.push(dep);
|
|
290
|
+
}
|
|
291
|
+
for (const statementPath of macroStatements) keptStatementPaths.add(statementPath);
|
|
353
292
|
return {
|
|
354
|
-
|
|
355
|
-
|
|
293
|
+
bodyPaths,
|
|
294
|
+
keptStatementPaths
|
|
356
295
|
};
|
|
357
296
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/plugins/vue/transform/tempDirLock.ts
|
|
299
|
+
const locks = /* @__PURE__ */ new Map();
|
|
300
|
+
async function withTempDirLock(tempDir, fn) {
|
|
301
|
+
const previous = locks.get(tempDir) ?? Promise.resolve();
|
|
302
|
+
let release;
|
|
303
|
+
const gate = new Promise((resolve) => {
|
|
304
|
+
release = resolve;
|
|
305
|
+
});
|
|
306
|
+
const current = previous.then(() => gate);
|
|
307
|
+
locks.set(tempDir, current);
|
|
308
|
+
try {
|
|
309
|
+
await previous;
|
|
310
|
+
return await fn();
|
|
311
|
+
} finally {
|
|
312
|
+
release?.();
|
|
313
|
+
if (locks.get(tempDir) === current) locks.delete(tempDir);
|
|
374
314
|
}
|
|
375
|
-
return lowered;
|
|
376
315
|
}
|
|
377
|
-
function normalizeWxmlExpression(exp) {
|
|
378
|
-
if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.")) return exp;
|
|
379
|
-
try {
|
|
380
|
-
const ast = parse$2(`(${exp})`, {
|
|
381
|
-
sourceType: "module",
|
|
382
|
-
plugins: ["typescript"]
|
|
383
|
-
});
|
|
384
|
-
const stmt = ast.program.body[0];
|
|
385
|
-
if (!stmt || !("expression" in stmt)) return exp;
|
|
386
|
-
traverse(ast, {
|
|
387
|
-
OptionalMemberExpression: { exit(path) {
|
|
388
|
-
if (isOptionalChainNode(path.parentPath.node)) return;
|
|
389
|
-
path.replaceWith(lowerOptionalChain(path.node));
|
|
390
|
-
path.skip();
|
|
391
|
-
} },
|
|
392
|
-
OptionalCallExpression: { exit(path) {
|
|
393
|
-
if (isOptionalChainNode(path.parentPath.node)) return;
|
|
394
|
-
path.replaceWith(lowerOptionalChain(path.node));
|
|
395
|
-
path.skip();
|
|
396
|
-
} },
|
|
397
|
-
LogicalExpression(path) {
|
|
398
|
-
if (path.node.operator !== "??") return;
|
|
399
|
-
const left = path.node.left;
|
|
400
|
-
const right = path.node.right;
|
|
401
|
-
const test = t.binaryExpression("!=", t.cloneNode(left), t.nullLiteral());
|
|
402
|
-
path.replaceWith(t.conditionalExpression(test, t.cloneNode(left), t.cloneNode(right)));
|
|
403
|
-
path.skip();
|
|
404
|
-
},
|
|
405
|
-
TemplateLiteral(path) {
|
|
406
|
-
if (t.isTaggedTemplateExpression(path.parent)) return;
|
|
407
|
-
path.replaceWith(templateLiteralToConcat(path.node));
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
const normalized = stmt.expression;
|
|
411
|
-
return generateExpression(normalized);
|
|
412
|
-
} catch {
|
|
413
|
-
if (exp.startsWith("`") && exp.endsWith("`")) {
|
|
414
|
-
let rewritten = `'${exp.slice(1, -1).replace(/\$\{([^}]+)\}/g, "' + ($1) + '")}'`;
|
|
415
|
-
rewritten = rewritten.replace(/'\s*\+\s*''/g, "'").replace(/''\s*\+\s*'/g, "'");
|
|
416
|
-
rewritten = rewritten.replace(/^\s*''\s*\+\s*/g, "").replace(/\s*\+\s*''\s*$/g, "");
|
|
417
|
-
return rewritten;
|
|
418
|
-
}
|
|
419
|
-
return exp;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
316
|
//#endregion
|
|
424
|
-
//#region src/
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
confirm: "confirm",
|
|
437
|
-
cancel: "cancel",
|
|
438
|
-
load: "load",
|
|
439
|
-
error: "error",
|
|
440
|
-
scroll: "scroll",
|
|
441
|
-
scrolltoupper: "scrolltoupper",
|
|
442
|
-
scrolltolower: "scrolltolower",
|
|
443
|
-
touchcancel: "touchcancel",
|
|
444
|
-
longtap: "longtap",
|
|
445
|
-
longpress: "longpress"
|
|
317
|
+
//#region src/utils/babel.ts
|
|
318
|
+
const BABEL_TS_MODULE_PLUGINS = [
|
|
319
|
+
"typescript",
|
|
320
|
+
"decorators-legacy",
|
|
321
|
+
"classProperties",
|
|
322
|
+
"classPrivateProperties",
|
|
323
|
+
"classPrivateMethods",
|
|
324
|
+
"jsx"
|
|
325
|
+
];
|
|
326
|
+
const BABEL_TS_MODULE_PARSER_OPTIONS = {
|
|
327
|
+
sourceType: "module",
|
|
328
|
+
plugins: BABEL_TS_MODULE_PLUGINS
|
|
446
329
|
};
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
330
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
331
|
+
let cachedTraverse;
|
|
332
|
+
let cachedGenerate;
|
|
333
|
+
function requireCallableDefault(id) {
|
|
334
|
+
const mod = nodeRequire(id);
|
|
335
|
+
if (typeof mod === "function") return mod;
|
|
336
|
+
if (mod && (typeof mod === "object" || typeof mod === "function") && "default" in mod) {
|
|
337
|
+
const candidate = mod.default;
|
|
338
|
+
if (typeof candidate === "function") return candidate;
|
|
339
|
+
}
|
|
340
|
+
throw new TypeError(`Invalid module shape for ${id}`);
|
|
450
341
|
}
|
|
451
|
-
function
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
prefix: prefixed[1],
|
|
455
|
-
name: prefixed[2]
|
|
456
|
-
};
|
|
457
|
-
return {
|
|
458
|
-
prefix: "bind",
|
|
459
|
-
name: eventName
|
|
460
|
-
};
|
|
342
|
+
function getTraverse() {
|
|
343
|
+
if (!cachedTraverse) cachedTraverse = requireCallableDefault("@babel/traverse");
|
|
344
|
+
return cachedTraverse;
|
|
461
345
|
}
|
|
462
|
-
function
|
|
463
|
-
if (!
|
|
464
|
-
|
|
465
|
-
switch (prefix) {
|
|
466
|
-
case "catch": return `catch${pascalEvent}`;
|
|
467
|
-
case "capture-bind": return `capture${pascalEvent}`;
|
|
468
|
-
case "capture-catch": return `captureCatch${pascalEvent}`;
|
|
469
|
-
default: return toOnEventName(eventName);
|
|
470
|
-
}
|
|
346
|
+
function getGenerate() {
|
|
347
|
+
if (!cachedGenerate) cachedGenerate = requireCallableDefault("@babel/generator");
|
|
348
|
+
return cachedGenerate;
|
|
471
349
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
*/
|
|
475
|
-
const alipayPlatform = {
|
|
476
|
-
name: "alipay",
|
|
477
|
-
wrapIf: (exp, content, renderMustache) => `<block a:if="${renderMustache(exp)}">${content}</block>`,
|
|
478
|
-
wrapElseIf: (exp, content, renderMustache) => `<block a:elif="${renderMustache(exp)}">${content}</block>`,
|
|
479
|
-
wrapElse: (content) => `<block a:else>${content}</block>`,
|
|
480
|
-
forAttrs: (listExp, renderMustache, item, index) => {
|
|
481
|
-
const attrs = [`a:for="${renderMustache(listExp)}"`];
|
|
482
|
-
if (item) attrs.push(`a:for-item="${item}"`);
|
|
483
|
-
if (index) attrs.push(`a:for-index="${index}"`);
|
|
484
|
-
return attrs;
|
|
485
|
-
},
|
|
486
|
-
keyThisValue: "*this",
|
|
487
|
-
keyAttr: (value) => `a:key="${value}"`,
|
|
488
|
-
mapEventName: (eventName) => eventMap$3[eventName] || eventName,
|
|
489
|
-
eventBindingAttr: (eventName) => {
|
|
490
|
-
const { prefix, name } = parseEventBinding$3(eventName);
|
|
491
|
-
if (name.includes(":")) return `on:${name}`;
|
|
492
|
-
return toAlipayDirectiveEvent(prefix, name);
|
|
493
|
-
}
|
|
350
|
+
const traverse = (...args) => {
|
|
351
|
+
return getTraverse()(...args);
|
|
494
352
|
};
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
//#region src/plugins/vue/compiler/template/platforms/swan.ts
|
|
498
|
-
const eventMap$2 = {
|
|
499
|
-
click: "tap",
|
|
500
|
-
dblclick: "tap",
|
|
501
|
-
mousedown: "touchstart",
|
|
502
|
-
mouseup: "touchend",
|
|
503
|
-
tap: "tap",
|
|
504
|
-
input: "input",
|
|
505
|
-
change: "change",
|
|
506
|
-
submit: "submit",
|
|
507
|
-
focus: "focus",
|
|
508
|
-
blur: "blur",
|
|
509
|
-
confirm: "confirm",
|
|
510
|
-
cancel: "cancel",
|
|
511
|
-
load: "load",
|
|
512
|
-
error: "error",
|
|
513
|
-
scroll: "scroll",
|
|
514
|
-
scrolltoupper: "scrolltoupper",
|
|
515
|
-
scrolltolower: "scrolltolower",
|
|
516
|
-
touchcancel: "touchcancel",
|
|
517
|
-
longtap: "longtap",
|
|
518
|
-
longpress: "longpress"
|
|
353
|
+
const generate = (...args) => {
|
|
354
|
+
return getGenerate()(...args);
|
|
519
355
|
};
|
|
520
|
-
function
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
};
|
|
530
|
-
}
|
|
531
|
-
function shouldUseColonEventBinding$2(name) {
|
|
532
|
-
return name.includes(":") || name.includes("-");
|
|
356
|
+
function parseJsLike(source) {
|
|
357
|
+
return parse$2(source, {
|
|
358
|
+
sourceType: "module",
|
|
359
|
+
plugins: [
|
|
360
|
+
...BABEL_TS_MODULE_PLUGINS,
|
|
361
|
+
"dynamicImport",
|
|
362
|
+
"optionalChaining",
|
|
363
|
+
"nullishCoalescingOperator"
|
|
364
|
+
]
|
|
365
|
+
});
|
|
533
366
|
}
|
|
534
|
-
/**
|
|
535
|
-
* 百度智能小程序平台适配器。
|
|
536
|
-
*/
|
|
537
|
-
const swanPlatform = {
|
|
538
|
-
name: "swan",
|
|
539
|
-
wrapIf: (exp, content, renderMustache) => `<block s-if="${renderMustache(exp)}">${content}</block>`,
|
|
540
|
-
wrapElseIf: (exp, content, renderMustache) => `<block s-elif="${renderMustache(exp)}">${content}</block>`,
|
|
541
|
-
wrapElse: (content) => `<block s-else>${content}</block>`,
|
|
542
|
-
forAttrs: (listExp, renderMustache, item, index) => {
|
|
543
|
-
const attrs = [`s-for="${renderMustache(listExp)}"`];
|
|
544
|
-
if (item) attrs.push(`s-for-item="${item}"`);
|
|
545
|
-
if (index) attrs.push(`s-for-index="${index}"`);
|
|
546
|
-
return attrs;
|
|
547
|
-
},
|
|
548
|
-
keyThisValue: "*this",
|
|
549
|
-
keyAttr: (value) => `s-key="${value}"`,
|
|
550
|
-
mapEventName: (eventName) => eventMap$2[eventName] || eventName,
|
|
551
|
-
eventBindingAttr: (eventName) => {
|
|
552
|
-
const { prefix, name } = parseEventBinding$2(eventName);
|
|
553
|
-
switch (prefix) {
|
|
554
|
-
case "catch": return shouldUseColonEventBinding$2(name) ? `catch:${name}` : `catch${name}`;
|
|
555
|
-
case "capture-bind": return `capture-bind:${name}`;
|
|
556
|
-
case "capture-catch": return `capture-catch:${name}`;
|
|
557
|
-
case "mut-bind": return `mut-bind:${name}`;
|
|
558
|
-
default: return shouldUseColonEventBinding$2(name) ? `bind:${name}` : `bind${name}`;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
|
|
563
367
|
//#endregion
|
|
564
|
-
//#region src/
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
input: "input",
|
|
572
|
-
change: "change",
|
|
573
|
-
submit: "submit",
|
|
574
|
-
focus: "focus",
|
|
575
|
-
blur: "blur",
|
|
576
|
-
confirm: "confirm",
|
|
577
|
-
cancel: "cancel",
|
|
578
|
-
load: "load",
|
|
579
|
-
error: "error",
|
|
580
|
-
scroll: "scroll",
|
|
581
|
-
scrolltoupper: "scrolltoupper",
|
|
582
|
-
scrolltolower: "scrolltolower",
|
|
583
|
-
touchcancel: "touchcancel",
|
|
584
|
-
longtap: "longtap",
|
|
585
|
-
longpress: "longpress"
|
|
586
|
-
};
|
|
587
|
-
function parseEventBinding$1(eventName) {
|
|
588
|
-
const prefixed = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/.exec(eventName);
|
|
589
|
-
if (prefixed) return {
|
|
590
|
-
prefix: prefixed[1],
|
|
591
|
-
name: prefixed[2]
|
|
592
|
-
};
|
|
593
|
-
return {
|
|
594
|
-
prefix: "bind",
|
|
595
|
-
name: eventName
|
|
596
|
-
};
|
|
368
|
+
//#region src/utils/path.ts
|
|
369
|
+
const BACKSLASH_RE$4 = /\\/g;
|
|
370
|
+
const LEADING_SLASH_RE = /^[\\/]+/;
|
|
371
|
+
const DUPLICATE_SLASH_RE = /\/{2,}/g;
|
|
372
|
+
const TRIM_SLASH_RE = /^\/+|\/+$/g;
|
|
373
|
+
function toPosixPath(value) {
|
|
374
|
+
return value.replace(BACKSLASH_RE$4, "/");
|
|
597
375
|
}
|
|
598
|
-
function
|
|
599
|
-
return
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* 抖音小程序平台适配器。
|
|
603
|
-
*/
|
|
604
|
-
const ttPlatform = {
|
|
605
|
-
name: "tt",
|
|
606
|
-
wrapIf: (exp, content, renderMustache) => `<block tt:if="${renderMustache(exp)}">${content}</block>`,
|
|
607
|
-
wrapElseIf: (exp, content, renderMustache) => `<block tt:elif="${renderMustache(exp)}">${content}</block>`,
|
|
608
|
-
wrapElse: (content) => `<block tt:else>${content}</block>`,
|
|
609
|
-
forAttrs: (listExp, renderMustache, item, index) => {
|
|
610
|
-
const attrs = [`tt:for="${renderMustache(listExp)}"`];
|
|
611
|
-
if (item) attrs.push(`tt:for-item="${item}"`);
|
|
612
|
-
if (index) attrs.push(`tt:for-index="${index}"`);
|
|
613
|
-
return attrs;
|
|
614
|
-
},
|
|
615
|
-
keyThisValue: "*this",
|
|
616
|
-
keyAttr: (value) => `tt:key="${value}"`,
|
|
617
|
-
mapEventName: (eventName) => eventMap$1[eventName] || eventName,
|
|
618
|
-
eventBindingAttr: (eventName) => {
|
|
619
|
-
const { prefix, name } = parseEventBinding$1(eventName);
|
|
620
|
-
switch (prefix) {
|
|
621
|
-
case "catch": return shouldUseColonEventBinding$1(name) ? `catch:${name}` : `catch${name}`;
|
|
622
|
-
case "capture-bind": return `capture-bind:${name}`;
|
|
623
|
-
case "capture-catch": return `capture-catch:${name}`;
|
|
624
|
-
case "mut-bind": return `mut-bind:${name}`;
|
|
625
|
-
default: return shouldUseColonEventBinding$1(name) ? `bind:${name}` : `bind${name}`;
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
|
|
630
|
-
//#endregion
|
|
631
|
-
//#region src/plugins/vue/compiler/template/platforms/wechat.ts
|
|
632
|
-
const eventMap = {
|
|
633
|
-
click: "tap",
|
|
634
|
-
dblclick: "tap",
|
|
635
|
-
mousedown: "touchstart",
|
|
636
|
-
mouseup: "touchend",
|
|
637
|
-
tap: "tap",
|
|
638
|
-
input: "input",
|
|
639
|
-
change: "change",
|
|
640
|
-
submit: "submit",
|
|
641
|
-
focus: "focus",
|
|
642
|
-
blur: "blur",
|
|
643
|
-
confirm: "confirm",
|
|
644
|
-
cancel: "cancel",
|
|
645
|
-
load: "load",
|
|
646
|
-
error: "error",
|
|
647
|
-
scroll: "scroll",
|
|
648
|
-
scrolltoupper: "scrolltoupper",
|
|
649
|
-
scrolltolower: "scrolltolower",
|
|
650
|
-
touchcancel: "touchcancel",
|
|
651
|
-
longtap: "longtap",
|
|
652
|
-
longpress: "longpress"
|
|
653
|
-
};
|
|
654
|
-
function parseEventBinding(eventName) {
|
|
655
|
-
const prefixed = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/.exec(eventName);
|
|
656
|
-
if (prefixed) return {
|
|
657
|
-
prefix: prefixed[1],
|
|
658
|
-
name: prefixed[2]
|
|
659
|
-
};
|
|
660
|
-
return {
|
|
661
|
-
prefix: "bind",
|
|
662
|
-
name: eventName
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
function shouldUseColonEventBinding(name) {
|
|
666
|
-
return name.includes(":") || name.includes("-");
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* 微信小程序平台适配器。
|
|
670
|
-
*/
|
|
671
|
-
const wechatPlatform = {
|
|
672
|
-
name: "wechat",
|
|
673
|
-
wrapIf: (exp, content, renderMustache) => `<block wx:if="${renderMustache(exp)}">${content}</block>`,
|
|
674
|
-
wrapElseIf: (exp, content, renderMustache) => `<block wx:elif="${renderMustache(exp)}">${content}</block>`,
|
|
675
|
-
wrapElse: (content) => `<block wx:else>${content}</block>`,
|
|
676
|
-
forAttrs: (listExp, renderMustache, item, index) => {
|
|
677
|
-
const attrs = [`wx:for="${renderMustache(listExp)}"`];
|
|
678
|
-
if (item) attrs.push(`wx:for-item="${item}"`);
|
|
679
|
-
if (index) attrs.push(`wx:for-index="${index}"`);
|
|
680
|
-
return attrs;
|
|
681
|
-
},
|
|
682
|
-
keyThisValue: "*this",
|
|
683
|
-
keyAttr: (value) => `wx:key="${value}"`,
|
|
684
|
-
mapEventName: (eventName) => eventMap[eventName] || eventName,
|
|
685
|
-
eventBindingAttr: (eventName) => {
|
|
686
|
-
const { prefix, name } = parseEventBinding(eventName);
|
|
687
|
-
switch (prefix) {
|
|
688
|
-
case "catch": return shouldUseColonEventBinding(name) ? `catch:${name}` : `catch${name}`;
|
|
689
|
-
case "capture-bind": return `capture-bind:${name}`;
|
|
690
|
-
case "capture-catch": return `capture-catch:${name}`;
|
|
691
|
-
case "mut-bind": return `mut-bind:${name}`;
|
|
692
|
-
default: return shouldUseColonEventBinding(name) ? `bind:${name}` : `bind${name}`;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
};
|
|
696
|
-
|
|
697
|
-
//#endregion
|
|
698
|
-
//#region src/plugins/vue/compiler/template/platforms/index.ts
|
|
699
|
-
const TEMPLATE_PLATFORMS = {
|
|
700
|
-
weapp: wechatPlatform,
|
|
701
|
-
alipay: alipayPlatform,
|
|
702
|
-
tt: ttPlatform,
|
|
703
|
-
swan: swanPlatform,
|
|
704
|
-
jd: wechatPlatform,
|
|
705
|
-
xhs: wechatPlatform
|
|
706
|
-
};
|
|
707
|
-
/**
|
|
708
|
-
* 获取指定平台的模板适配器,默认回退到 wechat。
|
|
709
|
-
*/
|
|
710
|
-
function getMiniProgramTemplatePlatform(platform) {
|
|
711
|
-
if (!platform) return wechatPlatform;
|
|
712
|
-
return TEMPLATE_PLATFORMS[platform] ?? wechatPlatform;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
//#endregion
|
|
716
|
-
//#region src/plugins/vue/transform/jsonMacros/analyze.ts
|
|
717
|
-
function collectPatternNames(pattern, out) {
|
|
718
|
-
if (!pattern) return;
|
|
719
|
-
if (t.isIdentifier(pattern)) {
|
|
720
|
-
out.add(pattern.name);
|
|
721
|
-
return;
|
|
722
|
-
}
|
|
723
|
-
if (t.isRestElement(pattern)) {
|
|
724
|
-
collectPatternNames(pattern.argument, out);
|
|
725
|
-
return;
|
|
726
|
-
}
|
|
727
|
-
if (t.isAssignmentPattern(pattern)) {
|
|
728
|
-
collectPatternNames(pattern.left, out);
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
if (t.isObjectPattern(pattern)) {
|
|
732
|
-
for (const prop of pattern.properties) if (t.isRestElement(prop)) collectPatternNames(prop.argument, out);
|
|
733
|
-
else if (t.isObjectProperty(prop)) collectPatternNames(prop.value, out);
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
if (t.isArrayPattern(pattern)) for (const el of pattern.elements) collectPatternNames(el, out);
|
|
737
|
-
}
|
|
738
|
-
function declaredNamesInStatement(statement) {
|
|
739
|
-
const out = /* @__PURE__ */ new Set();
|
|
740
|
-
if (t.isImportDeclaration(statement)) {
|
|
741
|
-
for (const specifier of statement.specifiers) if (t.isImportSpecifier(specifier) || t.isImportDefaultSpecifier(specifier) || t.isImportNamespaceSpecifier(specifier)) {
|
|
742
|
-
if (t.isIdentifier(specifier.local)) out.add(specifier.local.name);
|
|
743
|
-
}
|
|
744
|
-
return out;
|
|
745
|
-
}
|
|
746
|
-
if (t.isVariableDeclaration(statement)) {
|
|
747
|
-
for (const decl of statement.declarations) collectPatternNames(decl.id, out);
|
|
748
|
-
return out;
|
|
749
|
-
}
|
|
750
|
-
if (t.isFunctionDeclaration(statement) || t.isClassDeclaration(statement)) {
|
|
751
|
-
if (statement.id && t.isIdentifier(statement.id)) out.add(statement.id.name);
|
|
752
|
-
return out;
|
|
753
|
-
}
|
|
754
|
-
if (t.isExportNamedDeclaration(statement) && statement.declaration) return declaredNamesInStatement(statement.declaration);
|
|
755
|
-
return out;
|
|
756
|
-
}
|
|
757
|
-
function collectTopLevelReferencedNames(path) {
|
|
758
|
-
const names = /* @__PURE__ */ new Set();
|
|
759
|
-
if (!path) return names;
|
|
760
|
-
const addIfTopLevelReferenced = (p) => {
|
|
761
|
-
if (!p?.isReferencedIdentifier?.()) return;
|
|
762
|
-
const name = p.node.name;
|
|
763
|
-
const binding = p.scope?.getBinding(name);
|
|
764
|
-
if (!binding) return;
|
|
765
|
-
if (binding.scope?.block?.type === "Program") names.add(name);
|
|
766
|
-
};
|
|
767
|
-
addIfTopLevelReferenced(path);
|
|
768
|
-
path.traverse({
|
|
769
|
-
Function(p) {
|
|
770
|
-
if (p.node !== path.node) p.skip();
|
|
771
|
-
},
|
|
772
|
-
Class(p) {
|
|
773
|
-
if (p.node !== path.node) p.skip();
|
|
774
|
-
},
|
|
775
|
-
Identifier(p) {
|
|
776
|
-
addIfTopLevelReferenced(p);
|
|
777
|
-
}
|
|
778
|
-
});
|
|
779
|
-
return names;
|
|
780
|
-
}
|
|
781
|
-
function collectKeptStatementPaths(programPath, macroStatements) {
|
|
782
|
-
const bodyPaths = programPath.get("body");
|
|
783
|
-
const nameToStatementPath = /* @__PURE__ */ new Map();
|
|
784
|
-
for (const statementPath of bodyPaths) {
|
|
785
|
-
const declared = declaredNamesInStatement(statementPath.node);
|
|
786
|
-
for (const name of declared) if (!nameToStatementPath.has(name)) nameToStatementPath.set(name, statementPath);
|
|
787
|
-
}
|
|
788
|
-
const neededNames = /* @__PURE__ */ new Set();
|
|
789
|
-
for (const statementPath of macroStatements) {
|
|
790
|
-
const deps = collectTopLevelReferencedNames(statementPath.get("expression").get("arguments.0"));
|
|
791
|
-
for (const dep of deps) neededNames.add(dep);
|
|
792
|
-
}
|
|
793
|
-
const keptStatementPaths = /* @__PURE__ */ new Set();
|
|
794
|
-
const queue = [...neededNames];
|
|
795
|
-
while (queue.length) {
|
|
796
|
-
const name = queue.pop();
|
|
797
|
-
const declPath = nameToStatementPath.get(name);
|
|
798
|
-
if (!declPath || keptStatementPaths.has(declPath)) continue;
|
|
799
|
-
keptStatementPaths.add(declPath);
|
|
800
|
-
const deps = collectTopLevelReferencedNames(declPath);
|
|
801
|
-
for (const dep of deps) if (dep !== name) queue.push(dep);
|
|
802
|
-
}
|
|
803
|
-
for (const statementPath of macroStatements) keptStatementPaths.add(statementPath);
|
|
804
|
-
return {
|
|
805
|
-
bodyPaths,
|
|
806
|
-
keptStatementPaths
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
//#endregion
|
|
811
|
-
//#region src/plugins/vue/transform/tempDirLock.ts
|
|
812
|
-
const locks = /* @__PURE__ */ new Map();
|
|
813
|
-
async function withTempDirLock(tempDir, fn) {
|
|
814
|
-
const previous = locks.get(tempDir) ?? Promise.resolve();
|
|
815
|
-
let release;
|
|
816
|
-
const gate = new Promise((resolve) => {
|
|
817
|
-
release = resolve;
|
|
818
|
-
});
|
|
819
|
-
const current = previous.then(() => gate);
|
|
820
|
-
locks.set(tempDir, current);
|
|
821
|
-
try {
|
|
822
|
-
await previous;
|
|
823
|
-
return await fn();
|
|
824
|
-
} finally {
|
|
825
|
-
release?.();
|
|
826
|
-
if (locks.get(tempDir) === current) locks.delete(tempDir);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
//#endregion
|
|
831
|
-
//#region src/utils/path.ts
|
|
832
|
-
const BACKSLASH_RE$1 = /\\/g;
|
|
833
|
-
const LEADING_SLASH_RE = /^[\\/]+/;
|
|
834
|
-
const DUPLICATE_SLASH_RE = /\/{2,}/g;
|
|
835
|
-
const TRIM_SLASH_RE = /^\/+|\/+$/g;
|
|
836
|
-
function toPosixPath(value) {
|
|
837
|
-
return value.replace(BACKSLASH_RE$1, "/");
|
|
838
|
-
}
|
|
839
|
-
function stripLeadingSlashes(value) {
|
|
840
|
-
return value.replace(LEADING_SLASH_RE, "");
|
|
376
|
+
function stripLeadingSlashes(value) {
|
|
377
|
+
return value.replace(LEADING_SLASH_RE, "");
|
|
841
378
|
}
|
|
842
379
|
function normalizeRoot(root) {
|
|
843
380
|
return toPosixPath(root).replace(DUPLICATE_SLASH_RE, "/").replace(TRIM_SLASH_RE, "");
|
|
844
381
|
}
|
|
845
|
-
|
|
846
382
|
//#endregion
|
|
847
383
|
//#region src/plugins/vue/transform/tempImportRewrite.ts
|
|
848
384
|
function rewriteRelativeImportSource(source, fromDir, tempDir) {
|
|
@@ -893,7 +429,6 @@ function rewriteJsLikeImportsForTempDir(source, fromDir, tempDir) {
|
|
|
893
429
|
});
|
|
894
430
|
return mutated ? ms.toString() : source;
|
|
895
431
|
}
|
|
896
|
-
|
|
897
432
|
//#endregion
|
|
898
433
|
//#region src/plugins/vue/transform/wevuTempDir.ts
|
|
899
434
|
function getWevuConfigCacheRoot() {
|
|
@@ -909,7 +444,6 @@ function resolveWevuConfigTempDir(fromDir) {
|
|
|
909
444
|
const key = createHash("sha256").update(path.normalize(fromDir)).digest("hex").slice(0, 8);
|
|
910
445
|
return path.join(root, key);
|
|
911
446
|
}
|
|
912
|
-
|
|
913
447
|
//#endregion
|
|
914
448
|
//#region src/plugins/vue/transform/jsonMacros/execute.ts
|
|
915
449
|
function normalizeScriptSetupLang$1(lang) {
|
|
@@ -980,7 +514,7 @@ const __weapp_defineThemeJson = (config) => (__weapp_json_macro_values.push(conf
|
|
|
980
514
|
if (typeof next === "function") next = next();
|
|
981
515
|
if (next && typeof next.then === "function") next = await next;
|
|
982
516
|
if (!next || typeof next !== "object" || Array.isArray(next)) throw new Error("宏的返回值必须解析为对象。");
|
|
983
|
-
if (Object.
|
|
517
|
+
if (Object.hasOwn(next, "$schema")) delete next.$schema;
|
|
984
518
|
if (options?.merge) {
|
|
985
519
|
const merged = options.merge(accumulator, next);
|
|
986
520
|
if (merged && typeof merged === "object" && !Array.isArray(merged)) accumulator = merged;
|
|
@@ -1001,7 +535,6 @@ const __weapp_defineThemeJson = (config) => (__weapp_json_macro_values.push(conf
|
|
|
1001
535
|
}
|
|
1002
536
|
});
|
|
1003
537
|
}
|
|
1004
|
-
|
|
1005
538
|
//#endregion
|
|
1006
539
|
//#region src/plugins/vue/transform/jsonMacros/parse.ts
|
|
1007
540
|
const JSON_MACROS = new Set([
|
|
@@ -1036,7 +569,7 @@ function collectMacroCallPaths(ast, filename) {
|
|
|
1036
569
|
};
|
|
1037
570
|
}
|
|
1038
571
|
function assertSingleMacro(macroNames, filename) {
|
|
1039
|
-
if (macroNames.size > 1) throw new Error(`同一个 <script setup> 仅能使用 ${
|
|
572
|
+
if (macroNames.size > 1) throw new Error(`同一个 <script setup> 仅能使用 ${[...JSON_MACROS].join(", ")} 中的一个(${filename})。`);
|
|
1040
573
|
return macroNames.values().next().value;
|
|
1041
574
|
}
|
|
1042
575
|
function findProgramPath(ast) {
|
|
@@ -1047,7 +580,6 @@ function findProgramPath(ast) {
|
|
|
1047
580
|
} });
|
|
1048
581
|
return programPath;
|
|
1049
582
|
}
|
|
1050
|
-
|
|
1051
583
|
//#endregion
|
|
1052
584
|
//#region src/plugins/vue/transform/jsonMacros/rewrite.ts
|
|
1053
585
|
/**
|
|
@@ -1099,7 +631,6 @@ function stripJsonMacroCallsFromCode(code, filename) {
|
|
|
1099
631
|
} });
|
|
1100
632
|
return ms.toString();
|
|
1101
633
|
}
|
|
1102
|
-
|
|
1103
634
|
//#endregion
|
|
1104
635
|
//#region src/plugins/vue/transform/jsonMacros/index.ts
|
|
1105
636
|
/**
|
|
@@ -1142,7 +673,6 @@ async function evaluateJsonMacroConfig(content, filename, lang, options) {
|
|
|
1142
673
|
options
|
|
1143
674
|
});
|
|
1144
675
|
}
|
|
1145
|
-
|
|
1146
676
|
//#endregion
|
|
1147
677
|
//#region src/plugins/vue/transform/jsonMerge.ts
|
|
1148
678
|
function toPlainRecord(value) {
|
|
@@ -1180,7 +710,6 @@ function createJsonMerger(strategy, baseContext) {
|
|
|
1180
710
|
});
|
|
1181
711
|
};
|
|
1182
712
|
}
|
|
1183
|
-
|
|
1184
713
|
//#endregion
|
|
1185
714
|
//#region src/utils/warn.ts
|
|
1186
715
|
/**
|
|
@@ -1191,7 +720,6 @@ function resolveWarnHandler(warn) {
|
|
|
1191
720
|
console.warn(message);
|
|
1192
721
|
});
|
|
1193
722
|
}
|
|
1194
|
-
|
|
1195
723
|
//#endregion
|
|
1196
724
|
//#region src/plugins/wevu/pageFeatures/astUtils.ts
|
|
1197
725
|
function isStaticObjectKeyMatch$1(key, expected) {
|
|
@@ -1207,7 +735,7 @@ function getObjectPropertyByKey$2(node, key) {
|
|
|
1207
735
|
return null;
|
|
1208
736
|
}
|
|
1209
737
|
function buildInjectedFeaturesObject(enabled) {
|
|
1210
|
-
return t.objectExpression(Array.from(enabled
|
|
738
|
+
return t.objectExpression(Array.from(enabled, (key) => {
|
|
1211
739
|
return t.objectProperty(t.identifier(key), t.booleanLiteral(true));
|
|
1212
740
|
}));
|
|
1213
741
|
}
|
|
@@ -1221,7 +749,6 @@ function getObjectMemberIndexByKey(node, key) {
|
|
|
1221
749
|
function isTopLevel(path) {
|
|
1222
750
|
return path.getFunctionParent() == null;
|
|
1223
751
|
}
|
|
1224
|
-
|
|
1225
752
|
//#endregion
|
|
1226
753
|
//#region src/plugins/wevu/pageFeatures/flags.ts
|
|
1227
754
|
function injectWevuShareLifecycleHooksIntoOptionsObject(_optionsObject, _enabled) {
|
|
@@ -1234,7 +761,7 @@ function collectWevuPageFeatureFlags(ast) {
|
|
|
1234
761
|
const namedHookLocals = /* @__PURE__ */ new Map();
|
|
1235
762
|
const namespaceLocals = /* @__PURE__ */ new Set();
|
|
1236
763
|
for (const stmt of ast.program.body) {
|
|
1237
|
-
if (!t.isImportDeclaration(stmt) || stmt.source.value !==
|
|
764
|
+
if (!t.isImportDeclaration(stmt) || stmt.source.value !== "wevu") continue;
|
|
1238
765
|
for (const specifier of stmt.specifiers) if (t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported)) {
|
|
1239
766
|
const matched = WE_VU_PAGE_HOOK_TO_FEATURE[specifier.imported.name];
|
|
1240
767
|
if (matched) namedHookLocals.set(specifier.local.name, matched);
|
|
@@ -1282,7 +809,7 @@ function collectWevuPageFeatureFlags(ast) {
|
|
|
1282
809
|
*/
|
|
1283
810
|
function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject, enabled) {
|
|
1284
811
|
if (!enabled.size) return false;
|
|
1285
|
-
const expectedKeys =
|
|
812
|
+
const expectedKeys = [...enabled];
|
|
1286
813
|
const existingFeaturesProp = getObjectPropertyByKey$2(optionsObject, "features");
|
|
1287
814
|
let changed = false;
|
|
1288
815
|
if (!existingFeaturesProp) {
|
|
@@ -1312,7 +839,6 @@ function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject, enabled) {
|
|
|
1312
839
|
changed = injectWevuShareLifecycleHooksIntoOptionsObject(optionsObject, enabled) || changed;
|
|
1313
840
|
return changed;
|
|
1314
841
|
}
|
|
1315
|
-
|
|
1316
842
|
//#endregion
|
|
1317
843
|
//#region src/plugins/wevu/pageFeatures/moduleAnalysis.ts
|
|
1318
844
|
const externalModuleAnalysisCache = new LRUCache({ max: 256 });
|
|
@@ -1360,7 +886,7 @@ function createModuleAnalysis(id, ast) {
|
|
|
1360
886
|
const source = stmt.source.value;
|
|
1361
887
|
for (const specifier of stmt.specifiers) if (t.isImportSpecifier(specifier)) {
|
|
1362
888
|
const imported = specifier.imported;
|
|
1363
|
-
if (source ===
|
|
889
|
+
if (source === "wevu" && t.isIdentifier(imported)) {
|
|
1364
890
|
const matched = WE_VU_PAGE_HOOK_TO_FEATURE[imported.name];
|
|
1365
891
|
if (matched) wevuNamedHookLocals.set(specifier.local.name, matched);
|
|
1366
892
|
}
|
|
@@ -1378,7 +904,7 @@ function createModuleAnalysis(id, ast) {
|
|
|
1378
904
|
kind: "namespace",
|
|
1379
905
|
source
|
|
1380
906
|
});
|
|
1381
|
-
if (source ===
|
|
907
|
+
if (source === "wevu") wevuNamespaceLocals.add(specifier.local.name);
|
|
1382
908
|
}
|
|
1383
909
|
continue;
|
|
1384
910
|
}
|
|
@@ -1459,7 +985,6 @@ function createModuleAnalysis(id, ast) {
|
|
|
1459
985
|
exports
|
|
1460
986
|
};
|
|
1461
987
|
}
|
|
1462
|
-
|
|
1463
988
|
//#endregion
|
|
1464
989
|
//#region src/plugins/wevu/pageFeatures/optionsObjects.ts
|
|
1465
990
|
function unwrapTypeLikeExpression$2(node) {
|
|
@@ -1508,11 +1033,11 @@ function collectTargetOptionsObjects(ast, moduleId) {
|
|
|
1508
1033
|
if (!first || !t.isExpression(first)) return;
|
|
1509
1034
|
const binding = t.isIdentifier(node.callee) ? module.importedBindings.get(node.callee.name) : void 0;
|
|
1510
1035
|
if (t.isIdentifier(node.callee)) {
|
|
1511
|
-
if (binding?.kind !== "named" || binding.source !==
|
|
1036
|
+
if (binding?.kind !== "named" || binding.source !== "wevu") return;
|
|
1512
1037
|
if (binding.importedName !== WE_VU_RUNTIME_APIS.defineComponent && binding.importedName !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
|
|
1513
1038
|
} else if (t.isMemberExpression(node.callee) && !node.callee.computed && t.isIdentifier(node.callee.object) && t.isIdentifier(node.callee.property)) {
|
|
1514
1039
|
const objectBinding = module.importedBindings.get(node.callee.object.name);
|
|
1515
|
-
if (objectBinding?.kind !== "namespace" || objectBinding.source !==
|
|
1040
|
+
if (objectBinding?.kind !== "namespace" || objectBinding.source !== "wevu") return;
|
|
1516
1041
|
if (node.callee.property.name !== WE_VU_RUNTIME_APIS.defineComponent && node.callee.property.name !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
|
|
1517
1042
|
} else return;
|
|
1518
1043
|
const inlineObject = resolveOptionsObjectFromExpression(first);
|
|
@@ -1532,11 +1057,11 @@ function collectTargetOptionsObjects(ast, moduleId) {
|
|
|
1532
1057
|
if (!first || !t.isExpression(first)) return;
|
|
1533
1058
|
if (t.isIdentifier(callee)) {
|
|
1534
1059
|
const binding = module.importedBindings.get(callee.name);
|
|
1535
|
-
if (binding?.kind !== "named" || binding.source !==
|
|
1060
|
+
if (binding?.kind !== "named" || binding.source !== "wevu") return;
|
|
1536
1061
|
if (binding.importedName !== WE_VU_RUNTIME_APIS.defineComponent && binding.importedName !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
|
|
1537
1062
|
} else if (t.isMemberExpression(callee) && !callee.computed && t.isIdentifier(callee.object) && t.isIdentifier(callee.property)) {
|
|
1538
1063
|
const objectBinding = module.importedBindings.get(callee.object.name);
|
|
1539
|
-
if (objectBinding?.kind !== "namespace" || objectBinding.source !==
|
|
1064
|
+
if (objectBinding?.kind !== "namespace" || objectBinding.source !== "wevu") return;
|
|
1540
1065
|
if (callee.property.name !== WE_VU_RUNTIME_APIS.defineComponent && callee.property.name !== WE_VU_RUNTIME_APIS.createWevuComponent) return;
|
|
1541
1066
|
} else return;
|
|
1542
1067
|
const inlineObject = resolveOptionsObjectFromExpression(first);
|
|
@@ -1557,7 +1082,6 @@ function collectTargetOptionsObjects(ast, moduleId) {
|
|
|
1557
1082
|
module
|
|
1558
1083
|
};
|
|
1559
1084
|
}
|
|
1560
|
-
|
|
1561
1085
|
//#endregion
|
|
1562
1086
|
//#region src/plugins/wevu/pageFeatures/reachability/calls.ts
|
|
1563
1087
|
function getCallCalleeName(callee) {
|
|
@@ -1586,7 +1110,6 @@ function collectCalledBindingsFromFunctionBody(fn) {
|
|
|
1586
1110
|
});
|
|
1587
1111
|
return called;
|
|
1588
1112
|
}
|
|
1589
|
-
|
|
1590
1113
|
//#endregion
|
|
1591
1114
|
//#region src/plugins/wevu/pageFeatures/reachability/hooks.ts
|
|
1592
1115
|
function collectWevuHookCallsInFunctionBody(module, fn) {
|
|
@@ -1620,7 +1143,6 @@ function collectWevuHookCallsInFunctionBody(module, fn) {
|
|
|
1620
1143
|
});
|
|
1621
1144
|
return enabled;
|
|
1622
1145
|
}
|
|
1623
|
-
|
|
1624
1146
|
//#endregion
|
|
1625
1147
|
//#region src/plugins/wevu/pageFeatures/reachability/resolve.ts
|
|
1626
1148
|
function resolveExportedFunctionNode(module, exportName) {
|
|
@@ -1638,7 +1160,7 @@ function resolveExportedFunctionNode(module, exportName) {
|
|
|
1638
1160
|
return null;
|
|
1639
1161
|
}
|
|
1640
1162
|
async function resolveExternalFunction(resolver, importerId, source, exportName, moduleCache) {
|
|
1641
|
-
if (source ===
|
|
1163
|
+
if (source === "wevu") return null;
|
|
1642
1164
|
const resolvedId = await resolver.resolveId(source, importerId);
|
|
1643
1165
|
if (!resolvedId) return null;
|
|
1644
1166
|
const code = await resolver.loadCode(resolvedId);
|
|
@@ -1664,7 +1186,6 @@ async function resolveExternalFunction(resolver, importerId, source, exportName,
|
|
|
1664
1186
|
};
|
|
1665
1187
|
return null;
|
|
1666
1188
|
}
|
|
1667
|
-
|
|
1668
1189
|
//#endregion
|
|
1669
1190
|
//#region src/plugins/wevu/pageFeatures/reachability/walk.ts
|
|
1670
1191
|
async function walkReachableWevuFeatures(options) {
|
|
@@ -1755,7 +1276,6 @@ async function walkReachableWevuFeatures(options) {
|
|
|
1755
1276
|
}
|
|
1756
1277
|
return enabled;
|
|
1757
1278
|
}
|
|
1758
|
-
|
|
1759
1279
|
//#endregion
|
|
1760
1280
|
//#region src/plugins/wevu/pageFeatures/reachability/index.ts
|
|
1761
1281
|
async function collectWevuFeaturesFromSetupReachableImports(pageModule, setupFn, resolver, moduleCache) {
|
|
@@ -1766,7 +1286,6 @@ async function collectWevuFeaturesFromSetupReachableImports(pageModule, setupFn,
|
|
|
1766
1286
|
moduleCache
|
|
1767
1287
|
});
|
|
1768
1288
|
}
|
|
1769
|
-
|
|
1770
1289
|
//#endregion
|
|
1771
1290
|
//#region src/plugins/wevu/pageFeatures/inject.ts
|
|
1772
1291
|
/**
|
|
@@ -1830,7 +1349,6 @@ async function injectWevuPageFeaturesInJsWithResolver(source, options) {
|
|
|
1830
1349
|
transformed: true
|
|
1831
1350
|
};
|
|
1832
1351
|
}
|
|
1833
|
-
|
|
1834
1352
|
//#endregion
|
|
1835
1353
|
//#region src/plugins/wevu/pageFeatures/matcher.ts
|
|
1836
1354
|
/**
|
|
@@ -1881,7 +1399,6 @@ function createPageEntryMatcher(source) {
|
|
|
1881
1399
|
}
|
|
1882
1400
|
};
|
|
1883
1401
|
}
|
|
1884
|
-
|
|
1885
1402
|
//#endregion
|
|
1886
1403
|
//#region src/plugins/vue/transform/scriptTemplateMeta.ts
|
|
1887
1404
|
function injectTemplateComponentMeta(ast, templateComponentMeta) {
|
|
@@ -1925,7 +1442,6 @@ function injectTemplateComponentMeta(ast, templateComponentMeta) {
|
|
|
1925
1442
|
}
|
|
1926
1443
|
return changed;
|
|
1927
1444
|
}
|
|
1928
|
-
|
|
1929
1445
|
//#endregion
|
|
1930
1446
|
//#region src/plugins/vue/transform/scriptVueSfcTransform.ts
|
|
1931
1447
|
/**
|
|
@@ -1966,7 +1482,6 @@ function vueSfcTransformPlugin() {
|
|
|
1966
1482
|
}
|
|
1967
1483
|
};
|
|
1968
1484
|
}
|
|
1969
|
-
|
|
1970
1485
|
//#endregion
|
|
1971
1486
|
//#region src/plugins/vue/transform/scriptComponent.ts
|
|
1972
1487
|
function isDefineComponentCall(node, aliases) {
|
|
@@ -2025,7 +1540,6 @@ function resolveComponentOptionsObject(componentExpr) {
|
|
|
2025
1540
|
if (t.isCallExpression(normalized)) return resolveObjectExpressionFromAssignCall(normalized);
|
|
2026
1541
|
return null;
|
|
2027
1542
|
}
|
|
2028
|
-
|
|
2029
1543
|
//#endregion
|
|
2030
1544
|
//#region src/plugins/vue/transform/transformScript/collect.ts
|
|
2031
1545
|
function createCollectVisitors(state) {
|
|
@@ -2045,11 +1559,9 @@ function createCollectVisitors(state) {
|
|
|
2045
1559
|
}
|
|
2046
1560
|
};
|
|
2047
1561
|
}
|
|
2048
|
-
|
|
2049
1562
|
//#endregion
|
|
2050
1563
|
//#region src/plugins/vue/transform/constants.ts
|
|
2051
1564
|
const RUNTIME_IMPORT_PATH = WE_VU_MODULE_ID;
|
|
2052
|
-
|
|
2053
1565
|
//#endregion
|
|
2054
1566
|
//#region src/plugins/vue/transform/scriptRuntimeImport.ts
|
|
2055
1567
|
function ensureRuntimeImport(program, importedName, localName = importedName) {
|
|
@@ -2065,7 +1577,6 @@ function ensureRuntimeImport(program, importedName, localName = importedName) {
|
|
|
2065
1577
|
return t.isIdentifier(spec.local, { name: localName });
|
|
2066
1578
|
})) targetImport.specifiers.push(t.importSpecifier(t.identifier(localName), t.identifier(importedName)));
|
|
2067
1579
|
}
|
|
2068
|
-
|
|
2069
1580
|
//#endregion
|
|
2070
1581
|
//#region src/plugins/vue/transform/transformScript/imports.ts
|
|
2071
1582
|
function createImportVisitors(program, state) {
|
|
@@ -2126,7 +1637,6 @@ function createImportVisitors(program, state) {
|
|
|
2126
1637
|
}
|
|
2127
1638
|
} };
|
|
2128
1639
|
}
|
|
2129
|
-
|
|
2130
1640
|
//#endregion
|
|
2131
1641
|
//#region src/plugins/vue/transform/transformScript/macros/setupExpose.ts
|
|
2132
1642
|
function createSetupExposeVisitors(state) {
|
|
@@ -2148,7 +1658,6 @@ function createSetupExposeVisitors(state) {
|
|
|
2148
1658
|
}
|
|
2149
1659
|
} };
|
|
2150
1660
|
}
|
|
2151
|
-
|
|
2152
1661
|
//#endregion
|
|
2153
1662
|
//#region src/plugins/vue/transform/transformScript/macros/optional.ts
|
|
2154
1663
|
function isOptionalPatternNode(node) {
|
|
@@ -2186,7 +1695,6 @@ function stripOptionalFromPattern(pattern) {
|
|
|
2186
1695
|
}
|
|
2187
1696
|
return changed;
|
|
2188
1697
|
}
|
|
2189
|
-
|
|
2190
1698
|
//#endregion
|
|
2191
1699
|
//#region src/plugins/vue/transform/transformScript/macros/stripTypes.ts
|
|
2192
1700
|
function createStripTypesVisitors(state) {
|
|
@@ -2321,7 +1829,6 @@ function createStripTypesVisitors(state) {
|
|
|
2321
1829
|
}
|
|
2322
1830
|
};
|
|
2323
1831
|
}
|
|
2324
|
-
|
|
2325
1832
|
//#endregion
|
|
2326
1833
|
//#region src/plugins/vue/transform/transformScript/macros/index.ts
|
|
2327
1834
|
function createMacroVisitors(state) {
|
|
@@ -2330,9 +1837,8 @@ function createMacroVisitors(state) {
|
|
|
2330
1837
|
...createStripTypesVisitors(state)
|
|
2331
1838
|
};
|
|
2332
1839
|
}
|
|
2333
|
-
|
|
2334
1840
|
//#endregion
|
|
2335
|
-
//#region src/plugins/vue/transform/
|
|
1841
|
+
//#region src/plugins/vue/transform/classStyleComputedBuilders.ts
|
|
2336
1842
|
function createStaticObjectKey$1(key) {
|
|
2337
1843
|
return t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key);
|
|
2338
1844
|
}
|
|
@@ -2346,9 +1852,10 @@ function buildNormalizedExpression(binding, helpers) {
|
|
|
2346
1852
|
return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.tryStatement(t.blockStatement([t.returnStatement(exp)]), t.catchClause(t.identifier("__wv_expr_err"), t.blockStatement([t.returnStatement(t.identifier("undefined"))])), null)])), []);
|
|
2347
1853
|
}
|
|
2348
1854
|
const normalizeHelper = binding.type === "class" ? helpers.normalizeClass : helpers.normalizeStyle;
|
|
1855
|
+
const errorFallback = binding.errorFallback ?? "";
|
|
2349
1856
|
const exp = binding.expAst ? t.cloneNode(binding.expAst, true) : t.stringLiteral("");
|
|
2350
1857
|
const normalizedCall = t.callExpression(t.cloneNode(normalizeHelper), [exp]);
|
|
2351
|
-
return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.tryStatement(t.blockStatement([t.returnStatement(normalizedCall)]), t.catchClause(t.identifier("__wv_expr_err"), t.blockStatement([t.returnStatement(t.stringLiteral(
|
|
1858
|
+
return t.callExpression(t.arrowFunctionExpression([], t.blockStatement([t.tryStatement(t.blockStatement([t.returnStatement(normalizedCall)]), t.catchClause(t.identifier("__wv_expr_err"), t.blockStatement([t.returnStatement(t.stringLiteral(errorFallback))])), null)])), []);
|
|
2352
1859
|
}
|
|
2353
1860
|
function buildArrayMapExpression(binding, forStack, level, listId, helpers) {
|
|
2354
1861
|
const itemParam = createValidIdentifier(forStack[level].item, `__wv_item_${level}`);
|
|
@@ -2413,6 +1920,8 @@ function buildComputedFunctionBody(binding, helpers) {
|
|
|
2413
1920
|
const expr = buildForExpression(binding, binding.forStack ?? [], 0, helpers);
|
|
2414
1921
|
return t.blockStatement([t.returnStatement(expr)]);
|
|
2415
1922
|
}
|
|
1923
|
+
//#endregion
|
|
1924
|
+
//#region src/plugins/vue/transform/classStyleComputed.ts
|
|
2416
1925
|
function buildClassStyleComputedEntries(bindings, helpers) {
|
|
2417
1926
|
const entries = [];
|
|
2418
1927
|
for (const binding of bindings) {
|
|
@@ -2440,7 +1949,6 @@ function buildClassStyleComputedCode(bindings, helpers) {
|
|
|
2440
1949
|
const { code } = generate(obj, { compact: true });
|
|
2441
1950
|
return code;
|
|
2442
1951
|
}
|
|
2443
|
-
|
|
2444
1952
|
//#endregion
|
|
2445
1953
|
//#region src/plugins/vue/transform/transformScript/utils.ts
|
|
2446
1954
|
function isPlainRecord(value) {
|
|
@@ -2463,7 +1971,6 @@ function getObjectPropertyByKey$1(node, key) {
|
|
|
2463
1971
|
function createStaticObjectKey(key) {
|
|
2464
1972
|
return t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key);
|
|
2465
1973
|
}
|
|
2466
|
-
|
|
2467
1974
|
//#endregion
|
|
2468
1975
|
//#region src/plugins/vue/transform/transformScript/rewrite/classStyle.ts
|
|
2469
1976
|
function injectClassStyleComputed(optionsObject, bindings, warn) {
|
|
@@ -2496,7 +2003,6 @@ function ensureClassStyleRuntimeImports(program) {
|
|
|
2496
2003
|
ensureRuntimeImport(program, "normalizeStyle", "__wevuNormalizeStyle");
|
|
2497
2004
|
ensureRuntimeImport(program, "unref", "__wevuUnref");
|
|
2498
2005
|
}
|
|
2499
|
-
|
|
2500
2006
|
//#endregion
|
|
2501
2007
|
//#region src/plugins/vue/transform/transformScript/rewrite/defaults.ts
|
|
2502
2008
|
function mergePlainDefaultsIntoObjectExpression(target, defaults) {
|
|
@@ -2571,7 +2077,7 @@ function stripVirtualHostFromDefaults(defaults) {
|
|
|
2571
2077
|
const next = { ...defaults };
|
|
2572
2078
|
const options = next.options;
|
|
2573
2079
|
if (!isPlainRecord(options)) return next;
|
|
2574
|
-
if (!Object.
|
|
2080
|
+
if (!Object.hasOwn(options, "virtualHost")) return next;
|
|
2575
2081
|
const copiedOptions = { ...options };
|
|
2576
2082
|
delete copiedOptions.virtualHost;
|
|
2577
2083
|
if (Object.keys(copiedOptions).length > 0) next.options = copiedOptions;
|
|
@@ -2624,7 +2130,6 @@ function injectWevuDefaultsForApp(params) {
|
|
|
2624
2130
|
}
|
|
2625
2131
|
return changed;
|
|
2626
2132
|
}
|
|
2627
|
-
|
|
2628
2133
|
//#endregion
|
|
2629
2134
|
//#region src/plugins/vue/transform/transformScript/rewrite/export.ts
|
|
2630
2135
|
function rewriteComponentExport(params) {
|
|
@@ -2644,33 +2149,83 @@ function rewriteComponentExport(params) {
|
|
|
2644
2149
|
exportPath.insertAfter(t.expressionStatement(t.callExpression(t.identifier(WE_VU_RUNTIME_APIS.createWevuComponent), [t.identifier(DEFAULT_OPTIONS_IDENTIFIER)])));
|
|
2645
2150
|
return true;
|
|
2646
2151
|
}
|
|
2647
|
-
|
|
2648
2152
|
//#endregion
|
|
2649
|
-
//#region src/plugins/vue/
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2153
|
+
//#region src/plugins/vue/compiler/template/expression/parse.ts
|
|
2154
|
+
const babelExpressionCache = new LRUCache({ max: 1024 });
|
|
2155
|
+
new LRUCache({ max: 1024 });
|
|
2156
|
+
const BABEL_GENERATE_MINI_PROGRAM_OPTIONS = {
|
|
2157
|
+
compact: true,
|
|
2158
|
+
jsescOption: {
|
|
2159
|
+
quotes: "single",
|
|
2160
|
+
minimal: true
|
|
2161
|
+
}
|
|
2162
|
+
};
|
|
2163
|
+
function generateExpression(node) {
|
|
2164
|
+
const { code } = generate(node, BABEL_GENERATE_MINI_PROGRAM_OPTIONS);
|
|
2165
|
+
return code;
|
|
2166
|
+
}
|
|
2167
|
+
function parseBabelExpression(exp) {
|
|
2168
|
+
const cached = babelExpressionCache.get(exp);
|
|
2169
|
+
if (cached !== void 0) return cached === false ? null : cached;
|
|
2170
|
+
try {
|
|
2171
|
+
const stmt = parse$2(`(${exp})`, {
|
|
2172
|
+
sourceType: "module",
|
|
2173
|
+
plugins: ["typescript"]
|
|
2174
|
+
}).program.body[0];
|
|
2175
|
+
if (!stmt || !("expression" in stmt)) {
|
|
2176
|
+
babelExpressionCache.set(exp, false);
|
|
2177
|
+
return null;
|
|
2178
|
+
}
|
|
2179
|
+
const expression = stmt.expression;
|
|
2180
|
+
babelExpressionCache.set(exp, expression);
|
|
2181
|
+
return expression;
|
|
2182
|
+
} catch {
|
|
2183
|
+
babelExpressionCache.set(exp, false);
|
|
2184
|
+
return null;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
function parseBabelExpressionFile(exp) {
|
|
2188
|
+
try {
|
|
2189
|
+
const ast = parse$2(`(${exp})`, {
|
|
2190
|
+
sourceType: "module",
|
|
2191
|
+
plugins: ["typescript"]
|
|
2192
|
+
});
|
|
2193
|
+
const stmt = ast.program.body[0];
|
|
2194
|
+
if (!stmt || !("expression" in stmt)) return null;
|
|
2195
|
+
return {
|
|
2196
|
+
ast,
|
|
2197
|
+
expression: stmt.expression
|
|
2198
|
+
};
|
|
2199
|
+
} catch {
|
|
2200
|
+
return null;
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
//#endregion
|
|
2204
|
+
//#region src/plugins/vue/transform/transformScript/rewrite/inlineExpressions.ts
|
|
2205
|
+
function buildInlineMapExpression(inlineExpressions) {
|
|
2206
|
+
const entries = inlineExpressions.map((entry) => {
|
|
2207
|
+
const keysExpr = t.arrayExpression(entry.scopeKeys.map((key) => t.stringLiteral(key)));
|
|
2208
|
+
const exprAst = parseBabelExpression(entry.expression) ?? t.identifier("undefined");
|
|
2209
|
+
const fnExpr = t.arrowFunctionExpression([
|
|
2210
|
+
t.identifier("ctx"),
|
|
2211
|
+
t.identifier("scope"),
|
|
2212
|
+
t.identifier("$event")
|
|
2213
|
+
], exprAst);
|
|
2214
|
+
const entryObjProps = [t.objectProperty(t.identifier("keys"), keysExpr), t.objectProperty(t.identifier("fn"), fnExpr)];
|
|
2215
|
+
if (entry.indexBindings?.length) {
|
|
2216
|
+
const indexKeysExpr = t.arrayExpression(entry.indexBindings.map((binding) => t.stringLiteral(binding.key)));
|
|
2217
|
+
entryObjProps.push(t.objectProperty(t.identifier("indexKeys"), indexKeysExpr));
|
|
2218
|
+
}
|
|
2219
|
+
if (entry.scopeResolvers?.length) {
|
|
2220
|
+
const resolverMap = new Map(entry.scopeResolvers.map((item) => [item.key, item.expression]));
|
|
2221
|
+
const resolverExpr = t.arrayExpression(entry.scopeKeys.map((key) => {
|
|
2222
|
+
const source = resolverMap.get(key);
|
|
2223
|
+
if (!source) return t.identifier("undefined");
|
|
2224
|
+
return parseBabelExpression(source) ?? t.identifier("undefined");
|
|
2225
|
+
}));
|
|
2226
|
+
entryObjProps.push(t.objectProperty(t.identifier("scopeResolvers"), resolverExpr));
|
|
2227
|
+
}
|
|
2228
|
+
const entryObj = t.objectExpression(entryObjProps);
|
|
2674
2229
|
return t.objectProperty(t.stringLiteral(entry.id), entryObj);
|
|
2675
2230
|
});
|
|
2676
2231
|
return t.objectExpression(entries);
|
|
@@ -2714,7 +2269,110 @@ function injectInlineExpressions(componentExpr, inlineExpressions) {
|
|
|
2714
2269
|
}
|
|
2715
2270
|
return false;
|
|
2716
2271
|
}
|
|
2717
|
-
|
|
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
|
+
}
|
|
2718
2376
|
//#endregion
|
|
2719
2377
|
//#region src/plugins/vue/transform/transformScript/rewrite/templateRefs.ts
|
|
2720
2378
|
function buildTemplateRefEntry(binding) {
|
|
@@ -2749,7 +2407,6 @@ function injectTemplateRefs(optionsObject, bindings, warn) {
|
|
|
2749
2407
|
warnHandler("无法自动注入 template ref 元数据,请手动合并 __wevuTemplateRefs。");
|
|
2750
2408
|
return false;
|
|
2751
2409
|
}
|
|
2752
|
-
|
|
2753
2410
|
//#endregion
|
|
2754
2411
|
//#region src/plugins/vue/transform/transformScript/rewrite/index.ts
|
|
2755
2412
|
function hasStaticProperty(target, keyName) {
|
|
@@ -2779,7 +2436,7 @@ function resolveObjectExpressionFromProgram(program, name) {
|
|
|
2779
2436
|
const normalized = unwrapTypeLikeExpression(declarator.init);
|
|
2780
2437
|
if (t.isObjectExpression(normalized)) return normalized;
|
|
2781
2438
|
if (t.isCallExpression(normalized) && isObjectAssignCall(normalized)) {
|
|
2782
|
-
const lastArg = normalized.arguments
|
|
2439
|
+
const lastArg = normalized.arguments.at(-1);
|
|
2783
2440
|
if (lastArg && !t.isSpreadElement(lastArg) && t.isExpression(lastArg)) {
|
|
2784
2441
|
const lastNormalized = unwrapTypeLikeExpression(lastArg);
|
|
2785
2442
|
if (t.isObjectExpression(lastNormalized)) return lastNormalized;
|
|
@@ -2835,6 +2492,7 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
|
|
|
2835
2492
|
parsedWevuDefaults,
|
|
2836
2493
|
options
|
|
2837
2494
|
}) || transformed;
|
|
2495
|
+
if (componentOptionsObject) transformed = injectSetupInitialData(componentOptionsObject) || transformed;
|
|
2838
2496
|
const classStyleBindings = options?.classStyleBindings ?? [];
|
|
2839
2497
|
if (classStyleBindings.length) if (componentOptionsObject) {
|
|
2840
2498
|
ensureClassStyleRuntimeImports(ast.program);
|
|
@@ -2865,7 +2523,6 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
|
|
|
2865
2523
|
}
|
|
2866
2524
|
return transformed;
|
|
2867
2525
|
}
|
|
2868
|
-
|
|
2869
2526
|
//#endregion
|
|
2870
2527
|
//#region src/plugins/vue/transform/transformScript/index.ts
|
|
2871
2528
|
/**
|
|
@@ -2896,252 +2553,817 @@ function transformScript(source, options) {
|
|
|
2896
2553
|
transformed: false
|
|
2897
2554
|
};
|
|
2898
2555
|
return {
|
|
2899
|
-
code: generate(ast, { retainLines: true }).code,
|
|
2900
|
-
transformed: state.transformed
|
|
2556
|
+
code: generate(ast, { retainLines: true }).code,
|
|
2557
|
+
transformed: state.transformed
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
//#endregion
|
|
2561
|
+
//#region src/plugins/vue/compiler/template/expression/wxml.ts
|
|
2562
|
+
function templateLiteralToConcat(node) {
|
|
2563
|
+
const segments = [];
|
|
2564
|
+
node.quasis.forEach((quasi, index) => {
|
|
2565
|
+
const cooked = quasi.value.cooked ?? quasi.value.raw ?? "";
|
|
2566
|
+
if (cooked) segments.push(t.stringLiteral(cooked));
|
|
2567
|
+
if (index < node.expressions.length) {
|
|
2568
|
+
let inner = node.expressions[index];
|
|
2569
|
+
if (t.isTemplateLiteral(inner)) inner = templateLiteralToConcat(inner);
|
|
2570
|
+
segments.push(inner);
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
2573
|
+
if (segments.length === 0) return t.stringLiteral("");
|
|
2574
|
+
if (segments.length === 1) return segments[0];
|
|
2575
|
+
return segments.reduce((acc, cur) => t.binaryExpression("+", acc, cur));
|
|
2576
|
+
}
|
|
2577
|
+
function isOptionalChainNode(node) {
|
|
2578
|
+
return Boolean(node && (t.isOptionalMemberExpression(node) || t.isOptionalCallExpression(node)));
|
|
2579
|
+
}
|
|
2580
|
+
function collectOptionalChain(node) {
|
|
2581
|
+
const operations = [];
|
|
2582
|
+
let current = node;
|
|
2583
|
+
while (isOptionalChainNode(current)) {
|
|
2584
|
+
if (t.isOptionalMemberExpression(current)) {
|
|
2585
|
+
operations.push({
|
|
2586
|
+
type: "member",
|
|
2587
|
+
optional: current.optional === true,
|
|
2588
|
+
computed: current.computed,
|
|
2589
|
+
property: t.cloneNode(current.property)
|
|
2590
|
+
});
|
|
2591
|
+
current = current.object;
|
|
2592
|
+
continue;
|
|
2593
|
+
}
|
|
2594
|
+
operations.push({
|
|
2595
|
+
type: "call",
|
|
2596
|
+
optional: current.optional === true,
|
|
2597
|
+
args: current.arguments.map((arg) => t.cloneNode(arg))
|
|
2598
|
+
});
|
|
2599
|
+
current = current.callee;
|
|
2600
|
+
}
|
|
2601
|
+
if (!t.isExpression(current)) return null;
|
|
2602
|
+
return {
|
|
2603
|
+
base: t.cloneNode(current),
|
|
2604
|
+
operations: operations.reverse()
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
function applyOptionalChainOperation(base, operation) {
|
|
2608
|
+
if (operation.type === "member") return t.memberExpression(base, t.cloneNode(operation.property), operation.computed);
|
|
2609
|
+
return t.callExpression(base, operation.args.map((arg) => t.cloneNode(arg)));
|
|
2610
|
+
}
|
|
2611
|
+
function lowerOptionalChain(node) {
|
|
2612
|
+
const chain = collectOptionalChain(node);
|
|
2613
|
+
if (!chain) return t.cloneNode(node);
|
|
2614
|
+
const segments = [chain.base];
|
|
2615
|
+
for (const operation of chain.operations) {
|
|
2616
|
+
const currentBase = t.cloneNode(segments.at(-1));
|
|
2617
|
+
segments.push(applyOptionalChainOperation(currentBase, operation));
|
|
2618
|
+
}
|
|
2619
|
+
let lowered = t.cloneNode(segments.at(-1));
|
|
2620
|
+
for (let index = chain.operations.length - 1; index >= 0; index--) {
|
|
2621
|
+
if (!chain.operations[index].optional) continue;
|
|
2622
|
+
lowered = t.conditionalExpression(t.binaryExpression("==", t.cloneNode(segments[index]), t.nullLiteral()), t.identifier("undefined"), lowered);
|
|
2623
|
+
}
|
|
2624
|
+
return lowered;
|
|
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;
|
|
2631
|
+
function normalizeWxmlExpression(exp) {
|
|
2632
|
+
if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.")) return exp;
|
|
2633
|
+
try {
|
|
2634
|
+
const ast = parse$2(`(${exp})`, {
|
|
2635
|
+
sourceType: "module",
|
|
2636
|
+
plugins: ["typescript"]
|
|
2637
|
+
});
|
|
2638
|
+
const stmt = ast.program.body[0];
|
|
2639
|
+
if (!stmt || !("expression" in stmt)) return exp;
|
|
2640
|
+
traverse(ast, {
|
|
2641
|
+
OptionalMemberExpression: { exit(path) {
|
|
2642
|
+
if (isOptionalChainNode(path.parentPath.node)) return;
|
|
2643
|
+
path.replaceWith(lowerOptionalChain(path.node));
|
|
2644
|
+
path.skip();
|
|
2645
|
+
} },
|
|
2646
|
+
OptionalCallExpression: { exit(path) {
|
|
2647
|
+
if (isOptionalChainNode(path.parentPath.node)) return;
|
|
2648
|
+
path.replaceWith(lowerOptionalChain(path.node));
|
|
2649
|
+
path.skip();
|
|
2650
|
+
} },
|
|
2651
|
+
LogicalExpression(path) {
|
|
2652
|
+
if (path.node.operator !== "??") return;
|
|
2653
|
+
const left = path.node.left;
|
|
2654
|
+
const right = path.node.right;
|
|
2655
|
+
const test = t.binaryExpression("!=", t.cloneNode(left), t.nullLiteral());
|
|
2656
|
+
path.replaceWith(t.conditionalExpression(test, t.cloneNode(left), t.cloneNode(right)));
|
|
2657
|
+
path.skip();
|
|
2658
|
+
},
|
|
2659
|
+
TemplateLiteral(path) {
|
|
2660
|
+
if (t.isTaggedTemplateExpression(path.parent)) return;
|
|
2661
|
+
path.replaceWith(templateLiteralToConcat(path.node));
|
|
2662
|
+
}
|
|
2663
|
+
});
|
|
2664
|
+
const normalized = stmt.expression;
|
|
2665
|
+
return generateExpression(normalized);
|
|
2666
|
+
} catch {
|
|
2667
|
+
if (exp.startsWith("`") && exp.endsWith("`")) {
|
|
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, "");
|
|
2671
|
+
return rewritten;
|
|
2672
|
+
}
|
|
2673
|
+
return exp;
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
//#endregion
|
|
2677
|
+
//#region src/plugins/jsx/compileJsx/ast.ts
|
|
2678
|
+
const ESCAPED_TEXT_RE = /[&<>]/g;
|
|
2679
|
+
const ESCAPED_ATTR_RE = /[&"<>]/g;
|
|
2680
|
+
const ESCAPED_TEXT_MAP = {
|
|
2681
|
+
"&": "&",
|
|
2682
|
+
"<": "<",
|
|
2683
|
+
">": ">"
|
|
2684
|
+
};
|
|
2685
|
+
const ESCAPED_ATTR_MAP = {
|
|
2686
|
+
"&": "&",
|
|
2687
|
+
"\"": """,
|
|
2688
|
+
"<": "<",
|
|
2689
|
+
">": ">"
|
|
2690
|
+
};
|
|
2691
|
+
function escapeText(value) {
|
|
2692
|
+
return value.replace(ESCAPED_TEXT_RE, (ch) => ESCAPED_TEXT_MAP[ch] || ch);
|
|
2693
|
+
}
|
|
2694
|
+
function escapeAttr(value) {
|
|
2695
|
+
return value.replace(ESCAPED_ATTR_RE, (ch) => ESCAPED_ATTR_MAP[ch] || ch);
|
|
2696
|
+
}
|
|
2697
|
+
const WHITESPACE_RE = /\s+/g;
|
|
2698
|
+
function normalizeJsxText(value) {
|
|
2699
|
+
return value.replace(WHITESPACE_RE, " ");
|
|
2700
|
+
}
|
|
2701
|
+
function printExpression(exp) {
|
|
2702
|
+
return generate(exp).code;
|
|
2703
|
+
}
|
|
2704
|
+
function unwrapTsExpression$2(exp) {
|
|
2705
|
+
let current = exp;
|
|
2706
|
+
while (t.isTSAsExpression(current) || t.isTSTypeAssertion(current) || t.isTSNonNullExpression(current) || t.isParenthesizedExpression(current) || t.isTSInstantiationExpression(current)) {
|
|
2707
|
+
if (t.isTSAsExpression(current) || t.isTSTypeAssertion(current) || t.isTSNonNullExpression(current)) {
|
|
2708
|
+
current = current.expression;
|
|
2709
|
+
continue;
|
|
2710
|
+
}
|
|
2711
|
+
if (t.isParenthesizedExpression(current)) {
|
|
2712
|
+
current = current.expression;
|
|
2713
|
+
continue;
|
|
2714
|
+
}
|
|
2715
|
+
if (t.isTSInstantiationExpression(current)) current = current.expression;
|
|
2716
|
+
}
|
|
2717
|
+
return current;
|
|
2718
|
+
}
|
|
2719
|
+
function normalizeInterpolationExpression(exp) {
|
|
2720
|
+
return normalizeWxmlExpression(printExpression(unwrapTsExpression$2(exp)));
|
|
2721
|
+
}
|
|
2722
|
+
function renderMustache$1(expression, context) {
|
|
2723
|
+
return context.mustacheInterpolation === "spaced" ? `{{ ${expression} }}` : `{{${expression}}}`;
|
|
2724
|
+
}
|
|
2725
|
+
function pushScope$1(context, names) {
|
|
2726
|
+
for (const name of names) {
|
|
2727
|
+
if (!name) continue;
|
|
2728
|
+
context.scopeStack.push(name);
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
function popScope$1(context, count) {
|
|
2732
|
+
for (let i = 0; i < count; i += 1) context.scopeStack.pop();
|
|
2733
|
+
}
|
|
2734
|
+
function collectExpressionScopeBindings(exp, context) {
|
|
2735
|
+
const localSet = new Set(context.scopeStack);
|
|
2736
|
+
if (!localSet.size) return [];
|
|
2737
|
+
const used = [];
|
|
2738
|
+
const usedSet = /* @__PURE__ */ new Set();
|
|
2739
|
+
traverse(t.file(t.program([t.expressionStatement(t.cloneNode(exp, true))])), { Identifier(path) {
|
|
2740
|
+
if (!path.isReferencedIdentifier()) return;
|
|
2741
|
+
const name = path.node.name;
|
|
2742
|
+
if (!localSet.has(name)) return;
|
|
2743
|
+
if (path.scope.hasBinding(name)) return;
|
|
2744
|
+
if (usedSet.has(name)) return;
|
|
2745
|
+
usedSet.add(name);
|
|
2746
|
+
used.push(name);
|
|
2747
|
+
} });
|
|
2748
|
+
return used;
|
|
2749
|
+
}
|
|
2750
|
+
function registerInlineExpression$1(exp, context) {
|
|
2751
|
+
const scopeKeys = collectExpressionScopeBindings(exp, context);
|
|
2752
|
+
const id = `__wv_inline_${context.inlineExpressionSeed++}`;
|
|
2753
|
+
context.inlineExpressions.push({
|
|
2754
|
+
id,
|
|
2755
|
+
expression: printExpression(exp),
|
|
2756
|
+
scopeKeys
|
|
2757
|
+
});
|
|
2758
|
+
return {
|
|
2759
|
+
id,
|
|
2760
|
+
scopeKeys
|
|
2761
|
+
};
|
|
2762
|
+
}
|
|
2763
|
+
function toStaticObjectKey(key) {
|
|
2764
|
+
if (t.isIdentifier(key)) return key.name;
|
|
2765
|
+
if (t.isStringLiteral(key)) return key.value;
|
|
2766
|
+
return null;
|
|
2767
|
+
}
|
|
2768
|
+
function getObjectPropertyByKey(node, key) {
|
|
2769
|
+
for (const prop of node.properties) {
|
|
2770
|
+
if (t.isObjectMethod(prop)) {
|
|
2771
|
+
if (toStaticObjectKey(prop.key) === key) return prop;
|
|
2772
|
+
continue;
|
|
2773
|
+
}
|
|
2774
|
+
if (!t.isObjectProperty(prop) || prop.computed) continue;
|
|
2775
|
+
if (toStaticObjectKey(prop.key) === key) return prop;
|
|
2776
|
+
}
|
|
2777
|
+
return null;
|
|
2778
|
+
}
|
|
2779
|
+
function toJsxTagName(name, context) {
|
|
2780
|
+
if (t.isJSXIdentifier(name)) return name.name;
|
|
2781
|
+
if (t.isJSXNamespacedName(name)) return `${name.namespace.name}:${name.name.name}`;
|
|
2782
|
+
context.warnings.push("暂不支持 JSX 成员标签(如 <Foo.Bar />),已回退为 <view />。");
|
|
2783
|
+
return "view";
|
|
2784
|
+
}
|
|
2785
|
+
function resolveRenderableExpression(node) {
|
|
2786
|
+
if (t.isObjectMethod(node)) {
|
|
2787
|
+
for (const statement of node.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2788
|
+
return null;
|
|
2789
|
+
}
|
|
2790
|
+
if (!node.value) return null;
|
|
2791
|
+
const value = node.value;
|
|
2792
|
+
if (t.isArrowFunctionExpression(value)) {
|
|
2793
|
+
if (t.isBlockStatement(value.body)) {
|
|
2794
|
+
for (const statement of value.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2795
|
+
return null;
|
|
2796
|
+
}
|
|
2797
|
+
return unwrapTsExpression$2(value.body);
|
|
2798
|
+
}
|
|
2799
|
+
if (t.isFunctionExpression(value)) {
|
|
2800
|
+
for (const statement of value.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2801
|
+
}
|
|
2802
|
+
return null;
|
|
2803
|
+
}
|
|
2804
|
+
//#endregion
|
|
2805
|
+
//#region src/plugins/jsx/compileJsx/script.ts
|
|
2806
|
+
function removeRenderOptionFromObjectExpression(node) {
|
|
2807
|
+
const nextProps = node.properties.filter((prop) => {
|
|
2808
|
+
if (t.isObjectMethod(prop)) return toStaticObjectKey(prop.key) !== "render";
|
|
2809
|
+
if (t.isObjectProperty(prop) && !prop.computed) return toStaticObjectKey(prop.key) !== "render";
|
|
2810
|
+
return true;
|
|
2811
|
+
});
|
|
2812
|
+
const removed = nextProps.length !== node.properties.length;
|
|
2813
|
+
if (removed) node.properties = nextProps;
|
|
2814
|
+
return removed;
|
|
2815
|
+
}
|
|
2816
|
+
function stripRenderOptionFromScript(source, filename, warn) {
|
|
2817
|
+
let ast;
|
|
2818
|
+
try {
|
|
2819
|
+
ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
2820
|
+
} catch {
|
|
2821
|
+
return source;
|
|
2822
|
+
}
|
|
2823
|
+
const defineComponentAliases = new Set(["defineComponent", "_defineComponent"]);
|
|
2824
|
+
const defineComponentDecls = /* @__PURE__ */ new Map();
|
|
2825
|
+
let removedRender = false;
|
|
2826
|
+
let removedJsonMacroImport = false;
|
|
2827
|
+
traverse(ast, {
|
|
2828
|
+
ImportDeclaration(path) {
|
|
2829
|
+
const importSource = path.node.source.value;
|
|
2830
|
+
if (importSource === "wevu" || importSource === "vue") for (const specifier of path.node.specifiers) {
|
|
2831
|
+
if (!t.isImportSpecifier(specifier)) continue;
|
|
2832
|
+
if (!t.isIdentifier(specifier.imported, { name: "defineComponent" })) continue;
|
|
2833
|
+
defineComponentAliases.add(specifier.local.name);
|
|
2834
|
+
}
|
|
2835
|
+
if (importSource !== "weapp-vite") return;
|
|
2836
|
+
const retained = path.node.specifiers.filter((specifier) => {
|
|
2837
|
+
if (!t.isImportSpecifier(specifier)) return true;
|
|
2838
|
+
const importedName = t.isIdentifier(specifier.imported) ? specifier.imported.name : t.isStringLiteral(specifier.imported) ? specifier.imported.value : "";
|
|
2839
|
+
return !JSON_MACROS.has(importedName);
|
|
2840
|
+
});
|
|
2841
|
+
if (retained.length === path.node.specifiers.length) return;
|
|
2842
|
+
removedJsonMacroImport = true;
|
|
2843
|
+
if (retained.length === 0) path.remove();
|
|
2844
|
+
else path.node.specifiers = retained;
|
|
2845
|
+
},
|
|
2846
|
+
VariableDeclarator(path) {
|
|
2847
|
+
if (!t.isIdentifier(path.node.id) || !path.node.init) return;
|
|
2848
|
+
if (t.isObjectExpression(path.node.init)) {
|
|
2849
|
+
defineComponentDecls.set(path.node.id.name, path.node.init);
|
|
2850
|
+
return;
|
|
2851
|
+
}
|
|
2852
|
+
if (!t.isCallExpression(path.node.init)) return;
|
|
2853
|
+
const callee = path.node.init.callee;
|
|
2854
|
+
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
2855
|
+
const first = path.node.init.arguments[0];
|
|
2856
|
+
if (t.isObjectExpression(first)) defineComponentDecls.set(path.node.id.name, first);
|
|
2857
|
+
},
|
|
2858
|
+
ExportDefaultDeclaration(path) {
|
|
2859
|
+
const declaration = path.node.declaration;
|
|
2860
|
+
if (t.isDeclaration(declaration)) return;
|
|
2861
|
+
if (t.isObjectExpression(declaration)) {
|
|
2862
|
+
removedRender = removeRenderOptionFromObjectExpression(declaration) || removedRender;
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
if (t.isCallExpression(declaration)) {
|
|
2866
|
+
const callee = declaration.callee;
|
|
2867
|
+
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
2868
|
+
const first = declaration.arguments[0];
|
|
2869
|
+
if (t.isObjectExpression(first)) removedRender = removeRenderOptionFromObjectExpression(first) || removedRender;
|
|
2870
|
+
return;
|
|
2871
|
+
}
|
|
2872
|
+
if (t.isIdentifier(declaration)) {
|
|
2873
|
+
const target = defineComponentDecls.get(declaration.name);
|
|
2874
|
+
if (target) removedRender = removeRenderOptionFromObjectExpression(target) || removedRender;
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
});
|
|
2878
|
+
if (!removedRender) warn?.(`[JSX 编译] 未在 ${filename} 中移除 render 选项,输出脚本可能包含 JSX。`);
|
|
2879
|
+
if (!removedRender && !removedJsonMacroImport) return source;
|
|
2880
|
+
return generate(ast).code;
|
|
2881
|
+
}
|
|
2882
|
+
//#endregion
|
|
2883
|
+
//#region src/plugins/vue/compiler/template/platforms/alipay.ts
|
|
2884
|
+
const eventMap$3 = {
|
|
2885
|
+
click: "tap",
|
|
2886
|
+
dblclick: "tap",
|
|
2887
|
+
mousedown: "touchstart",
|
|
2888
|
+
mouseup: "touchend",
|
|
2889
|
+
tap: "tap",
|
|
2890
|
+
input: "input",
|
|
2891
|
+
change: "change",
|
|
2892
|
+
submit: "submit",
|
|
2893
|
+
focus: "focus",
|
|
2894
|
+
blur: "blur",
|
|
2895
|
+
confirm: "confirm",
|
|
2896
|
+
cancel: "cancel",
|
|
2897
|
+
load: "load",
|
|
2898
|
+
error: "error",
|
|
2899
|
+
scroll: "scroll",
|
|
2900
|
+
scrolltoupper: "scrolltoupper",
|
|
2901
|
+
scrolltolower: "scrolltolower",
|
|
2902
|
+
touchcancel: "touchcancel",
|
|
2903
|
+
longtap: "longtap",
|
|
2904
|
+
longpress: "longpress"
|
|
2905
|
+
};
|
|
2906
|
+
function toOnEventName(eventName) {
|
|
2907
|
+
if (!eventName) return "on";
|
|
2908
|
+
return `on${(eventName[0] ?? "").toUpperCase()}${eventName.slice(1)}`;
|
|
2909
|
+
}
|
|
2910
|
+
const EVENT_BINDING_PREFIX_RE$3 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2911
|
+
function parseEventBinding$3(eventName) {
|
|
2912
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$3.exec(eventName);
|
|
2913
|
+
if (prefixed) return {
|
|
2914
|
+
prefix: prefixed[1],
|
|
2915
|
+
name: prefixed[2]
|
|
2916
|
+
};
|
|
2917
|
+
return {
|
|
2918
|
+
prefix: "bind",
|
|
2919
|
+
name: eventName
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2922
|
+
function toAlipayDirectiveEvent(prefix, eventName) {
|
|
2923
|
+
if (!eventName) return "on";
|
|
2924
|
+
const pascalEvent = `${(eventName[0] ?? "").toUpperCase()}${eventName.slice(1)}`;
|
|
2925
|
+
switch (prefix) {
|
|
2926
|
+
case "catch": return `catch${pascalEvent}`;
|
|
2927
|
+
case "capture-bind": return `capture${pascalEvent}`;
|
|
2928
|
+
case "capture-catch": return `captureCatch${pascalEvent}`;
|
|
2929
|
+
default: return toOnEventName(eventName);
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
/**
|
|
2933
|
+
* 支付宝小程序平台适配器。
|
|
2934
|
+
*/
|
|
2935
|
+
const alipayPlatform = {
|
|
2936
|
+
name: "alipay",
|
|
2937
|
+
wrapIf: (exp, content, renderMustache) => `<block a:if="${renderMustache(exp)}">${content}</block>`,
|
|
2938
|
+
wrapElseIf: (exp, content, renderMustache) => `<block a:elif="${renderMustache(exp)}">${content}</block>`,
|
|
2939
|
+
wrapElse: (content) => `<block a:else>${content}</block>`,
|
|
2940
|
+
forAttrs: (listExp, renderMustache, item, index) => {
|
|
2941
|
+
const attrs = [`a:for="${renderMustache(listExp)}"`];
|
|
2942
|
+
if (item) attrs.push(`a:for-item="${item}"`);
|
|
2943
|
+
if (index) attrs.push(`a:for-index="${index}"`);
|
|
2944
|
+
return attrs;
|
|
2945
|
+
},
|
|
2946
|
+
keyThisValue: "*this",
|
|
2947
|
+
keyAttr: (value) => `a:key="${value}"`,
|
|
2948
|
+
mapEventName: (eventName) => eventMap$3[eventName] || eventName,
|
|
2949
|
+
eventBindingAttr: (eventName) => {
|
|
2950
|
+
const { prefix, name } = parseEventBinding$3(eventName);
|
|
2951
|
+
if (name.includes(":")) return `on:${name}`;
|
|
2952
|
+
return toAlipayDirectiveEvent(prefix, name);
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
//#endregion
|
|
2956
|
+
//#region src/plugins/vue/compiler/template/platforms/swan.ts
|
|
2957
|
+
const eventMap$2 = {
|
|
2958
|
+
click: "tap",
|
|
2959
|
+
dblclick: "tap",
|
|
2960
|
+
mousedown: "touchstart",
|
|
2961
|
+
mouseup: "touchend",
|
|
2962
|
+
tap: "tap",
|
|
2963
|
+
input: "input",
|
|
2964
|
+
change: "change",
|
|
2965
|
+
submit: "submit",
|
|
2966
|
+
focus: "focus",
|
|
2967
|
+
blur: "blur",
|
|
2968
|
+
confirm: "confirm",
|
|
2969
|
+
cancel: "cancel",
|
|
2970
|
+
load: "load",
|
|
2971
|
+
error: "error",
|
|
2972
|
+
scroll: "scroll",
|
|
2973
|
+
scrolltoupper: "scrolltoupper",
|
|
2974
|
+
scrolltolower: "scrolltolower",
|
|
2975
|
+
touchcancel: "touchcancel",
|
|
2976
|
+
longtap: "longtap",
|
|
2977
|
+
longpress: "longpress"
|
|
2978
|
+
};
|
|
2979
|
+
const EVENT_BINDING_PREFIX_RE$2 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
2980
|
+
function parseEventBinding$2(eventName) {
|
|
2981
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$2.exec(eventName);
|
|
2982
|
+
if (prefixed) return {
|
|
2983
|
+
prefix: prefixed[1],
|
|
2984
|
+
name: prefixed[2]
|
|
2985
|
+
};
|
|
2986
|
+
return {
|
|
2987
|
+
prefix: "bind",
|
|
2988
|
+
name: eventName
|
|
2901
2989
|
};
|
|
2902
2990
|
}
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
//#region src/plugins/jsx/compileJsxFile.ts
|
|
2906
|
-
const ESCAPED_TEXT_RE = /[&<>]/g;
|
|
2907
|
-
const ESCAPED_ATTR_RE = /[&"<>]/g;
|
|
2908
|
-
const ESCAPED_TEXT_MAP = {
|
|
2909
|
-
"&": "&",
|
|
2910
|
-
"<": "<",
|
|
2911
|
-
">": ">"
|
|
2912
|
-
};
|
|
2913
|
-
const ESCAPED_ATTR_MAP = {
|
|
2914
|
-
"&": "&",
|
|
2915
|
-
"\"": """,
|
|
2916
|
-
"<": "<",
|
|
2917
|
-
">": ">"
|
|
2918
|
-
};
|
|
2919
|
-
function escapeText(value) {
|
|
2920
|
-
return value.replace(ESCAPED_TEXT_RE, (ch) => ESCAPED_TEXT_MAP[ch] || ch);
|
|
2921
|
-
}
|
|
2922
|
-
function escapeAttr(value) {
|
|
2923
|
-
return value.replace(ESCAPED_ATTR_RE, (ch) => ESCAPED_ATTR_MAP[ch] || ch);
|
|
2924
|
-
}
|
|
2925
|
-
function normalizeJsxText(value) {
|
|
2926
|
-
return value.replace(/\s+/g, " ");
|
|
2927
|
-
}
|
|
2928
|
-
function printExpression(exp) {
|
|
2929
|
-
return generate(exp).code;
|
|
2991
|
+
function shouldUseColonEventBinding$2(name) {
|
|
2992
|
+
return name.includes(":") || name.includes("-");
|
|
2930
2993
|
}
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2994
|
+
/**
|
|
2995
|
+
* 百度智能小程序平台适配器。
|
|
2996
|
+
*/
|
|
2997
|
+
const swanPlatform = {
|
|
2998
|
+
name: "swan",
|
|
2999
|
+
wrapIf: (exp, content, renderMustache) => `<block s-if="${renderMustache(exp)}">${content}</block>`,
|
|
3000
|
+
wrapElseIf: (exp, content, renderMustache) => `<block s-elif="${renderMustache(exp)}">${content}</block>`,
|
|
3001
|
+
wrapElse: (content) => `<block s-else>${content}</block>`,
|
|
3002
|
+
forAttrs: (listExp, renderMustache, item, index) => {
|
|
3003
|
+
const attrs = [`s-for="${renderMustache(listExp)}"`];
|
|
3004
|
+
if (item) attrs.push(`s-for-item="${item}"`);
|
|
3005
|
+
if (index) attrs.push(`s-for-index="${index}"`);
|
|
3006
|
+
return attrs;
|
|
3007
|
+
},
|
|
3008
|
+
keyThisValue: "*this",
|
|
3009
|
+
keyAttr: (value) => `s-key="${value}"`,
|
|
3010
|
+
mapEventName: (eventName) => eventMap$2[eventName] || eventName,
|
|
3011
|
+
eventBindingAttr: (eventName) => {
|
|
3012
|
+
const { prefix, name } = parseEventBinding$2(eventName);
|
|
3013
|
+
switch (prefix) {
|
|
3014
|
+
case "catch": return shouldUseColonEventBinding$2(name) ? `catch:${name}` : `catch${name}`;
|
|
3015
|
+
case "capture-bind": return `capture-bind:${name}`;
|
|
3016
|
+
case "capture-catch": return `capture-catch:${name}`;
|
|
3017
|
+
case "mut-bind": return `mut-bind:${name}`;
|
|
3018
|
+
default: return shouldUseColonEventBinding$2(name) ? `bind:${name}` : `bind${name}`;
|
|
2941
3019
|
}
|
|
2942
|
-
if (t.isTSInstantiationExpression(current)) current = current.expression;
|
|
2943
3020
|
}
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
3021
|
+
};
|
|
3022
|
+
//#endregion
|
|
3023
|
+
//#region src/plugins/vue/compiler/template/platforms/tt.ts
|
|
3024
|
+
const eventMap$1 = {
|
|
3025
|
+
click: "tap",
|
|
3026
|
+
dblclick: "tap",
|
|
3027
|
+
mousedown: "touchstart",
|
|
3028
|
+
mouseup: "touchend",
|
|
3029
|
+
tap: "tap",
|
|
3030
|
+
input: "input",
|
|
3031
|
+
change: "change",
|
|
3032
|
+
submit: "submit",
|
|
3033
|
+
focus: "focus",
|
|
3034
|
+
blur: "blur",
|
|
3035
|
+
confirm: "confirm",
|
|
3036
|
+
cancel: "cancel",
|
|
3037
|
+
load: "load",
|
|
3038
|
+
error: "error",
|
|
3039
|
+
scroll: "scroll",
|
|
3040
|
+
scrolltoupper: "scrolltoupper",
|
|
3041
|
+
scrolltolower: "scrolltolower",
|
|
3042
|
+
touchcancel: "touchcancel",
|
|
3043
|
+
longtap: "longtap",
|
|
3044
|
+
longpress: "longpress"
|
|
3045
|
+
};
|
|
3046
|
+
const EVENT_BINDING_PREFIX_RE$1 = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
3047
|
+
function parseEventBinding$1(eventName) {
|
|
3048
|
+
const prefixed = EVENT_BINDING_PREFIX_RE$1.exec(eventName);
|
|
3049
|
+
if (prefixed) return {
|
|
3050
|
+
prefix: prefixed[1],
|
|
3051
|
+
name: prefixed[2]
|
|
3052
|
+
};
|
|
3053
|
+
return {
|
|
3054
|
+
prefix: "bind",
|
|
3055
|
+
name: eventName
|
|
3056
|
+
};
|
|
2948
3057
|
}
|
|
2949
|
-
function
|
|
2950
|
-
return
|
|
3058
|
+
function shouldUseColonEventBinding$1(name) {
|
|
3059
|
+
return name.includes(":") || name.includes("-");
|
|
2951
3060
|
}
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
3061
|
+
/**
|
|
3062
|
+
* 抖音小程序平台适配器。
|
|
3063
|
+
*/
|
|
3064
|
+
const ttPlatform = {
|
|
3065
|
+
name: "tt",
|
|
3066
|
+
wrapIf: (exp, content, renderMustache) => `<block tt:if="${renderMustache(exp)}">${content}</block>`,
|
|
3067
|
+
wrapElseIf: (exp, content, renderMustache) => `<block tt:elif="${renderMustache(exp)}">${content}</block>`,
|
|
3068
|
+
wrapElse: (content) => `<block tt:else>${content}</block>`,
|
|
3069
|
+
forAttrs: (listExp, renderMustache, item, index) => {
|
|
3070
|
+
const attrs = [`tt:for="${renderMustache(listExp)}"`];
|
|
3071
|
+
if (item) attrs.push(`tt:for-item="${item}"`);
|
|
3072
|
+
if (index) attrs.push(`tt:for-index="${index}"`);
|
|
3073
|
+
return attrs;
|
|
3074
|
+
},
|
|
3075
|
+
keyThisValue: "*this",
|
|
3076
|
+
keyAttr: (value) => `tt:key="${value}"`,
|
|
3077
|
+
mapEventName: (eventName) => eventMap$1[eventName] || eventName,
|
|
3078
|
+
eventBindingAttr: (eventName) => {
|
|
3079
|
+
const { prefix, name } = parseEventBinding$1(eventName);
|
|
3080
|
+
switch (prefix) {
|
|
3081
|
+
case "catch": return shouldUseColonEventBinding$1(name) ? `catch:${name}` : `catch${name}`;
|
|
3082
|
+
case "capture-bind": return `capture-bind:${name}`;
|
|
3083
|
+
case "capture-catch": return `capture-catch:${name}`;
|
|
3084
|
+
case "mut-bind": return `mut-bind:${name}`;
|
|
3085
|
+
default: return shouldUseColonEventBinding$1(name) ? `bind:${name}` : `bind${name}`;
|
|
3086
|
+
}
|
|
2956
3087
|
}
|
|
2957
|
-
}
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
3088
|
+
};
|
|
3089
|
+
//#endregion
|
|
3090
|
+
//#region src/plugins/vue/compiler/template/platforms/wechat.ts
|
|
3091
|
+
const eventMap = {
|
|
3092
|
+
click: "tap",
|
|
3093
|
+
dblclick: "tap",
|
|
3094
|
+
mousedown: "touchstart",
|
|
3095
|
+
mouseup: "touchend",
|
|
3096
|
+
tap: "tap",
|
|
3097
|
+
input: "input",
|
|
3098
|
+
change: "change",
|
|
3099
|
+
submit: "submit",
|
|
3100
|
+
focus: "focus",
|
|
3101
|
+
blur: "blur",
|
|
3102
|
+
confirm: "confirm",
|
|
3103
|
+
cancel: "cancel",
|
|
3104
|
+
load: "load",
|
|
3105
|
+
error: "error",
|
|
3106
|
+
scroll: "scroll",
|
|
3107
|
+
scrolltoupper: "scrolltoupper",
|
|
3108
|
+
scrolltolower: "scrolltolower",
|
|
3109
|
+
touchcancel: "touchcancel",
|
|
3110
|
+
longtap: "longtap",
|
|
3111
|
+
longpress: "longpress"
|
|
3112
|
+
};
|
|
3113
|
+
const EVENT_BINDING_PREFIX_RE = /^(bind|catch|capture-bind|capture-catch|mut-bind):(.+)$/;
|
|
3114
|
+
function parseEventBinding(eventName) {
|
|
3115
|
+
const prefixed = EVENT_BINDING_PREFIX_RE.exec(eventName);
|
|
3116
|
+
if (prefixed) return {
|
|
3117
|
+
prefix: prefixed[1],
|
|
3118
|
+
name: prefixed[2]
|
|
3119
|
+
};
|
|
2985
3120
|
return {
|
|
2986
|
-
|
|
2987
|
-
|
|
3121
|
+
prefix: "bind",
|
|
3122
|
+
name: eventName
|
|
2988
3123
|
};
|
|
2989
3124
|
}
|
|
2990
|
-
function
|
|
2991
|
-
|
|
2992
|
-
if (t.isStringLiteral(key)) return key.value;
|
|
2993
|
-
return null;
|
|
3125
|
+
function shouldUseColonEventBinding(name) {
|
|
3126
|
+
return name.includes(":") || name.includes("-");
|
|
2994
3127
|
}
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3128
|
+
/**
|
|
3129
|
+
* 微信小程序平台适配器。
|
|
3130
|
+
*/
|
|
3131
|
+
const wechatPlatform = {
|
|
3132
|
+
name: "wechat",
|
|
3133
|
+
wrapIf: (exp, content, renderMustache) => `<block wx:if="${renderMustache(exp)}">${content}</block>`,
|
|
3134
|
+
wrapElseIf: (exp, content, renderMustache) => `<block wx:elif="${renderMustache(exp)}">${content}</block>`,
|
|
3135
|
+
wrapElse: (content) => `<block wx:else>${content}</block>`,
|
|
3136
|
+
forAttrs: (listExp, renderMustache, item, index) => {
|
|
3137
|
+
const attrs = [`wx:for="${renderMustache(listExp)}"`];
|
|
3138
|
+
if (item) attrs.push(`wx:for-item="${item}"`);
|
|
3139
|
+
if (index) attrs.push(`wx:for-index="${index}"`);
|
|
3140
|
+
return attrs;
|
|
3141
|
+
},
|
|
3142
|
+
keyThisValue: "*this",
|
|
3143
|
+
keyAttr: (value) => `wx:key="${value}"`,
|
|
3144
|
+
mapEventName: (eventName) => eventMap[eventName] || eventName,
|
|
3145
|
+
eventBindingAttr: (eventName) => {
|
|
3146
|
+
const { prefix, name } = parseEventBinding(eventName);
|
|
3147
|
+
switch (prefix) {
|
|
3148
|
+
case "catch": return shouldUseColonEventBinding(name) ? `catch:${name}` : `catch${name}`;
|
|
3149
|
+
case "capture-bind": return `capture-bind:${name}`;
|
|
3150
|
+
case "capture-catch": return `capture-catch:${name}`;
|
|
3151
|
+
case "mut-bind": return `mut-bind:${name}`;
|
|
3152
|
+
default: return shouldUseColonEventBinding(name) ? `bind:${name}` : `bind${name}`;
|
|
3000
3153
|
}
|
|
3001
|
-
if (!t.isObjectProperty(prop) || prop.computed) continue;
|
|
3002
|
-
if (toStaticObjectKey(prop.key) === key) return prop;
|
|
3003
3154
|
}
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3155
|
+
};
|
|
3156
|
+
//#endregion
|
|
3157
|
+
//#region src/plugins/vue/compiler/template/platforms/index.ts
|
|
3158
|
+
const TEMPLATE_PLATFORMS = {
|
|
3159
|
+
weapp: wechatPlatform,
|
|
3160
|
+
alipay: alipayPlatform,
|
|
3161
|
+
tt: ttPlatform,
|
|
3162
|
+
swan: swanPlatform,
|
|
3163
|
+
jd: wechatPlatform,
|
|
3164
|
+
xhs: wechatPlatform
|
|
3165
|
+
};
|
|
3166
|
+
/**
|
|
3167
|
+
* 获取指定平台的模板适配器,默认回退到 wechat。
|
|
3168
|
+
*/
|
|
3169
|
+
function getMiniProgramTemplatePlatform(platform) {
|
|
3170
|
+
if (!platform) return wechatPlatform;
|
|
3171
|
+
return TEMPLATE_PLATFORMS[platform] ?? wechatPlatform;
|
|
3011
3172
|
}
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3173
|
+
//#endregion
|
|
3174
|
+
//#region src/plugins/jsx/compileJsx/analysis.ts
|
|
3175
|
+
function resolveRenderExpression(componentExpr, context) {
|
|
3176
|
+
if (!t.isObjectExpression(componentExpr)) {
|
|
3177
|
+
context.warnings.push("JSX 编译仅支持对象字面量组件选项。");
|
|
3015
3178
|
return null;
|
|
3016
3179
|
}
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
for (const statement of value.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
3022
|
-
return null;
|
|
3023
|
-
}
|
|
3024
|
-
return unwrapTsExpression$2(value.body);
|
|
3180
|
+
const renderNode = getObjectPropertyByKey(componentExpr, "render");
|
|
3181
|
+
if (!renderNode) {
|
|
3182
|
+
context.warnings.push("未找到 render(),请在默认导出组件中声明 render 函数。");
|
|
3183
|
+
return null;
|
|
3025
3184
|
}
|
|
3026
|
-
if (t.
|
|
3027
|
-
|
|
3185
|
+
if (!t.isObjectMethod(renderNode) && !t.isObjectProperty(renderNode)) {
|
|
3186
|
+
context.warnings.push("render 不是可执行函数。");
|
|
3187
|
+
return null;
|
|
3028
3188
|
}
|
|
3029
|
-
return
|
|
3030
|
-
}
|
|
3031
|
-
function removeRenderOptionFromObjectExpression(node) {
|
|
3032
|
-
const nextProps = node.properties.filter((prop) => {
|
|
3033
|
-
if (t.isObjectMethod(prop)) return toStaticObjectKey(prop.key) !== "render";
|
|
3034
|
-
if (t.isObjectProperty(prop) && !prop.computed) return toStaticObjectKey(prop.key) !== "render";
|
|
3035
|
-
return true;
|
|
3036
|
-
});
|
|
3037
|
-
const removed = nextProps.length !== node.properties.length;
|
|
3038
|
-
if (removed) node.properties = nextProps;
|
|
3039
|
-
return removed;
|
|
3189
|
+
return resolveRenderableExpression(renderNode);
|
|
3040
3190
|
}
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
} catch {
|
|
3046
|
-
return source;
|
|
3047
|
-
}
|
|
3191
|
+
/**
|
|
3192
|
+
* 单次遍历同时收集导入组件信息和默认导出表达式,避免多次 traverse 开销。
|
|
3193
|
+
*/
|
|
3194
|
+
function collectImportsAndExportDefault(ast) {
|
|
3048
3195
|
const defineComponentAliases = new Set(["defineComponent", "_defineComponent"]);
|
|
3049
3196
|
const defineComponentDecls = /* @__PURE__ */ new Map();
|
|
3050
|
-
|
|
3051
|
-
let
|
|
3197
|
+
const imports = /* @__PURE__ */ new Map();
|
|
3198
|
+
let exportDefaultExpression = null;
|
|
3052
3199
|
traverse(ast, {
|
|
3053
3200
|
ImportDeclaration(path) {
|
|
3054
|
-
const
|
|
3055
|
-
if (
|
|
3201
|
+
const source = path.node.source.value;
|
|
3202
|
+
if (source === "wevu" || source === "vue") for (const specifier of path.node.specifiers) {
|
|
3056
3203
|
if (!t.isImportSpecifier(specifier)) continue;
|
|
3057
3204
|
if (!t.isIdentifier(specifier.imported, { name: "defineComponent" })) continue;
|
|
3058
3205
|
defineComponentAliases.add(specifier.local.name);
|
|
3059
3206
|
}
|
|
3060
|
-
if (
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
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
|
+
}
|
|
3070
3232
|
},
|
|
3071
3233
|
VariableDeclarator(path) {
|
|
3072
3234
|
if (!t.isIdentifier(path.node.id) || !path.node.init) return;
|
|
3073
3235
|
if (t.isObjectExpression(path.node.init)) {
|
|
3074
|
-
defineComponentDecls.set(path.node.id.name, path.node.init);
|
|
3236
|
+
defineComponentDecls.set(path.node.id.name, t.cloneNode(path.node.init, true));
|
|
3075
3237
|
return;
|
|
3076
3238
|
}
|
|
3077
3239
|
if (!t.isCallExpression(path.node.init)) return;
|
|
3078
3240
|
const callee = path.node.init.callee;
|
|
3079
3241
|
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
3080
3242
|
const first = path.node.init.arguments[0];
|
|
3081
|
-
if (t.isObjectExpression(first)) defineComponentDecls.set(path.node.id.name, first);
|
|
3243
|
+
if (t.isObjectExpression(first)) defineComponentDecls.set(path.node.id.name, t.cloneNode(first, true));
|
|
3082
3244
|
},
|
|
3083
3245
|
ExportDefaultDeclaration(path) {
|
|
3084
3246
|
const declaration = path.node.declaration;
|
|
3085
3247
|
if (t.isDeclaration(declaration)) return;
|
|
3086
|
-
|
|
3087
|
-
removedRender = removeRenderOptionFromObjectExpression(declaration) || removedRender;
|
|
3088
|
-
return;
|
|
3089
|
-
}
|
|
3090
|
-
if (t.isCallExpression(declaration)) {
|
|
3091
|
-
const callee = declaration.callee;
|
|
3092
|
-
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
3093
|
-
const first = declaration.arguments[0];
|
|
3094
|
-
if (t.isObjectExpression(first)) removedRender = removeRenderOptionFromObjectExpression(first) || removedRender;
|
|
3095
|
-
return;
|
|
3096
|
-
}
|
|
3097
|
-
if (t.isIdentifier(declaration)) {
|
|
3098
|
-
const target = defineComponentDecls.get(declaration.name);
|
|
3099
|
-
if (target) removedRender = removeRenderOptionFromObjectExpression(target) || removedRender;
|
|
3100
|
-
}
|
|
3248
|
+
exportDefaultExpression = resolveComponentExpression(declaration, defineComponentDecls, defineComponentAliases);
|
|
3101
3249
|
}
|
|
3102
3250
|
});
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3251
|
+
return {
|
|
3252
|
+
importedComponents: [...imports.values()],
|
|
3253
|
+
exportDefaultExpression
|
|
3254
|
+
};
|
|
3106
3255
|
}
|
|
3107
|
-
function
|
|
3108
|
-
if (!
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3256
|
+
function isCollectableJsxTemplateTag(tag) {
|
|
3257
|
+
if (!tag) return false;
|
|
3258
|
+
if (RESERVED_VUE_COMPONENT_TAGS.has(tag)) return false;
|
|
3259
|
+
return !isBuiltinComponent(tag);
|
|
3260
|
+
}
|
|
3261
|
+
/**
|
|
3262
|
+
* 递归收集 JSX 表达式中的自定义组件标签名。
|
|
3263
|
+
* 直接遍历 AST 节点,无需 cloneNode 和 Babel traverse。
|
|
3264
|
+
*/
|
|
3265
|
+
function collectJsxTemplateTags(renderExpression) {
|
|
3266
|
+
const tags = /* @__PURE__ */ new Set();
|
|
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);
|
|
3275
|
+
}
|
|
3276
|
+
for (const child of node.children) walk(child);
|
|
3277
|
+
return;
|
|
3278
|
+
}
|
|
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);
|
|
3116
3312
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3313
|
+
walk(renderExpression);
|
|
3314
|
+
return tags;
|
|
3315
|
+
}
|
|
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);
|
|
3120
3327
|
}
|
|
3121
|
-
return
|
|
3328
|
+
return {
|
|
3329
|
+
renderExpression,
|
|
3330
|
+
autoComponentContext: {
|
|
3331
|
+
templateTags,
|
|
3332
|
+
importedComponents
|
|
3333
|
+
}
|
|
3334
|
+
};
|
|
3122
3335
|
}
|
|
3336
|
+
//#endregion
|
|
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]/;
|
|
3123
3343
|
function isEventBinding(name) {
|
|
3124
|
-
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);
|
|
3125
3345
|
}
|
|
3346
|
+
const LEADING_UPPER_RE = /^[A-Z]/;
|
|
3347
|
+
const UPPER_CHAR_RE = /[A-Z]/g;
|
|
3126
3348
|
function lowerEventName(name) {
|
|
3127
3349
|
if (!name) return name;
|
|
3128
|
-
return name.replace(
|
|
3350
|
+
return name.replace(LEADING_UPPER_RE, (s) => s.toLowerCase()).replace(UPPER_CHAR_RE, (s) => s.toLowerCase());
|
|
3129
3351
|
}
|
|
3130
3352
|
function toEventBindingName(rawName, context) {
|
|
3131
3353
|
const resolveEvent = (name) => context.platform.mapEventName(lowerEventName(name));
|
|
3132
|
-
if (
|
|
3354
|
+
if (CAPTURE_BIND_EVENT_RE.test(rawName)) {
|
|
3133
3355
|
const eventName = resolveEvent(rawName.slice(11));
|
|
3134
3356
|
return context.platform.eventBindingAttr(`capture-bind:${eventName}`);
|
|
3135
3357
|
}
|
|
3136
|
-
if (
|
|
3358
|
+
if (CAPTURE_CATCH_EVENT_RE.test(rawName)) {
|
|
3137
3359
|
const eventName = resolveEvent(rawName.slice(12));
|
|
3138
3360
|
return context.platform.eventBindingAttr(`capture-catch:${eventName}`);
|
|
3139
3361
|
}
|
|
3140
|
-
if (
|
|
3362
|
+
if (MUT_BIND_EVENT_RE.test(rawName)) {
|
|
3141
3363
|
const eventName = resolveEvent(rawName.slice(7));
|
|
3142
3364
|
return context.platform.eventBindingAttr(`mut-bind:${eventName}`);
|
|
3143
3365
|
}
|
|
3144
|
-
if (
|
|
3366
|
+
if (CATCH_EVENT_RE.test(rawName)) {
|
|
3145
3367
|
const eventName = resolveEvent(rawName.slice(5));
|
|
3146
3368
|
return context.platform.eventBindingAttr(`catch:${eventName}`);
|
|
3147
3369
|
}
|
|
@@ -3210,6 +3432,8 @@ function compileJsxAttributes(attributes, context) {
|
|
|
3210
3432
|
}
|
|
3211
3433
|
return output;
|
|
3212
3434
|
}
|
|
3435
|
+
//#endregion
|
|
3436
|
+
//#region src/plugins/jsx/compileJsx/render.ts
|
|
3213
3437
|
function compileListExpression(exp) {
|
|
3214
3438
|
return normalizeInterpolationExpression(exp);
|
|
3215
3439
|
}
|
|
@@ -3327,129 +3551,10 @@ function compileJsxElement(node, context) {
|
|
|
3327
3551
|
if (node.openingElement.selfClosing) return `<${tag}${attrsSegment} />`;
|
|
3328
3552
|
return `<${tag}${attrsSegment}>${compileJsxChildren(node.children, context)}</${tag}>`;
|
|
3329
3553
|
}
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
let exportDefaultExpression = null;
|
|
3334
|
-
traverse(ast, {
|
|
3335
|
-
ImportDeclaration(path) {
|
|
3336
|
-
const source = path.node.source.value;
|
|
3337
|
-
if (source !== "wevu" && source !== "vue") return;
|
|
3338
|
-
for (const specifier of path.node.specifiers) {
|
|
3339
|
-
if (!t.isImportSpecifier(specifier)) continue;
|
|
3340
|
-
if (!t.isIdentifier(specifier.imported, { name: "defineComponent" })) continue;
|
|
3341
|
-
defineComponentAliases.add(specifier.local.name);
|
|
3342
|
-
}
|
|
3343
|
-
},
|
|
3344
|
-
VariableDeclarator(path) {
|
|
3345
|
-
if (!t.isIdentifier(path.node.id) || !path.node.init) return;
|
|
3346
|
-
if (t.isObjectExpression(path.node.init)) {
|
|
3347
|
-
defineComponentDecls.set(path.node.id.name, t.cloneNode(path.node.init, true));
|
|
3348
|
-
return;
|
|
3349
|
-
}
|
|
3350
|
-
if (!t.isCallExpression(path.node.init)) return;
|
|
3351
|
-
const callee = path.node.init.callee;
|
|
3352
|
-
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
3353
|
-
const first = path.node.init.arguments[0];
|
|
3354
|
-
if (t.isObjectExpression(first)) defineComponentDecls.set(path.node.id.name, t.cloneNode(first, true));
|
|
3355
|
-
},
|
|
3356
|
-
ExportDefaultDeclaration(path) {
|
|
3357
|
-
const declaration = path.node.declaration;
|
|
3358
|
-
if (t.isDeclaration(declaration)) return;
|
|
3359
|
-
exportDefaultExpression = resolveComponentExpression(declaration, defineComponentDecls, defineComponentAliases);
|
|
3360
|
-
}
|
|
3361
|
-
});
|
|
3362
|
-
return exportDefaultExpression;
|
|
3363
|
-
}
|
|
3364
|
-
function isCollectableJsxTemplateTag(tag) {
|
|
3365
|
-
if (!tag) return false;
|
|
3366
|
-
if (RESERVED_VUE_COMPONENT_TAGS.has(tag)) return false;
|
|
3367
|
-
return !isBuiltinComponent(tag);
|
|
3368
|
-
}
|
|
3369
|
-
function collectJsxTemplateTags(renderExpression) {
|
|
3370
|
-
const tags = /* @__PURE__ */ new Set();
|
|
3371
|
-
traverse(t.file(t.program([t.expressionStatement(t.cloneNode(renderExpression, true))])), { JSXOpeningElement(path) {
|
|
3372
|
-
const { name } = path.node;
|
|
3373
|
-
if (t.isJSXMemberExpression(name)) return;
|
|
3374
|
-
let tag = null;
|
|
3375
|
-
if (t.isJSXIdentifier(name)) tag = name.name;
|
|
3376
|
-
else if (t.isJSXNamespacedName(name)) tag = `${name.namespace.name}:${name.name.name}`;
|
|
3377
|
-
if (!tag || !isCollectableJsxTemplateTag(tag)) return;
|
|
3378
|
-
tags.add(tag);
|
|
3379
|
-
} });
|
|
3380
|
-
return tags;
|
|
3381
|
-
}
|
|
3382
|
-
function collectImportedComponents(ast) {
|
|
3383
|
-
const imports = /* @__PURE__ */ new Map();
|
|
3384
|
-
traverse(ast, { ImportDeclaration(path) {
|
|
3385
|
-
if (path.node.importKind === "type") return;
|
|
3386
|
-
if (!t.isStringLiteral(path.node.source)) return;
|
|
3387
|
-
const importSource = path.node.source.value;
|
|
3388
|
-
for (const specifier of path.node.specifiers) {
|
|
3389
|
-
if ("importKind" in specifier && specifier.importKind === "type") continue;
|
|
3390
|
-
if (!("local" in specifier) || !t.isIdentifier(specifier.local)) continue;
|
|
3391
|
-
const localName = specifier.local.name;
|
|
3392
|
-
if (t.isImportDefaultSpecifier(specifier)) {
|
|
3393
|
-
imports.set(localName, {
|
|
3394
|
-
localName,
|
|
3395
|
-
importSource,
|
|
3396
|
-
importedName: "default",
|
|
3397
|
-
kind: "default"
|
|
3398
|
-
});
|
|
3399
|
-
continue;
|
|
3400
|
-
}
|
|
3401
|
-
if (!t.isImportSpecifier(specifier)) continue;
|
|
3402
|
-
const importedName = t.isIdentifier(specifier.imported) ? specifier.imported.name : t.isStringLiteral(specifier.imported) ? specifier.imported.value : void 0;
|
|
3403
|
-
imports.set(localName, {
|
|
3404
|
-
localName,
|
|
3405
|
-
importSource,
|
|
3406
|
-
importedName,
|
|
3407
|
-
kind: "named"
|
|
3408
|
-
});
|
|
3409
|
-
}
|
|
3410
|
-
} });
|
|
3411
|
-
return Array.from(imports.values());
|
|
3412
|
-
}
|
|
3413
|
-
function collectJsxAutoComponentContext(source, filename, warn) {
|
|
3414
|
-
const empty = {
|
|
3415
|
-
templateTags: /* @__PURE__ */ new Set(),
|
|
3416
|
-
importedComponents: []
|
|
3417
|
-
};
|
|
3418
|
-
let ast;
|
|
3419
|
-
try {
|
|
3420
|
-
ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
3421
|
-
} catch (error) {
|
|
3422
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3423
|
-
warn?.(`[JSX 编译] 解析 ${filename} 失败,已跳过自动 usingComponents 推导:${message}`);
|
|
3424
|
-
return empty;
|
|
3425
|
-
}
|
|
3426
|
-
const importedComponents = collectImportedComponents(ast);
|
|
3427
|
-
const context = {
|
|
3428
|
-
platform: wechatPlatform,
|
|
3429
|
-
mustacheInterpolation: "compact",
|
|
3430
|
-
warnings: [],
|
|
3431
|
-
inlineExpressions: [],
|
|
3432
|
-
inlineExpressionSeed: 0,
|
|
3433
|
-
scopeStack: []
|
|
3434
|
-
};
|
|
3435
|
-
const componentExpr = findExportDefaultExpression(ast);
|
|
3436
|
-
if (!componentExpr) return {
|
|
3437
|
-
templateTags: /* @__PURE__ */ new Set(),
|
|
3438
|
-
importedComponents
|
|
3439
|
-
};
|
|
3440
|
-
const renderExpression = resolveRenderExpression(componentExpr, context);
|
|
3441
|
-
if (!renderExpression) return {
|
|
3442
|
-
templateTags: /* @__PURE__ */ new Set(),
|
|
3443
|
-
importedComponents
|
|
3444
|
-
};
|
|
3554
|
+
//#endregion
|
|
3555
|
+
//#region src/plugins/jsx/compileJsx/template.ts
|
|
3556
|
+
function createJsxCompileContext(options) {
|
|
3445
3557
|
return {
|
|
3446
|
-
templateTags: collectJsxTemplateTags(renderExpression),
|
|
3447
|
-
importedComponents
|
|
3448
|
-
};
|
|
3449
|
-
}
|
|
3450
|
-
function compileJsxTemplate(source, filename, options) {
|
|
3451
|
-
const ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
3452
|
-
const context = {
|
|
3453
3558
|
platform: options?.template?.platform ?? wechatPlatform,
|
|
3454
3559
|
mustacheInterpolation: options?.template?.mustacheInterpolation ?? "compact",
|
|
3455
3560
|
warnings: [],
|
|
@@ -3457,27 +3562,28 @@ function compileJsxTemplate(source, filename, options) {
|
|
|
3457
3562
|
inlineExpressionSeed: 0,
|
|
3458
3563
|
scopeStack: []
|
|
3459
3564
|
};
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
template: void 0,
|
|
3472
|
-
warnings: context.warnings,
|
|
3473
|
-
inlineExpressions: context.inlineExpressions
|
|
3474
|
-
};
|
|
3565
|
+
}
|
|
3566
|
+
/**
|
|
3567
|
+
* 单次解析同时编译模板和收集自动组件上下文,避免重复 babelParse 和 traverse。
|
|
3568
|
+
*/
|
|
3569
|
+
function compileJsxTemplateAndCollectComponents(source, filename, options) {
|
|
3570
|
+
const ast = parse$2(source, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
3571
|
+
const context = createJsxCompileContext(options);
|
|
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);
|
|
3475
3576
|
return {
|
|
3476
|
-
template
|
|
3577
|
+
template,
|
|
3477
3578
|
warnings: context.warnings,
|
|
3478
|
-
inlineExpressions: context.inlineExpressions
|
|
3579
|
+
inlineExpressions: context.inlineExpressions,
|
|
3580
|
+
autoComponentContext
|
|
3479
3581
|
};
|
|
3480
3582
|
}
|
|
3583
|
+
//#endregion
|
|
3584
|
+
//#region src/plugins/jsx/compileJsxFile.ts
|
|
3585
|
+
const LEADING_DOT_RE = /^\./;
|
|
3586
|
+
const SETUP_CALL_RE$1 = /\bsetup\s*\(/;
|
|
3481
3587
|
/**
|
|
3482
3588
|
* 编译 JSX/TSX 文件,输出 wevu 脚本与 WXML 模板。
|
|
3483
3589
|
*/
|
|
@@ -3491,7 +3597,7 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3491
3597
|
let scriptSource = source;
|
|
3492
3598
|
let scriptMacroConfig;
|
|
3493
3599
|
let scriptMacroHash;
|
|
3494
|
-
const scriptLang = path.extname(filename).replace(
|
|
3600
|
+
const scriptLang = path.extname(filename).replace(LEADING_DOT_RE, "") || void 0;
|
|
3495
3601
|
try {
|
|
3496
3602
|
const extracted = await extractJsonMacroFromScriptSetup(source, filename, scriptLang, { merge: (target, incoming) => mergeJson(target, incoming, "macro") });
|
|
3497
3603
|
scriptSource = extracted.stripped;
|
|
@@ -3501,8 +3607,7 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3501
3607
|
const message = error instanceof Error ? error.message : String(error);
|
|
3502
3608
|
throw new Error(`解析 ${filename} 失败:${message}`);
|
|
3503
3609
|
}
|
|
3504
|
-
const
|
|
3505
|
-
const autoComponentContext = collectJsxAutoComponentContext(source, filename, options?.warn);
|
|
3610
|
+
const { template: compiledTemplateStr, warnings: templateWarnings, inlineExpressions, autoComponentContext } = compileJsxTemplateAndCollectComponents(source, filename, options);
|
|
3506
3611
|
const autoUsingComponentsMap = {};
|
|
3507
3612
|
if (options?.autoUsingComponents?.resolveUsingComponentPath && autoComponentContext.templateTags.size > 0) for (const imported of autoComponentContext.importedComponents) {
|
|
3508
3613
|
if (!autoComponentContext.templateTags.has(imported.localName)) continue;
|
|
@@ -3534,9 +3639,9 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3534
3639
|
isPage: options?.isPage,
|
|
3535
3640
|
warn: options?.warn,
|
|
3536
3641
|
wevuDefaults: options?.wevuDefaults,
|
|
3537
|
-
inlineExpressions
|
|
3642
|
+
inlineExpressions
|
|
3538
3643
|
});
|
|
3539
|
-
if (
|
|
3644
|
+
if (templateWarnings.length && options?.warn) templateWarnings.forEach((message) => options.warn?.(`[JSX 编译] ${message}`));
|
|
3540
3645
|
let configObj;
|
|
3541
3646
|
if (Object.keys(autoUsingComponentsMap).length > 0 || Object.keys(autoImportTagsMap).length > 0) {
|
|
3542
3647
|
const existingRaw = configObj?.usingComponents;
|
|
@@ -3555,26 +3660,25 @@ async function compileJsxFile(source, filename, options) {
|
|
|
3555
3660
|
if (scriptMacroConfig && Object.keys(scriptMacroConfig).length > 0) configObj = mergeJson(configObj ?? {}, scriptMacroConfig, "macro");
|
|
3556
3661
|
return {
|
|
3557
3662
|
script: transformedScript.code,
|
|
3558
|
-
template:
|
|
3663
|
+
template: compiledTemplateStr,
|
|
3559
3664
|
config: configObj && Object.keys(configObj).length > 0 ? JSON.stringify(configObj, null, 2) : void 0,
|
|
3560
3665
|
meta: {
|
|
3561
3666
|
hasScriptSetup: false,
|
|
3562
|
-
hasSetupOption:
|
|
3667
|
+
hasSetupOption: SETUP_CALL_RE$1.test(normalizedScriptSource),
|
|
3563
3668
|
jsonMacroHash: scriptMacroHash
|
|
3564
3669
|
}
|
|
3565
3670
|
};
|
|
3566
3671
|
}
|
|
3567
|
-
|
|
3568
3672
|
//#endregion
|
|
3569
3673
|
//#region src/utils/text.ts
|
|
3674
|
+
const CRLF_RE = /\r\n?/g;
|
|
3570
3675
|
/**
|
|
3571
3676
|
* 统一文本换行符为 LF,消除不同系统(CRLF/CR/LF)差异。
|
|
3572
3677
|
*/
|
|
3573
3678
|
function normalizeLineEndings(source) {
|
|
3574
3679
|
if (!source.includes("\r")) return source;
|
|
3575
|
-
return source.replace(
|
|
3680
|
+
return source.replace(CRLF_RE, "\n");
|
|
3576
3681
|
}
|
|
3577
|
-
|
|
3578
3682
|
//#endregion
|
|
3579
3683
|
//#region src/plugins/utils/cache.ts
|
|
3580
3684
|
const mtimeCache = /* @__PURE__ */ new Map();
|
|
@@ -3652,7 +3756,6 @@ function clearFileCaches() {
|
|
|
3652
3756
|
loadCache.clear();
|
|
3653
3757
|
pathExistsCache.clear();
|
|
3654
3758
|
}
|
|
3655
|
-
|
|
3656
3759
|
//#endregion
|
|
3657
3760
|
//#region src/utils/cachePolicy.ts
|
|
3658
3761
|
/**
|
|
@@ -3661,11 +3764,10 @@ function clearFileCaches() {
|
|
|
3661
3764
|
function getReadFileCheckMtime(config) {
|
|
3662
3765
|
return Boolean(config?.isDev);
|
|
3663
3766
|
}
|
|
3664
|
-
|
|
3665
3767
|
//#endregion
|
|
3666
3768
|
//#region src/utils/viteId.ts
|
|
3667
3769
|
const VUE_VIRTUAL_MODULE_PREFIX = "\0vue:";
|
|
3668
|
-
const BACKSLASH_RE = /\\/g;
|
|
3770
|
+
const BACKSLASH_RE$3 = /\\/g;
|
|
3669
3771
|
function normalizeViteId(id, options) {
|
|
3670
3772
|
const stripQuery = options?.stripQuery !== false;
|
|
3671
3773
|
const fileProtocolToPathEnabled = options?.fileProtocolToPath !== false;
|
|
@@ -3674,7 +3776,7 @@ function normalizeViteId(id, options) {
|
|
|
3674
3776
|
const stripLeadingNullByte = options?.stripLeadingNullByte === true;
|
|
3675
3777
|
let clean = id;
|
|
3676
3778
|
if (stripVueVirtualPrefix && clean.startsWith(VUE_VIRTUAL_MODULE_PREFIX)) clean = clean.slice(5);
|
|
3677
|
-
if (clean.includes("\\")) clean = clean.replace(BACKSLASH_RE, "/");
|
|
3779
|
+
if (clean.includes("\\")) clean = clean.replace(BACKSLASH_RE$3, "/");
|
|
3678
3780
|
if (stripQuery) clean = clean.split("?", 1)[0];
|
|
3679
3781
|
if (fileProtocolToPathEnabled && clean.startsWith("file://")) try {
|
|
3680
3782
|
clean = fileURLToPath(clean);
|
|
@@ -3683,7 +3785,6 @@ function normalizeViteId(id, options) {
|
|
|
3683
3785
|
if (stripLeadingNullByte && clean.startsWith("\0")) clean = clean.slice(1);
|
|
3684
3786
|
return clean;
|
|
3685
3787
|
}
|
|
3686
|
-
|
|
3687
3788
|
//#endregion
|
|
3688
3789
|
//#region src/utils/resolvedId.ts
|
|
3689
3790
|
function isSkippableResolvedId(id) {
|
|
@@ -3707,13 +3808,8 @@ function normalizeFsResolvedId(id, options) {
|
|
|
3707
3808
|
if (options?.stripLeadingNullByte) normalizeOptions.stripLeadingNullByte = true;
|
|
3708
3809
|
return normalizeViteId(id, normalizeOptions);
|
|
3709
3810
|
}
|
|
3710
|
-
|
|
3711
3811
|
//#endregion
|
|
3712
|
-
//#region src/plugins/utils/
|
|
3713
|
-
const sfcParseCache = new LRUCache({ max: 512 });
|
|
3714
|
-
const SCRIPT_SETUP_SRC_ATTR = "data-weapp-vite-src";
|
|
3715
|
-
const SCRIPT_SRC_ATTR = "data-weapp-vite-script-src";
|
|
3716
|
-
const SCRIPT_SETUP_TAG_RE = /<script\b([^>]*)>/gi;
|
|
3812
|
+
//#region src/plugins/utils/vueSfcBlockSrc.ts
|
|
3717
3813
|
const SCRIPT_LANG_EXT = new Map([
|
|
3718
3814
|
[".ts", "ts"],
|
|
3719
3815
|
[".tsx", "tsx"],
|
|
@@ -3747,46 +3843,6 @@ function getBlockLabel(kind) {
|
|
|
3747
3843
|
if (kind === "script setup") return "script setup";
|
|
3748
3844
|
return kind;
|
|
3749
3845
|
}
|
|
3750
|
-
/**
|
|
3751
|
-
* 预处理 `<script setup src>`,避免编译器丢失 src。
|
|
3752
|
-
*/
|
|
3753
|
-
function preprocessScriptSetupSrc(source) {
|
|
3754
|
-
if (!source.includes("<script") || !source.includes("setup") || !source.includes("src")) return source;
|
|
3755
|
-
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
3756
|
-
if (!/\bsetup\b/i.test(attrs) || !/\bsrc\b/i.test(attrs)) return full;
|
|
3757
|
-
return `<script${attrs.replace(/\bsrc(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))/i, `${SCRIPT_SETUP_SRC_ATTR}$1`)}>`;
|
|
3758
|
-
});
|
|
3759
|
-
}
|
|
3760
|
-
/**
|
|
3761
|
-
* 预处理普通 `<script src>`,避免编译器丢失 src。
|
|
3762
|
-
*/
|
|
3763
|
-
function preprocessScriptSrc(source) {
|
|
3764
|
-
if (!source.includes("<script") || !source.includes("src")) return source;
|
|
3765
|
-
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
3766
|
-
if (/\bsetup\b/i.test(attrs) || !/\bsrc\b/i.test(attrs)) return full;
|
|
3767
|
-
return `<script${attrs.replace(/\bsrc(\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))/i, `${SCRIPT_SRC_ATTR}$1`)}>`;
|
|
3768
|
-
});
|
|
3769
|
-
}
|
|
3770
|
-
/**
|
|
3771
|
-
* 将预处理的 `<script setup src>` 恢复为真实 src。
|
|
3772
|
-
*/
|
|
3773
|
-
function restoreScriptSetupSrc(descriptor) {
|
|
3774
|
-
const scriptSetup = descriptor.scriptSetup;
|
|
3775
|
-
if (!scriptSetup?.attrs || !(SCRIPT_SETUP_SRC_ATTR in scriptSetup.attrs)) return;
|
|
3776
|
-
const raw = scriptSetup.attrs[SCRIPT_SETUP_SRC_ATTR];
|
|
3777
|
-
if (typeof raw === "string") scriptSetup.src = raw;
|
|
3778
|
-
delete scriptSetup.attrs[SCRIPT_SETUP_SRC_ATTR];
|
|
3779
|
-
}
|
|
3780
|
-
/**
|
|
3781
|
-
* 将预处理的 `<script src>` 恢复为真实 src。
|
|
3782
|
-
*/
|
|
3783
|
-
function restoreScriptSrc(descriptor) {
|
|
3784
|
-
const script = descriptor.script;
|
|
3785
|
-
if (!script?.attrs || !(SCRIPT_SRC_ATTR in script.attrs)) return;
|
|
3786
|
-
const raw = script.attrs[SCRIPT_SRC_ATTR];
|
|
3787
|
-
if (typeof raw === "string") script.src = raw;
|
|
3788
|
-
delete script.attrs[SCRIPT_SRC_ATTR];
|
|
3789
|
-
}
|
|
3790
3846
|
async function resolveBlockSrcPath(src, filename, options) {
|
|
3791
3847
|
const normalizedSrc = normalizeFsResolvedId(src);
|
|
3792
3848
|
if (normalizedSrc && isSkippableResolvedId(normalizedSrc)) throw new Error(`解析 ${filename} 失败:不支持 <src> 引用虚拟模块 ${src}`);
|
|
@@ -3848,9 +3904,58 @@ async function resolveSfcBlockSrc(descriptor, filename, options) {
|
|
|
3848
3904
|
if (nextDescriptor.styles.length) nextDescriptor.styles = await Promise.all(nextDescriptor.styles.map((style) => resolveBlock(style, "style")));
|
|
3849
3905
|
return {
|
|
3850
3906
|
descriptor: nextDescriptor,
|
|
3851
|
-
deps:
|
|
3907
|
+
deps: [...deps]
|
|
3852
3908
|
};
|
|
3853
3909
|
}
|
|
3910
|
+
//#endregion
|
|
3911
|
+
//#region src/plugins/utils/vueSfc.ts
|
|
3912
|
+
const sfcParseCache = new LRUCache({ max: 512 });
|
|
3913
|
+
const SCRIPT_SETUP_SRC_ATTR = "data-weapp-vite-src";
|
|
3914
|
+
const SCRIPT_SRC_ATTR = "data-weapp-vite-script-src";
|
|
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;
|
|
3919
|
+
/**
|
|
3920
|
+
* 预处理 `<script setup src>`,避免编译器丢失 src。
|
|
3921
|
+
*/
|
|
3922
|
+
function preprocessScriptSetupSrc(source) {
|
|
3923
|
+
if (!source.includes("<script") || !source.includes("setup") || !source.includes("src")) return source;
|
|
3924
|
+
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
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`)}>`;
|
|
3927
|
+
});
|
|
3928
|
+
}
|
|
3929
|
+
/**
|
|
3930
|
+
* 预处理普通 `<script src>`,避免编译器丢失 src。
|
|
3931
|
+
*/
|
|
3932
|
+
function preprocessScriptSrc(source) {
|
|
3933
|
+
if (!source.includes("<script") || !source.includes("src")) return source;
|
|
3934
|
+
return source.replace(SCRIPT_SETUP_TAG_RE, (full, attrs) => {
|
|
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`)}>`;
|
|
3937
|
+
});
|
|
3938
|
+
}
|
|
3939
|
+
/**
|
|
3940
|
+
* 将预处理的 `<script setup src>` 恢复为真实 src。
|
|
3941
|
+
*/
|
|
3942
|
+
function restoreScriptSetupSrc(descriptor) {
|
|
3943
|
+
const scriptSetup = descriptor.scriptSetup;
|
|
3944
|
+
if (!scriptSetup?.attrs || !(SCRIPT_SETUP_SRC_ATTR in scriptSetup.attrs)) return;
|
|
3945
|
+
const raw = scriptSetup.attrs[SCRIPT_SETUP_SRC_ATTR];
|
|
3946
|
+
if (typeof raw === "string") scriptSetup.src = raw;
|
|
3947
|
+
delete scriptSetup.attrs[SCRIPT_SETUP_SRC_ATTR];
|
|
3948
|
+
}
|
|
3949
|
+
/**
|
|
3950
|
+
* 将预处理的 `<script src>` 恢复为真实 src。
|
|
3951
|
+
*/
|
|
3952
|
+
function restoreScriptSrc(descriptor) {
|
|
3953
|
+
const script = descriptor.script;
|
|
3954
|
+
if (!script?.attrs || !(SCRIPT_SRC_ATTR in script.attrs)) return;
|
|
3955
|
+
const raw = script.attrs[SCRIPT_SRC_ATTR];
|
|
3956
|
+
if (typeof raw === "string") script.src = raw;
|
|
3957
|
+
delete script.attrs[SCRIPT_SRC_ATTR];
|
|
3958
|
+
}
|
|
3854
3959
|
/**
|
|
3855
3960
|
* 读取并解析 SFC,支持缓存与 src 解析。
|
|
3856
3961
|
*/
|
|
@@ -3907,9 +4012,10 @@ async function readAndParseSfc(filename, options) {
|
|
|
3907
4012
|
function getSfcCheckMtime(config) {
|
|
3908
4013
|
return getReadFileCheckMtime(config);
|
|
3909
4014
|
}
|
|
3910
|
-
|
|
3911
4015
|
//#endregion
|
|
3912
4016
|
//#region src/plugins/vue/compiler/style.ts
|
|
4017
|
+
const CSS_RULE_RE = /([^{]+)(\{[^}]*\})/g;
|
|
4018
|
+
const CSS_CLASS_RE = /\.([a-z_][\w-]*)(?:\[[^\]]+\])?\s*\{/gi;
|
|
3913
4019
|
/**
|
|
3914
4020
|
* 将 Vue SFC 的 style 块转换为 WXSS
|
|
3915
4021
|
*/
|
|
@@ -3933,7 +4039,7 @@ function compileVueStyleToWxss(styleBlock, options) {
|
|
|
3933
4039
|
*/
|
|
3934
4040
|
function transformScopedCss(source, id) {
|
|
3935
4041
|
const scopedId = `data-v-${id}`;
|
|
3936
|
-
return source.replace(
|
|
4042
|
+
return source.replace(CSS_RULE_RE, (match, selector, rules) => {
|
|
3937
4043
|
const trimmedSelector = selector.trim();
|
|
3938
4044
|
if (!trimmedSelector) return match;
|
|
3939
4045
|
if (trimmedSelector.includes("[") || trimmedSelector.includes(":deep(") || trimmedSelector.includes(":slotted(")) return match;
|
|
@@ -3949,7 +4055,7 @@ function transformScopedCss(source, id) {
|
|
|
3949
4055
|
function transformCssModules(source, id) {
|
|
3950
4056
|
const classes = {};
|
|
3951
4057
|
const hash = generateHash(id);
|
|
3952
|
-
const classRegex =
|
|
4058
|
+
const classRegex = new RegExp(CSS_CLASS_RE.source, CSS_CLASS_RE.flags);
|
|
3953
4059
|
const foundClasses = [];
|
|
3954
4060
|
let result = classRegex.exec(source);
|
|
3955
4061
|
while (result !== null) {
|
|
@@ -3983,7 +4089,6 @@ function generateHash(str) {
|
|
|
3983
4089
|
}
|
|
3984
4090
|
return Math.abs(hash).toString(36) + str.length.toString(36);
|
|
3985
4091
|
}
|
|
3986
|
-
|
|
3987
4092
|
//#endregion
|
|
3988
4093
|
//#region src/plugins/vue/compiler/template/classStyleRuntime.ts
|
|
3989
4094
|
/**
|
|
@@ -4002,7 +4107,7 @@ function resolveScriptModuleTag(extension) {
|
|
|
4002
4107
|
*/
|
|
4003
4108
|
function buildClassStyleWxsTag(extension, src) {
|
|
4004
4109
|
const normalized = extension.startsWith(".") ? extension.slice(1) : extension;
|
|
4005
|
-
const resolvedSrc = src ??
|
|
4110
|
+
const resolvedSrc = src ?? `./__weapp_vite_class_style.${normalized}`;
|
|
4006
4111
|
return `<${resolveScriptModuleTag(normalized)} module="${CLASS_STYLE_WXS_MODULE}" src="${resolvedSrc}"/>`;
|
|
4007
4112
|
}
|
|
4008
4113
|
/**
|
|
@@ -4242,106 +4347,12 @@ function getClassStyleWxsSource(options = {}) {
|
|
|
4242
4347
|
""
|
|
4243
4348
|
].join("\n");
|
|
4244
4349
|
}
|
|
4245
|
-
|
|
4246
4350
|
//#endregion
|
|
4247
|
-
//#region src/plugins/vue/compiler/template/elements/
|
|
4248
|
-
const IDENTIFIER_RE$
|
|
4351
|
+
//#region src/plugins/vue/compiler/template/elements/forExpression.ts
|
|
4352
|
+
const IDENTIFIER_RE$4 = /^[A-Z_$][\w$]*$/i;
|
|
4249
4353
|
const FOR_ITEM_ALIAS_PLACEHOLDER = "__wv_for_item__";
|
|
4250
|
-
function isStructuralDirective(node) {
|
|
4251
|
-
for (const prop of node.props) if (prop.type === NodeTypes.DIRECTIVE) {
|
|
4252
|
-
if (prop.name === "if" || prop.name === "else-if" || prop.name === "else") return {
|
|
4253
|
-
type: "if",
|
|
4254
|
-
directive: prop
|
|
4255
|
-
};
|
|
4256
|
-
if (prop.name === "for") return {
|
|
4257
|
-
type: "for",
|
|
4258
|
-
directive: prop
|
|
4259
|
-
};
|
|
4260
|
-
}
|
|
4261
|
-
return {
|
|
4262
|
-
type: null,
|
|
4263
|
-
directive: void 0
|
|
4264
|
-
};
|
|
4265
|
-
}
|
|
4266
|
-
function pushScope(context, names) {
|
|
4267
|
-
if (!names.length) return;
|
|
4268
|
-
context.scopeStack.push(new Set(names));
|
|
4269
|
-
}
|
|
4270
|
-
function popScope(context) {
|
|
4271
|
-
if (context.scopeStack.length) context.scopeStack.pop();
|
|
4272
|
-
}
|
|
4273
|
-
function pushForScope(context, info) {
|
|
4274
|
-
if (!info.listExp) return;
|
|
4275
|
-
context.forStack.push({ ...info });
|
|
4276
|
-
}
|
|
4277
|
-
function popForScope(context) {
|
|
4278
|
-
if (context.forStack.length) context.forStack.pop();
|
|
4279
|
-
}
|
|
4280
|
-
function withForScope(context, info, fn) {
|
|
4281
|
-
pushForScope(context, info);
|
|
4282
|
-
try {
|
|
4283
|
-
return fn();
|
|
4284
|
-
} finally {
|
|
4285
|
-
popForScope(context);
|
|
4286
|
-
}
|
|
4287
|
-
}
|
|
4288
|
-
function pushSlotProps(context, mapping) {
|
|
4289
|
-
if (!Object.keys(mapping).length) return;
|
|
4290
|
-
context.slotPropStack.push(mapping);
|
|
4291
|
-
}
|
|
4292
|
-
function popSlotProps(context) {
|
|
4293
|
-
if (context.slotPropStack.length) context.slotPropStack.pop();
|
|
4294
|
-
}
|
|
4295
|
-
function withScope(context, names, fn) {
|
|
4296
|
-
pushScope(context, names);
|
|
4297
|
-
try {
|
|
4298
|
-
return fn();
|
|
4299
|
-
} finally {
|
|
4300
|
-
popScope(context);
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
function withSlotProps(context, mapping, fn) {
|
|
4304
|
-
pushSlotProps(context, mapping);
|
|
4305
|
-
try {
|
|
4306
|
-
return fn();
|
|
4307
|
-
} finally {
|
|
4308
|
-
popSlotProps(context);
|
|
4309
|
-
}
|
|
4310
|
-
}
|
|
4311
|
-
function collectScopePropMapping(context) {
|
|
4312
|
-
const mapping = {};
|
|
4313
|
-
if (!context.slotMultipleInstance) return mapping;
|
|
4314
|
-
for (const scope of context.scopeStack) for (const name of scope) {
|
|
4315
|
-
if (!/^[A-Z_$][\w$]*$/i.test(name)) continue;
|
|
4316
|
-
if (!Object.prototype.hasOwnProperty.call(mapping, name)) mapping[name] = name;
|
|
4317
|
-
}
|
|
4318
|
-
return mapping;
|
|
4319
|
-
}
|
|
4320
|
-
function buildScopePropsExpression(context) {
|
|
4321
|
-
const mapping = collectScopePropMapping(context);
|
|
4322
|
-
const keys = Object.keys(mapping);
|
|
4323
|
-
if (!keys.length) return null;
|
|
4324
|
-
return `[${keys.map((key) => `${toWxmlStringLiteral$1(key)},${key}`).join(",")}]`;
|
|
4325
|
-
}
|
|
4326
|
-
function toWxmlStringLiteral$1(value) {
|
|
4327
|
-
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n")}'`;
|
|
4328
|
-
}
|
|
4329
|
-
function hashString(input) {
|
|
4330
|
-
let hash = 0;
|
|
4331
|
-
for (let i = 0; i < input.length; i++) {
|
|
4332
|
-
hash = (hash << 5) - hash + input.charCodeAt(i);
|
|
4333
|
-
hash |= 0;
|
|
4334
|
-
}
|
|
4335
|
-
return Math.abs(hash).toString(36);
|
|
4336
|
-
}
|
|
4337
|
-
function isScopedSlotsDisabled(context) {
|
|
4338
|
-
return context.scopedSlotsCompiler === "off";
|
|
4339
|
-
}
|
|
4340
|
-
function findSlotDirective(node) {
|
|
4341
|
-
return node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && prop.name === "slot");
|
|
4342
|
-
}
|
|
4343
4354
|
function isIdentifier(value) {
|
|
4344
|
-
return IDENTIFIER_RE$
|
|
4355
|
+
return IDENTIFIER_RE$4.test(value);
|
|
4345
4356
|
}
|
|
4346
4357
|
function splitTopLevelByComma(input) {
|
|
4347
4358
|
const out = [];
|
|
@@ -4513,46 +4524,145 @@ function collectPatternAliases(node, base, aliases) {
|
|
|
4513
4524
|
collectPatternAliases(property.value, nextBase, aliases);
|
|
4514
4525
|
});
|
|
4515
4526
|
}
|
|
4516
|
-
function parseItemAliases(pattern) {
|
|
4527
|
+
function parseItemAliases(pattern) {
|
|
4528
|
+
try {
|
|
4529
|
+
const stmt = parseJsLike(`(${pattern}) => {}`).program.body[0];
|
|
4530
|
+
if (!stmt || stmt.type !== "ExpressionStatement") return {};
|
|
4531
|
+
const exp = stmt.expression;
|
|
4532
|
+
if (!t.isArrowFunctionExpression(exp) || exp.params.length !== 1) return {};
|
|
4533
|
+
const aliases = {};
|
|
4534
|
+
collectPatternAliases(exp.params[0], FOR_ITEM_ALIAS_PLACEHOLDER, aliases);
|
|
4535
|
+
return aliases;
|
|
4536
|
+
} catch {
|
|
4537
|
+
return {};
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
function parseForExpression(exp) {
|
|
4541
|
+
const split = splitForExpression(exp.trim());
|
|
4542
|
+
if (!split) return {};
|
|
4543
|
+
const segments = splitTopLevelByComma(stripOuterParentheses(split.source));
|
|
4544
|
+
if (!segments.length || segments.length > 3) return { listExp: split.list };
|
|
4545
|
+
const result = { listExp: split.list };
|
|
4546
|
+
const rawItem = segments[0]?.trim();
|
|
4547
|
+
if (rawItem) if (isIdentifier(rawItem)) result.item = rawItem;
|
|
4548
|
+
else {
|
|
4549
|
+
const aliases = parseItemAliases(rawItem);
|
|
4550
|
+
if (Object.keys(aliases).length) {
|
|
4551
|
+
result.item = FOR_ITEM_ALIAS_PLACEHOLDER;
|
|
4552
|
+
result.itemAliases = aliases;
|
|
4553
|
+
}
|
|
4554
|
+
}
|
|
4555
|
+
if (segments.length === 2) {
|
|
4556
|
+
const rawIndex = segments[1]?.trim();
|
|
4557
|
+
if (rawIndex && isIdentifier(rawIndex)) result.index = rawIndex;
|
|
4558
|
+
} else if (segments.length === 3) {
|
|
4559
|
+
const rawKey = segments[1]?.trim();
|
|
4560
|
+
const rawIndex = segments[2]?.trim();
|
|
4561
|
+
if (rawKey && isIdentifier(rawKey)) result.key = rawKey;
|
|
4562
|
+
if (rawIndex && isIdentifier(rawIndex)) result.index = rawIndex;
|
|
4563
|
+
}
|
|
4564
|
+
return result;
|
|
4565
|
+
}
|
|
4566
|
+
//#endregion
|
|
4567
|
+
//#region src/plugins/vue/compiler/template/elements/helpers.ts
|
|
4568
|
+
function isStructuralDirective(node) {
|
|
4569
|
+
for (const prop of node.props) if (prop.type === NodeTypes.DIRECTIVE) {
|
|
4570
|
+
if (prop.name === "if" || prop.name === "else-if" || prop.name === "else") return {
|
|
4571
|
+
type: "if",
|
|
4572
|
+
directive: prop
|
|
4573
|
+
};
|
|
4574
|
+
if (prop.name === "for") return {
|
|
4575
|
+
type: "for",
|
|
4576
|
+
directive: prop
|
|
4577
|
+
};
|
|
4578
|
+
}
|
|
4579
|
+
return {
|
|
4580
|
+
type: null,
|
|
4581
|
+
directive: void 0
|
|
4582
|
+
};
|
|
4583
|
+
}
|
|
4584
|
+
function pushScope(context, names) {
|
|
4585
|
+
if (!names.length) return;
|
|
4586
|
+
context.scopeStack.push(new Set(names));
|
|
4587
|
+
}
|
|
4588
|
+
function popScope(context) {
|
|
4589
|
+
if (context.scopeStack.length) context.scopeStack.pop();
|
|
4590
|
+
}
|
|
4591
|
+
function pushForScope(context, info) {
|
|
4592
|
+
if (!info.listExp) return;
|
|
4593
|
+
context.forStack.push({ ...info });
|
|
4594
|
+
}
|
|
4595
|
+
function popForScope(context) {
|
|
4596
|
+
if (context.forStack.length) context.forStack.pop();
|
|
4597
|
+
}
|
|
4598
|
+
function withForScope(context, info, fn) {
|
|
4599
|
+
pushForScope(context, info);
|
|
4600
|
+
try {
|
|
4601
|
+
return fn();
|
|
4602
|
+
} finally {
|
|
4603
|
+
popForScope(context);
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
function pushSlotProps(context, mapping) {
|
|
4607
|
+
if (!Object.keys(mapping).length) return;
|
|
4608
|
+
context.slotPropStack.push(mapping);
|
|
4609
|
+
}
|
|
4610
|
+
function popSlotProps(context) {
|
|
4611
|
+
if (context.slotPropStack.length) context.slotPropStack.pop();
|
|
4612
|
+
}
|
|
4613
|
+
function withScope(context, names, fn) {
|
|
4614
|
+
pushScope(context, names);
|
|
4517
4615
|
try {
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
if (!t.isArrowFunctionExpression(exp) || exp.params.length !== 1) return {};
|
|
4522
|
-
const aliases = {};
|
|
4523
|
-
collectPatternAliases(exp.params[0], FOR_ITEM_ALIAS_PLACEHOLDER, aliases);
|
|
4524
|
-
return aliases;
|
|
4525
|
-
} catch {
|
|
4526
|
-
return {};
|
|
4616
|
+
return fn();
|
|
4617
|
+
} finally {
|
|
4618
|
+
popScope(context);
|
|
4527
4619
|
}
|
|
4528
4620
|
}
|
|
4529
|
-
function
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
const rawItem = segments[0]?.trim();
|
|
4536
|
-
if (rawItem) if (isIdentifier(rawItem)) result.item = rawItem;
|
|
4537
|
-
else {
|
|
4538
|
-
const aliases = parseItemAliases(rawItem);
|
|
4539
|
-
if (Object.keys(aliases).length) {
|
|
4540
|
-
result.item = FOR_ITEM_ALIAS_PLACEHOLDER;
|
|
4541
|
-
result.itemAliases = aliases;
|
|
4542
|
-
}
|
|
4621
|
+
function withSlotProps(context, mapping, fn) {
|
|
4622
|
+
pushSlotProps(context, mapping);
|
|
4623
|
+
try {
|
|
4624
|
+
return fn();
|
|
4625
|
+
} finally {
|
|
4626
|
+
popSlotProps(context);
|
|
4543
4627
|
}
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
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;
|
|
4634
|
+
function collectScopePropMapping(context) {
|
|
4635
|
+
const mapping = {};
|
|
4636
|
+
if (!context.slotMultipleInstance) return mapping;
|
|
4637
|
+
for (const scope of context.scopeStack) for (const name of scope) {
|
|
4638
|
+
if (!IDENTIFIER_RE$3.test(name)) continue;
|
|
4639
|
+
if (!Object.hasOwn(mapping, name)) mapping[name] = name;
|
|
4552
4640
|
}
|
|
4553
|
-
return
|
|
4641
|
+
return mapping;
|
|
4642
|
+
}
|
|
4643
|
+
function buildScopePropsExpression(context) {
|
|
4644
|
+
const mapping = collectScopePropMapping(context);
|
|
4645
|
+
const keys = Object.keys(mapping);
|
|
4646
|
+
if (!keys.length) return null;
|
|
4647
|
+
return `[${keys.map((key) => `${toWxmlStringLiteral$1(key)},${key}`).join(",")}]`;
|
|
4648
|
+
}
|
|
4649
|
+
function toWxmlStringLiteral$1(value) {
|
|
4650
|
+
return `'${value.replace(BACKSLASH_RE$2, "\\\\").replace(SINGLE_QUOTE_RE$2, "\\'").replace(CR_RE$1, "\\r").replace(LF_RE$1, "\\n")}'`;
|
|
4651
|
+
}
|
|
4652
|
+
function hashString(input) {
|
|
4653
|
+
let hash = 0;
|
|
4654
|
+
for (let i = 0; i < input.length; i++) {
|
|
4655
|
+
hash = (hash << 5) - hash + input.charCodeAt(i);
|
|
4656
|
+
hash |= 0;
|
|
4657
|
+
}
|
|
4658
|
+
return Math.abs(hash).toString(36);
|
|
4659
|
+
}
|
|
4660
|
+
function isScopedSlotsDisabled(context) {
|
|
4661
|
+
return context.scopedSlotsCompiler === "off";
|
|
4662
|
+
}
|
|
4663
|
+
function findSlotDirective(node) {
|
|
4664
|
+
return node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && prop.name === "slot");
|
|
4554
4665
|
}
|
|
4555
|
-
|
|
4556
4666
|
//#endregion
|
|
4557
4667
|
//#region src/plugins/vue/compiler/template/expression/scopedSlot.ts
|
|
4558
4668
|
const SCOPED_SLOT_GLOBALS = new Set([
|
|
@@ -4614,6 +4724,7 @@ function replaceIdentifierWithExpression(path, replacement) {
|
|
|
4614
4724
|
}
|
|
4615
4725
|
path.replaceWith(replacement);
|
|
4616
4726
|
}
|
|
4727
|
+
const IDENTIFIER_RE$2 = /^[A-Z_$][\w$]*$/i;
|
|
4617
4728
|
function rewriteScopedSlotExpression(exp, context) {
|
|
4618
4729
|
const normalized = normalizeWxmlExpression(exp);
|
|
4619
4730
|
const parsed = parseBabelExpressionFile(normalized);
|
|
@@ -4624,7 +4735,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4624
4735
|
const forAliases = collectForAliasMapping$2(context);
|
|
4625
4736
|
const createMemberAccess = (target, prop) => {
|
|
4626
4737
|
if (!prop) return t.identifier(target);
|
|
4627
|
-
if (
|
|
4738
|
+
if (IDENTIFIER_RE$2.test(prop)) return t.memberExpression(t.identifier(target), t.identifier(prop));
|
|
4628
4739
|
return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
|
|
4629
4740
|
};
|
|
4630
4741
|
traverse(ast, { Identifier(path) {
|
|
@@ -4632,7 +4743,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4632
4743
|
const name = path.node.name;
|
|
4633
4744
|
if (SCOPED_SLOT_GLOBALS.has(name)) return;
|
|
4634
4745
|
if (path.scope.hasBinding(name)) return;
|
|
4635
|
-
if (Object.
|
|
4746
|
+
if (Object.hasOwn(forAliases, name)) {
|
|
4636
4747
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
4637
4748
|
if (aliasExp) {
|
|
4638
4749
|
replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
|
|
@@ -4640,7 +4751,7 @@ function rewriteScopedSlotExpression(exp, context) {
|
|
|
4640
4751
|
}
|
|
4641
4752
|
}
|
|
4642
4753
|
if (locals.has(name)) return;
|
|
4643
|
-
if (Object.
|
|
4754
|
+
if (Object.hasOwn(slotProps, name)) {
|
|
4644
4755
|
replaceIdentifierWithExpression(path, createMemberAccess("__wvSlotPropsData", slotProps[name]));
|
|
4645
4756
|
return;
|
|
4646
4757
|
}
|
|
@@ -4661,7 +4772,7 @@ function rewriteForAliasExpression(exp, context) {
|
|
|
4661
4772
|
if (!path.isReferencedIdentifier()) return;
|
|
4662
4773
|
const name = path.node.name;
|
|
4663
4774
|
if (path.scope.hasBinding(name)) return;
|
|
4664
|
-
if (!Object.
|
|
4775
|
+
if (!Object.hasOwn(forAliases, name)) return;
|
|
4665
4776
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
4666
4777
|
if (!aliasExp) return;
|
|
4667
4778
|
replaceIdentifierWithExpression(path, t.cloneNode(aliasExp, true));
|
|
@@ -4675,7 +4786,6 @@ function normalizeWxmlExpressionWithContext(exp, context) {
|
|
|
4675
4786
|
if (!context.rewriteScopedSlot) return rewriteForAliasExpression(exp, context);
|
|
4676
4787
|
return rewriteScopedSlotExpression(exp, context);
|
|
4677
4788
|
}
|
|
4678
|
-
|
|
4679
4789
|
//#endregion
|
|
4680
4790
|
//#region src/plugins/vue/compiler/template/expression/bindings.ts
|
|
4681
4791
|
function normalizeClassBindingExpression(exp, context) {
|
|
@@ -4775,7 +4885,6 @@ function normalizeStyleBindingExpression(exp, context) {
|
|
|
4775
4885
|
if (!out.length) return [normalizeWxmlExpressionWithContext(exp, context)];
|
|
4776
4886
|
return out;
|
|
4777
4887
|
}
|
|
4778
|
-
|
|
4779
4888
|
//#endregion
|
|
4780
4889
|
//#region src/plugins/vue/compiler/template/expression/inline.ts
|
|
4781
4890
|
const INLINE_GLOBALS = new Set([
|
|
@@ -4824,14 +4933,14 @@ const INLINE_GLOBALS = new Set([
|
|
|
4824
4933
|
"ctx",
|
|
4825
4934
|
"scope"
|
|
4826
4935
|
]);
|
|
4827
|
-
const IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
4936
|
+
const IDENTIFIER_RE$1 = /^[A-Z_$][\w$]*$/i;
|
|
4828
4937
|
const SIMPLE_PATH_RE = /^[A-Z_$][\w$]*(?:\.[A-Z_$][\w$]*)*$/i;
|
|
4829
4938
|
function createMemberAccess$1(target, prop) {
|
|
4830
|
-
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));
|
|
4831
4940
|
return t.memberExpression(t.identifier(target), t.stringLiteral(prop), true);
|
|
4832
4941
|
}
|
|
4833
4942
|
function resolveSlotPropBinding(slotProps, name) {
|
|
4834
|
-
if (!Object.
|
|
4943
|
+
if (!Object.hasOwn(slotProps, name)) return null;
|
|
4835
4944
|
const prop = slotProps[name];
|
|
4836
4945
|
if (!prop) return "__wvSlotPropsData";
|
|
4837
4946
|
return generateExpression(createMemberAccess$1("__wvSlotPropsData", prop));
|
|
@@ -4948,7 +5057,6 @@ function registerInlineExpression(exp, context) {
|
|
|
4948
5057
|
indexBindings: scopeResolvers.length ? indexBindings.map((binding) => binding.binding) : []
|
|
4949
5058
|
};
|
|
4950
5059
|
}
|
|
4951
|
-
|
|
4952
5060
|
//#endregion
|
|
4953
5061
|
//#region src/plugins/vue/compiler/template/expression/js.ts
|
|
4954
5062
|
const JS_RUNTIME_GLOBALS = new Set([
|
|
@@ -5062,7 +5170,7 @@ function normalizeJsExpressionWithContext(exp, context, options) {
|
|
|
5062
5170
|
const name = path.node.name;
|
|
5063
5171
|
if (JS_RUNTIME_GLOBALS.has(name)) return;
|
|
5064
5172
|
if (path.scope.hasBinding(name)) return;
|
|
5065
|
-
if (Object.
|
|
5173
|
+
if (Object.hasOwn(forAliases, name)) {
|
|
5066
5174
|
const aliasExp = parseBabelExpression(forAliases[name]);
|
|
5067
5175
|
if (aliasExp) {
|
|
5068
5176
|
const replacement = t.cloneNode(aliasExp, true);
|
|
@@ -5078,7 +5186,7 @@ function normalizeJsExpressionWithContext(exp, context, options) {
|
|
|
5078
5186
|
}
|
|
5079
5187
|
if (locals.has(name)) return;
|
|
5080
5188
|
let replacement;
|
|
5081
|
-
if (context.rewriteScopedSlot) if (Object.
|
|
5189
|
+
if (context.rewriteScopedSlot) if (Object.hasOwn(slotProps, name)) {
|
|
5082
5190
|
const prop = slotProps[name];
|
|
5083
5191
|
const base = createThisMemberAccess("__wvSlotPropsData");
|
|
5084
5192
|
replacement = createUnrefCall(prop ? createMemberAccess(base, prop) : base);
|
|
@@ -5096,7 +5204,6 @@ function normalizeJsExpressionWithContext(exp, context, options) {
|
|
|
5096
5204
|
const stmt = ast.program.body[0];
|
|
5097
5205
|
return (stmt && "expression" in stmt ? stmt.expression : null) || null;
|
|
5098
5206
|
}
|
|
5099
|
-
|
|
5100
5207
|
//#endregion
|
|
5101
5208
|
//#region src/plugins/vue/compiler/template/expression/runtimeBinding.ts
|
|
5102
5209
|
function buildForIndexAccess$1(context) {
|
|
@@ -5140,17 +5247,19 @@ function registerRuntimeBindingExpression(exp, context, options) {
|
|
|
5140
5247
|
context.classStyleBindings.push(binding);
|
|
5141
5248
|
return `${binding.name}${buildForIndexAccess$1(context)}`;
|
|
5142
5249
|
}
|
|
5143
|
-
|
|
5144
5250
|
//#endregion
|
|
5145
5251
|
//#region src/plugins/vue/compiler/template/mustache.ts
|
|
5146
5252
|
function renderMustache(expression, context) {
|
|
5147
5253
|
return context.mustacheInterpolation === "spaced" ? `{{ ${expression} }}` : `{{${expression}}}`;
|
|
5148
5254
|
}
|
|
5149
|
-
|
|
5150
5255
|
//#endregion
|
|
5151
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;
|
|
5152
5261
|
function toWxmlStringLiteral(value) {
|
|
5153
|
-
return `'${value.replace(
|
|
5262
|
+
return `'${value.replace(BACKSLASH_RE$1, "\\\\").replace(SINGLE_QUOTE_RE$1, "\\'").replace(CR_RE, "\\r").replace(LF_RE, "\\n")}'`;
|
|
5154
5263
|
}
|
|
5155
5264
|
function cloneForStack(context) {
|
|
5156
5265
|
return context.forStack.map((info) => ({ ...info }));
|
|
@@ -5163,6 +5272,16 @@ function generateExpressionCode(exp) {
|
|
|
5163
5272
|
const { code } = generate(exp, { compact: true });
|
|
5164
5273
|
return code;
|
|
5165
5274
|
}
|
|
5275
|
+
const TRAILING_SEMICOLONS_RE = /;+\s*$/;
|
|
5276
|
+
function normalizeStyleFallbackValue(value) {
|
|
5277
|
+
return value.trim().replace(TRAILING_SEMICOLONS_RE, "");
|
|
5278
|
+
}
|
|
5279
|
+
function buildStyleErrorFallback(staticValue, shouldHideByDefault) {
|
|
5280
|
+
const segments = [];
|
|
5281
|
+
if (staticValue?.trim()) segments.push(normalizeStyleFallbackValue(staticValue));
|
|
5282
|
+
if (shouldHideByDefault) segments.push("display: none");
|
|
5283
|
+
return segments.join(";");
|
|
5284
|
+
}
|
|
5166
5285
|
function mergeJsExpressionParts(parts) {
|
|
5167
5286
|
if (!parts.length) return t.stringLiteral("");
|
|
5168
5287
|
if (parts.length === 1) return parts[0];
|
|
@@ -5192,21 +5311,26 @@ function shouldPreferJsClassStyleRuntime(exp) {
|
|
|
5192
5311
|
return false;
|
|
5193
5312
|
}
|
|
5194
5313
|
if (t.isConditionalExpression(current)) return visit(current.test) || visit(current.consequent) || visit(current.alternate);
|
|
5195
|
-
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
|
+
}
|
|
5196
5318
|
if (t.isUnaryExpression(current)) return visit(current.argument);
|
|
5197
5319
|
return true;
|
|
5198
5320
|
};
|
|
5199
5321
|
return visit(ast);
|
|
5200
5322
|
}
|
|
5201
|
-
function createClassStyleBinding(context, type, exp, expAst) {
|
|
5323
|
+
function createClassStyleBinding(context, type, exp, expAst, errorFallback) {
|
|
5202
5324
|
const sameTypeCount = context.classStyleBindings.filter((binding) => binding.type === type).length;
|
|
5203
|
-
|
|
5325
|
+
const binding = {
|
|
5204
5326
|
name: type === "class" ? `__wv_cls_${sameTypeCount}` : type === "style" ? `__wv_style_${sameTypeCount}` : `__wv_bind_${sameTypeCount}`,
|
|
5205
5327
|
type,
|
|
5206
5328
|
exp,
|
|
5207
5329
|
expAst,
|
|
5208
5330
|
forStack: cloneForStack(context)
|
|
5209
5331
|
};
|
|
5332
|
+
if (errorFallback !== void 0) binding.errorFallback = errorFallback;
|
|
5333
|
+
return binding;
|
|
5210
5334
|
}
|
|
5211
5335
|
function renderClassAttribute(staticClass, dynamicClassExp, context) {
|
|
5212
5336
|
const staticValue = staticClass?.trim();
|
|
@@ -5225,7 +5349,7 @@ function renderClassAttribute(staticClass, dynamicClassExp, context) {
|
|
|
5225
5349
|
const dynamicAst = normalizeJsExpressionWithContext(dynamicClassExp, context, { hint: "class 绑定" });
|
|
5226
5350
|
if (dynamicAst) jsParts.push(dynamicAst);
|
|
5227
5351
|
const expAst = mergeJsExpressionParts(jsParts);
|
|
5228
|
-
const binding = createClassStyleBinding(context, "class", generateExpressionCode(expAst), expAst);
|
|
5352
|
+
const binding = createClassStyleBinding(context, "class", generateExpressionCode(expAst), expAst, staticValue ?? "");
|
|
5229
5353
|
context.classStyleBindings.push(binding);
|
|
5230
5354
|
const indexAccess = buildForIndexAccess(context);
|
|
5231
5355
|
return `class="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
|
|
@@ -5259,7 +5383,7 @@ function renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context) {
|
|
|
5259
5383
|
if (showAst) jsParts.push(t.conditionalExpression(showAst, t.stringLiteral(""), t.stringLiteral("display: none")));
|
|
5260
5384
|
}
|
|
5261
5385
|
const expAst = mergeJsExpressionParts(jsParts);
|
|
5262
|
-
const binding = createClassStyleBinding(context, "style", generateExpressionCode(expAst), expAst);
|
|
5386
|
+
const binding = createClassStyleBinding(context, "style", generateExpressionCode(expAst), expAst, buildStyleErrorFallback(staticValue, Boolean(vShowExp)));
|
|
5263
5387
|
context.classStyleBindings.push(binding);
|
|
5264
5388
|
const indexAccess = buildForIndexAccess(context);
|
|
5265
5389
|
return `style="${renderMustache(`${binding.name}${indexAccess}`, context)}"`;
|
|
@@ -5270,7 +5394,6 @@ function transformAttribute(node, _context) {
|
|
|
5270
5394
|
if (value.type === NodeTypes.TEXT) return `${name}="${value.content}"`;
|
|
5271
5395
|
return `${name}=""`;
|
|
5272
5396
|
}
|
|
5273
|
-
|
|
5274
5397
|
//#endregion
|
|
5275
5398
|
//#region src/plugins/vue/compiler/template/directives/bind.ts
|
|
5276
5399
|
function unwrapTsExpression(node) {
|
|
@@ -5292,8 +5415,10 @@ function createInlineObjectLiteralAttr(argValue, rawExpValue, context) {
|
|
|
5292
5415
|
if (context.mustacheInterpolation === "spaced") return `${argValue}="${renderMustache(expValue, context)}"`;
|
|
5293
5416
|
return `${argValue}="{{ ${expValue} }}"`;
|
|
5294
5417
|
}
|
|
5295
|
-
const
|
|
5296
|
-
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);
|
|
5297
5422
|
function transformBindDirective(node, context, forInfo) {
|
|
5298
5423
|
const { exp, arg } = node;
|
|
5299
5424
|
if (!arg) return null;
|
|
@@ -5336,9 +5461,9 @@ function transformBindDirective(node, context, forInfo) {
|
|
|
5336
5461
|
}
|
|
5337
5462
|
return `${argValue}="${renderMustache(normalizeWxmlExpressionWithContext(rawExpValue, context), context)}"`;
|
|
5338
5463
|
}
|
|
5339
|
-
|
|
5340
5464
|
//#endregion
|
|
5341
5465
|
//#region src/plugins/vue/compiler/template/directives/custom.ts
|
|
5466
|
+
const IDENTIFIER_RE = /^[a-z_$][\w$]*$/i;
|
|
5342
5467
|
function transformCustomDirective(name, exp, arg, context) {
|
|
5343
5468
|
if (new Set([
|
|
5344
5469
|
"bind",
|
|
@@ -5358,14 +5483,13 @@ function transformCustomDirective(name, exp, arg, context) {
|
|
|
5358
5483
|
const dataAttrName = `data-v-${name}`;
|
|
5359
5484
|
if (exp && exp.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5360
5485
|
const expValue = normalizeWxmlExpressionWithContext(exp.content, context);
|
|
5361
|
-
if (
|
|
5486
|
+
if (IDENTIFIER_RE.test(expValue)) return `${dataAttrName}="${renderMustache(expValue, context)}"`;
|
|
5362
5487
|
return `${dataAttrName}="${renderMustache(expValue, context)}"`;
|
|
5363
5488
|
}
|
|
5364
5489
|
if (arg && arg.type === NodeTypes.SIMPLE_EXPRESSION) return `${dataAttrName}="${arg.content}"`;
|
|
5365
5490
|
context.warnings.push(`自定义指令 v-${name} 可能需要运行时支持。已生成 data 属性:${dataAttrName}`);
|
|
5366
5491
|
return dataAttrName;
|
|
5367
5492
|
}
|
|
5368
|
-
|
|
5369
5493
|
//#endregion
|
|
5370
5494
|
//#region src/plugins/vue/compiler/template/directives/model.ts
|
|
5371
5495
|
function getElementType(element) {
|
|
@@ -5375,8 +5499,9 @@ function getElementType(element) {
|
|
|
5375
5499
|
}
|
|
5376
5500
|
return "";
|
|
5377
5501
|
}
|
|
5502
|
+
const QUOTE_RE$1 = /"/g;
|
|
5378
5503
|
function transformVModel(element, expValue, context) {
|
|
5379
|
-
const escapedModel = expValue.replace(
|
|
5504
|
+
const escapedModel = expValue.replace(QUOTE_RE$1, """);
|
|
5380
5505
|
const bindModel = (event) => {
|
|
5381
5506
|
return `${context.platform.eventBindingAttr(event)}="__weapp_vite_model" data-wv-model="${escapedModel}"`;
|
|
5382
5507
|
};
|
|
@@ -5405,24 +5530,27 @@ function transformModelDirective(node, context, elementNode) {
|
|
|
5405
5530
|
if (!exp) return null;
|
|
5406
5531
|
return transformVModel(elementNode, normalizeWxmlExpressionWithContext(exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : "", context), context);
|
|
5407
5532
|
}
|
|
5408
|
-
|
|
5409
5533
|
//#endregion
|
|
5410
5534
|
//#region src/plugins/vue/compiler/template/directives/on.ts
|
|
5411
|
-
const
|
|
5535
|
+
const SIMPLE_IDENTIFIER_RE = /^[A-Z_$][\w$]*$/i;
|
|
5536
|
+
const isSimpleHandler = (value) => SIMPLE_IDENTIFIER_RE.test(value);
|
|
5412
5537
|
function shouldUseDetailPayload(options) {
|
|
5413
5538
|
return options?.isComponent === true;
|
|
5414
5539
|
}
|
|
5540
|
+
const NON_ALNUM_RE = /[^a-z0-9]+/gi;
|
|
5541
|
+
const LEADING_TRAILING_DASH_RE = /^-+|-+$/g;
|
|
5415
5542
|
function normalizeEventDatasetSuffix(eventName) {
|
|
5416
|
-
return eventName.trim().replace(
|
|
5543
|
+
return eventName.trim().replace(NON_ALNUM_RE, "-").replace(LEADING_TRAILING_DASH_RE, "").toLowerCase() || "event";
|
|
5417
5544
|
}
|
|
5545
|
+
const QUOTE_RE = /"/g;
|
|
5418
5546
|
function buildInlineScopeAttrs(scopeBindings, context) {
|
|
5419
5547
|
return scopeBindings.map((binding, index) => {
|
|
5420
|
-
return `data-wv-s${index}="${renderMustache(binding.replace(
|
|
5548
|
+
return `data-wv-s${index}="${renderMustache(binding.replace(QUOTE_RE, """), context)}"`;
|
|
5421
5549
|
});
|
|
5422
5550
|
}
|
|
5423
5551
|
function buildInlineIndexAttrs(indexBindings, context) {
|
|
5424
5552
|
return indexBindings.map((binding, index) => {
|
|
5425
|
-
return `data-wv-i${index}="${renderMustache(binding.replace(
|
|
5553
|
+
return `data-wv-i${index}="${renderMustache(binding.replace(QUOTE_RE, """), context)}"`;
|
|
5426
5554
|
});
|
|
5427
5555
|
}
|
|
5428
5556
|
function resolveEventPrefix(modifiers) {
|
|
@@ -5487,12 +5615,11 @@ function transformOnDirective(node, context, options) {
|
|
|
5487
5615
|
}
|
|
5488
5616
|
if (isInlineExpression) return [
|
|
5489
5617
|
detailAttr,
|
|
5490
|
-
`data-wv-inline-${eventSuffix}="${inlineSource.replace(
|
|
5618
|
+
`data-wv-inline-${eventSuffix}="${inlineSource.replace(QUOTE_RE, """)}"`,
|
|
5491
5619
|
`${bindAttr}="__weapp_vite_inline"`
|
|
5492
5620
|
].filter(Boolean).join(" ");
|
|
5493
5621
|
return [detailAttr, `${bindAttr}="${expValue}"`].filter(Boolean).join(" ");
|
|
5494
5622
|
}
|
|
5495
|
-
|
|
5496
5623
|
//#endregion
|
|
5497
5624
|
//#region src/plugins/vue/compiler/template/directives/show.ts
|
|
5498
5625
|
function transformShowDirective(node, context) {
|
|
@@ -5500,7 +5627,6 @@ function transformShowDirective(node, context) {
|
|
|
5500
5627
|
if (!exp) return null;
|
|
5501
5628
|
return `style="${renderMustache(`${normalizeWxmlExpressionWithContext(exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : "", context)} ? '' : 'display: none'`, context)}"`;
|
|
5502
5629
|
}
|
|
5503
|
-
|
|
5504
5630
|
//#endregion
|
|
5505
5631
|
//#region src/plugins/vue/compiler/template/directives/index.ts
|
|
5506
5632
|
function transformDirective(node, context, elementNode, forInfo, options) {
|
|
@@ -5520,7 +5646,6 @@ function transformDirective(node, context, elementNode, forInfo, options) {
|
|
|
5520
5646
|
}
|
|
5521
5647
|
return transformCustomDirective(name, exp, arg, context);
|
|
5522
5648
|
}
|
|
5523
|
-
|
|
5524
5649
|
//#endregion
|
|
5525
5650
|
//#region src/plugins/vue/compiler/template/elements/attrs.ts
|
|
5526
5651
|
const builtinTagSet = new Set(components.map((tag) => tag.toLowerCase()));
|
|
@@ -5611,7 +5736,93 @@ function collectElementAttributes(node, context, options) {
|
|
|
5611
5736
|
vTextExp
|
|
5612
5737
|
};
|
|
5613
5738
|
}
|
|
5614
|
-
|
|
5739
|
+
//#endregion
|
|
5740
|
+
//#region src/plugins/vue/compiler/template/elements/slotProps.ts
|
|
5741
|
+
const BACKSLASH_RE = /\\/g;
|
|
5742
|
+
const SINGLE_QUOTE_RE = /'/g;
|
|
5743
|
+
function parseSlotPropsExpression(exp, context) {
|
|
5744
|
+
const trimmed = exp.trim();
|
|
5745
|
+
if (!trimmed) return {};
|
|
5746
|
+
try {
|
|
5747
|
+
const stmt = parse$2(`(${trimmed}) => {}`, {
|
|
5748
|
+
sourceType: "module",
|
|
5749
|
+
plugins: ["typescript"]
|
|
5750
|
+
}).program.body[0];
|
|
5751
|
+
if (!stmt || !("expression" in stmt)) return {};
|
|
5752
|
+
const expression = stmt.expression;
|
|
5753
|
+
if (!t.isArrowFunctionExpression(expression)) return {};
|
|
5754
|
+
const param = expression.params[0];
|
|
5755
|
+
if (!param) return {};
|
|
5756
|
+
if (t.isIdentifier(param)) return { [param.name]: "" };
|
|
5757
|
+
if (t.isObjectPattern(param)) {
|
|
5758
|
+
const mapping = {};
|
|
5759
|
+
for (const prop of param.properties) {
|
|
5760
|
+
if (t.isRestElement(prop)) {
|
|
5761
|
+
context.warnings.push("小程序不支持作用域插槽的剩余解构元素。");
|
|
5762
|
+
continue;
|
|
5763
|
+
}
|
|
5764
|
+
if (!t.isObjectProperty(prop)) continue;
|
|
5765
|
+
const key = prop.key;
|
|
5766
|
+
const propName = t.isIdentifier(key) ? key.name : t.isStringLiteral(key) ? key.value : void 0;
|
|
5767
|
+
if (!propName) {
|
|
5768
|
+
context.warnings.push("小程序不支持作用域插槽的计算属性键。");
|
|
5769
|
+
continue;
|
|
5770
|
+
}
|
|
5771
|
+
const value = prop.value;
|
|
5772
|
+
if (t.isIdentifier(value)) {
|
|
5773
|
+
mapping[value.name] = propName;
|
|
5774
|
+
continue;
|
|
5775
|
+
}
|
|
5776
|
+
if (t.isAssignmentPattern(value) && t.isIdentifier(value.left)) {
|
|
5777
|
+
mapping[value.left.name] = propName;
|
|
5778
|
+
context.warnings.push("不支持作用域插槽参数的默认值,默认值将被忽略。");
|
|
5779
|
+
continue;
|
|
5780
|
+
}
|
|
5781
|
+
context.warnings.push("作用域插槽解构仅支持标识符绑定。");
|
|
5782
|
+
}
|
|
5783
|
+
return mapping;
|
|
5784
|
+
}
|
|
5785
|
+
} catch {
|
|
5786
|
+
context.warnings.push("作用域插槽参数解析失败,已回退为空参数。");
|
|
5787
|
+
}
|
|
5788
|
+
return {};
|
|
5789
|
+
}
|
|
5790
|
+
function collectSlotBindingExpression(node, context) {
|
|
5791
|
+
let bindObjectExp = null;
|
|
5792
|
+
const namedBindings = [];
|
|
5793
|
+
for (const prop of node.props) {
|
|
5794
|
+
if (prop.type === NodeTypes.ATTRIBUTE && prop.name === "name") continue;
|
|
5795
|
+
if (prop.type === NodeTypes.DIRECTIVE && prop.name === "bind") {
|
|
5796
|
+
if (prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5797
|
+
const rawExpValue = prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION ? prop.exp.content : "";
|
|
5798
|
+
if (prop.arg.content === "name") continue;
|
|
5799
|
+
if (rawExpValue) namedBindings.push({
|
|
5800
|
+
key: prop.arg.content,
|
|
5801
|
+
value: normalizeWxmlExpressionWithContext(rawExpValue, context)
|
|
5802
|
+
});
|
|
5803
|
+
continue;
|
|
5804
|
+
}
|
|
5805
|
+
if (prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5806
|
+
bindObjectExp = normalizeWxmlExpressionWithContext(prop.exp.content, context);
|
|
5807
|
+
continue;
|
|
5808
|
+
}
|
|
5809
|
+
}
|
|
5810
|
+
if (prop.type === NodeTypes.ATTRIBUTE && prop.name !== "name") {
|
|
5811
|
+
const literal = prop.value?.type === NodeTypes.TEXT ? prop.value.content : "";
|
|
5812
|
+
if (literal) namedBindings.push({
|
|
5813
|
+
key: prop.name,
|
|
5814
|
+
value: `'${literal.replace(BACKSLASH_RE, "\\\\").replace(SINGLE_QUOTE_RE, "\\'")}'`
|
|
5815
|
+
});
|
|
5816
|
+
}
|
|
5817
|
+
}
|
|
5818
|
+
if (bindObjectExp && namedBindings.length) {
|
|
5819
|
+
context.warnings.push("作用域插槽参数使用 v-bind 对象时,将忽略额外的命名绑定。");
|
|
5820
|
+
namedBindings.length = 0;
|
|
5821
|
+
}
|
|
5822
|
+
if (bindObjectExp) return bindObjectExp;
|
|
5823
|
+
if (!namedBindings.length) return null;
|
|
5824
|
+
return `[${namedBindings.map((entry) => `${toWxmlStringLiteral$1(entry.key)},${entry.value}`).join(",")}]`;
|
|
5825
|
+
}
|
|
5615
5826
|
//#endregion
|
|
5616
5827
|
//#region src/plugins/vue/compiler/template/elements/tag-slot.ts
|
|
5617
5828
|
function renderSlotNameAttribute(info, context, attrName) {
|
|
@@ -5663,53 +5874,6 @@ function stringifySlotName(info, context) {
|
|
|
5663
5874
|
if (info.type === "static") return info.value === "default" ? "'default'" : `'${info.value}'`;
|
|
5664
5875
|
return normalizeWxmlExpressionWithContext(info.exp, context);
|
|
5665
5876
|
}
|
|
5666
|
-
function parseSlotPropsExpression(exp, context) {
|
|
5667
|
-
const trimmed = exp.trim();
|
|
5668
|
-
if (!trimmed) return {};
|
|
5669
|
-
try {
|
|
5670
|
-
const stmt = parse$2(`(${trimmed}) => {}`, {
|
|
5671
|
-
sourceType: "module",
|
|
5672
|
-
plugins: ["typescript"]
|
|
5673
|
-
}).program.body[0];
|
|
5674
|
-
if (!stmt || !("expression" in stmt)) return {};
|
|
5675
|
-
const expression = stmt.expression;
|
|
5676
|
-
if (!t.isArrowFunctionExpression(expression)) return {};
|
|
5677
|
-
const param = expression.params[0];
|
|
5678
|
-
if (!param) return {};
|
|
5679
|
-
if (t.isIdentifier(param)) return { [param.name]: "" };
|
|
5680
|
-
if (t.isObjectPattern(param)) {
|
|
5681
|
-
const mapping = {};
|
|
5682
|
-
for (const prop of param.properties) {
|
|
5683
|
-
if (t.isRestElement(prop)) {
|
|
5684
|
-
context.warnings.push("小程序不支持作用域插槽的剩余解构元素。");
|
|
5685
|
-
continue;
|
|
5686
|
-
}
|
|
5687
|
-
if (!t.isObjectProperty(prop)) continue;
|
|
5688
|
-
const key = prop.key;
|
|
5689
|
-
const propName = t.isIdentifier(key) ? key.name : t.isStringLiteral(key) ? key.value : void 0;
|
|
5690
|
-
if (!propName) {
|
|
5691
|
-
context.warnings.push("小程序不支持作用域插槽的计算属性键。");
|
|
5692
|
-
continue;
|
|
5693
|
-
}
|
|
5694
|
-
const value = prop.value;
|
|
5695
|
-
if (t.isIdentifier(value)) {
|
|
5696
|
-
mapping[value.name] = propName;
|
|
5697
|
-
continue;
|
|
5698
|
-
}
|
|
5699
|
-
if (t.isAssignmentPattern(value) && t.isIdentifier(value.left)) {
|
|
5700
|
-
mapping[value.left.name] = propName;
|
|
5701
|
-
context.warnings.push("不支持作用域插槽参数的默认值,默认值将被忽略。");
|
|
5702
|
-
continue;
|
|
5703
|
-
}
|
|
5704
|
-
context.warnings.push("作用域插槽解构仅支持标识符绑定。");
|
|
5705
|
-
}
|
|
5706
|
-
return mapping;
|
|
5707
|
-
}
|
|
5708
|
-
} catch {
|
|
5709
|
-
context.warnings.push("作用域插槽参数解析失败,已回退为空参数。");
|
|
5710
|
-
}
|
|
5711
|
-
return {};
|
|
5712
|
-
}
|
|
5713
5877
|
function buildSlotDeclaration(name, propsExp, children, context) {
|
|
5714
5878
|
return {
|
|
5715
5879
|
name,
|
|
@@ -5767,39 +5931,7 @@ function renderSlotFallback(decl, context, transformNode) {
|
|
|
5767
5931
|
function transformSlotElement(node, context, transformNode) {
|
|
5768
5932
|
if (isScopedSlotsDisabled(context)) return transformSlotElementPlain(node, context, transformNode);
|
|
5769
5933
|
const slotNameInfo = resolveSlotNameFromSlotElement(node);
|
|
5770
|
-
let
|
|
5771
|
-
const namedBindings = [];
|
|
5772
|
-
for (const prop of node.props) {
|
|
5773
|
-
if (prop.type === NodeTypes.ATTRIBUTE && prop.name === "name") continue;
|
|
5774
|
-
if (prop.type === NodeTypes.DIRECTIVE && prop.name === "bind") {
|
|
5775
|
-
if (prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5776
|
-
const rawExpValue = prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION ? prop.exp.content : "";
|
|
5777
|
-
if (prop.arg.content === "name") continue;
|
|
5778
|
-
if (rawExpValue) namedBindings.push({
|
|
5779
|
-
key: prop.arg.content,
|
|
5780
|
-
value: normalizeWxmlExpressionWithContext(rawExpValue, context)
|
|
5781
|
-
});
|
|
5782
|
-
continue;
|
|
5783
|
-
}
|
|
5784
|
-
if (prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
5785
|
-
bindObjectExp = normalizeWxmlExpressionWithContext(prop.exp.content, context);
|
|
5786
|
-
continue;
|
|
5787
|
-
}
|
|
5788
|
-
}
|
|
5789
|
-
if (prop.type === NodeTypes.ATTRIBUTE && prop.name !== "name") {
|
|
5790
|
-
const literal = prop.value?.type === NodeTypes.TEXT ? prop.value.content : "";
|
|
5791
|
-
if (literal) namedBindings.push({
|
|
5792
|
-
key: prop.name,
|
|
5793
|
-
value: `'${literal.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`
|
|
5794
|
-
});
|
|
5795
|
-
}
|
|
5796
|
-
}
|
|
5797
|
-
if (bindObjectExp && namedBindings.length) {
|
|
5798
|
-
context.warnings.push("作用域插槽参数使用 v-bind 对象时,将忽略额外的命名绑定。");
|
|
5799
|
-
namedBindings.length = 0;
|
|
5800
|
-
}
|
|
5801
|
-
let slotPropsExp = bindObjectExp;
|
|
5802
|
-
if (!slotPropsExp && namedBindings.length) slotPropsExp = `[${namedBindings.map((entry) => `${toWxmlStringLiteral$1(entry.key)},${entry.value}`).join(",")}]`;
|
|
5934
|
+
let slotPropsExp = collectSlotBindingExpression(node, context);
|
|
5803
5935
|
let fallbackContent = "";
|
|
5804
5936
|
if (node.children.length > 0) fallbackContent = node.children.map((child) => transformNode(child, context)).join("");
|
|
5805
5937
|
if (slotPropsExp && fallbackContent) {
|
|
@@ -5814,8 +5946,8 @@ function transformSlotElement(node, context, transformNode) {
|
|
|
5814
5946
|
if (context.scopedSlotsRequireProps && !slotPropsExp) return slotTag;
|
|
5815
5947
|
const genericKey = `scoped-slots-${resolveSlotKey(context, slotNameInfo)}`;
|
|
5816
5948
|
context.componentGenerics[genericKey] = true;
|
|
5817
|
-
|
|
5818
|
-
const scopedAttrs = [`__wv-owner-id="${renderMustache("__wvSlotOwnerId", context)}"`, `__wv-slot-props="${renderMustache(
|
|
5949
|
+
slotPropsExp = slotPropsExp ?? "[]";
|
|
5950
|
+
const scopedAttrs = [`__wv-owner-id="${renderMustache("__wvSlotOwnerId", context)}"`, `__wv-slot-props="${renderMustache(slotPropsExp, context)}"`];
|
|
5819
5951
|
if (context.slotMultipleInstance) scopedAttrs.push(`__wv-slot-scope="${renderMustache("__wvSlotScope", context)}"`);
|
|
5820
5952
|
return `${slotTag}${`<${genericKey}${scopedAttrs.length ? ` ${scopedAttrs.join(" ")}` : ""} />`}`;
|
|
5821
5953
|
}
|
|
@@ -5832,7 +5964,6 @@ function transformSlotElementPlain(node, context, transformNode) {
|
|
|
5832
5964
|
const slotAttrString = slotAttrs.length ? ` ${slotAttrs.join(" ")}` : "";
|
|
5833
5965
|
return fallbackContent ? `<slot${slotAttrString}>${fallbackContent}</slot>` : `<slot${slotAttrString} />`;
|
|
5834
5966
|
}
|
|
5835
|
-
|
|
5836
5967
|
//#endregion
|
|
5837
5968
|
//#region src/plugins/vue/compiler/template/elements/tag-component.ts
|
|
5838
5969
|
function transformComponentWithSlots(node, context, transformNode, options) {
|
|
@@ -5985,7 +6116,6 @@ function transformComponentElement(node, context, transformNode) {
|
|
|
5985
6116
|
context.warnings.push("动态组件使用 data-is 属性,可能需要小程序运行时支持。");
|
|
5986
6117
|
return `<component data-is="${renderMustache(componentVar, context)}"${attrString}>${children}</component>`;
|
|
5987
6118
|
}
|
|
5988
|
-
|
|
5989
6119
|
//#endregion
|
|
5990
6120
|
//#region src/plugins/vue/compiler/template/elements/tag-normal.ts
|
|
5991
6121
|
function transformNormalElement(node, context, transformNode) {
|
|
@@ -6000,9 +6130,9 @@ function transformNormalElement(node, context, transformNode) {
|
|
|
6000
6130
|
const attrString = attrs.length ? ` ${attrs.join(" ")}` : "";
|
|
6001
6131
|
return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
|
|
6002
6132
|
}
|
|
6003
|
-
|
|
6004
6133
|
//#endregion
|
|
6005
6134
|
//#region src/plugins/vue/compiler/template/elements/tag-structural.ts
|
|
6135
|
+
const REGEX_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
|
|
6006
6136
|
function resolveConditionExpression$1(rawExpValue, context, hint) {
|
|
6007
6137
|
return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
6008
6138
|
}
|
|
@@ -6035,11 +6165,11 @@ function transformForElement(node, context, transformNode) {
|
|
|
6035
6165
|
const forDirective = node.props.find((prop) => prop.type === NodeTypes.DIRECTIVE && prop.name === "for");
|
|
6036
6166
|
if (!forDirective || !forDirective.exp) return transformNormalElement(node, context, transformNode);
|
|
6037
6167
|
const forInfo = parseForExpression(forDirective.exp.type === NodeTypes.SIMPLE_EXPRESSION ? forDirective.exp.content : "");
|
|
6038
|
-
if (forInfo.item ===
|
|
6168
|
+
if (forInfo.item === "__wv_for_item__") {
|
|
6039
6169
|
const generatedItem = `__wv_item_${context.forIndexSeed++}`;
|
|
6040
6170
|
forInfo.item = generatedItem;
|
|
6041
6171
|
if (forInfo.itemAliases) {
|
|
6042
|
-
const escaped = FOR_ITEM_ALIAS_PLACEHOLDER.replace(
|
|
6172
|
+
const escaped = FOR_ITEM_ALIAS_PLACEHOLDER.replace(REGEX_SPECIAL_CHARS_RE, "\\$&");
|
|
6043
6173
|
const placeholderRE = new RegExp(`\\b${escaped}\\b`, "g");
|
|
6044
6174
|
forInfo.itemAliases = Object.fromEntries(Object.entries(forInfo.itemAliases).map(([alias, expression]) => {
|
|
6045
6175
|
return [alias, expression.replace(placeholderRE, generatedItem)];
|
|
@@ -6088,9 +6218,10 @@ function transformForElement(node, context, transformNode) {
|
|
|
6088
6218
|
return children ? `<${tag}${attrString}>${children}</${tag}>` : `<${tag}${attrString} />`;
|
|
6089
6219
|
}));
|
|
6090
6220
|
}
|
|
6091
|
-
|
|
6092
6221
|
//#endregion
|
|
6093
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;
|
|
6094
6225
|
function resolveConditionExpression(rawExpValue, context, hint) {
|
|
6095
6226
|
return (shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
6096
6227
|
}
|
|
@@ -6149,7 +6280,7 @@ function transformTemplateElement(node, context, transformNode) {
|
|
|
6149
6280
|
if (dir.name === "else") return context.platform.wrapElse(children);
|
|
6150
6281
|
return transformIfElement(fakeNode, context, transformNode);
|
|
6151
6282
|
}
|
|
6152
|
-
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>");
|
|
6153
6284
|
return children;
|
|
6154
6285
|
}
|
|
6155
6286
|
const attrs = [];
|
|
@@ -6158,7 +6289,6 @@ function transformTemplateElement(node, context, transformNode) {
|
|
|
6158
6289
|
if (dataAttr) attrs.push(`data="${dataAttr}"`);
|
|
6159
6290
|
return `<template${attrs.length ? ` ${attrs.join(" ")}` : ""}>${children}</template>`;
|
|
6160
6291
|
}
|
|
6161
|
-
|
|
6162
6292
|
//#endregion
|
|
6163
6293
|
//#region src/plugins/vue/compiler/template/elements/index.ts
|
|
6164
6294
|
function transformElement(node, context, transformNode) {
|
|
@@ -6173,12 +6303,14 @@ function transformElement(node, context, transformNode) {
|
|
|
6173
6303
|
if (type === "for") return transformForElement(node, context, transformNode);
|
|
6174
6304
|
return transformNormalElement(node, context, transformNode);
|
|
6175
6305
|
}
|
|
6176
|
-
|
|
6177
6306
|
//#endregion
|
|
6178
6307
|
//#region src/plugins/vue/compiler/template/nodes.ts
|
|
6308
|
+
const AMP_RE = /&/g;
|
|
6309
|
+
const LT_RE = /</g;
|
|
6310
|
+
const GT_RE = />/g;
|
|
6179
6311
|
function escapeWxmlText(value) {
|
|
6180
6312
|
if (!value) return "";
|
|
6181
|
-
return value.replace(
|
|
6313
|
+
return value.replace(AMP_RE, "&").replace(LT_RE, "<").replace(GT_RE, ">");
|
|
6182
6314
|
}
|
|
6183
6315
|
function transformText(node, _context) {
|
|
6184
6316
|
return escapeWxmlText(node.content);
|
|
@@ -6203,9 +6335,24 @@ function transformNode(node, context) {
|
|
|
6203
6335
|
return "";
|
|
6204
6336
|
}
|
|
6205
6337
|
}
|
|
6206
|
-
|
|
6207
6338
|
//#endregion
|
|
6208
6339
|
//#region src/plugins/vue/compiler/template.ts
|
|
6340
|
+
const HTML_VOID_TAGS = new Set([
|
|
6341
|
+
"area",
|
|
6342
|
+
"base",
|
|
6343
|
+
"br",
|
|
6344
|
+
"col",
|
|
6345
|
+
"embed",
|
|
6346
|
+
"hr",
|
|
6347
|
+
"img",
|
|
6348
|
+
"input",
|
|
6349
|
+
"link",
|
|
6350
|
+
"meta",
|
|
6351
|
+
"param",
|
|
6352
|
+
"source",
|
|
6353
|
+
"track",
|
|
6354
|
+
"wbr"
|
|
6355
|
+
]);
|
|
6209
6356
|
/**
|
|
6210
6357
|
* 将 Vue 模板编译为 WXML。
|
|
6211
6358
|
*/
|
|
@@ -6216,9 +6363,12 @@ function compileVueTemplateToWxml(template, filename, options) {
|
|
|
6216
6363
|
const wxsExtension = options?.wxsExtension;
|
|
6217
6364
|
const scopedSlotsRequireProps = options?.scopedSlotsRequireProps ?? options?.scopedSlotsCompiler !== "augmented";
|
|
6218
6365
|
try {
|
|
6219
|
-
const ast = baseParse(template, {
|
|
6220
|
-
|
|
6221
|
-
|
|
6366
|
+
const ast = baseParse(template, {
|
|
6367
|
+
isVoidTag: (tag) => HTML_VOID_TAGS.has(tag),
|
|
6368
|
+
onError: (error) => {
|
|
6369
|
+
warnings.push(`模板解析失败:${error.message}`);
|
|
6370
|
+
}
|
|
6371
|
+
});
|
|
6222
6372
|
const context = {
|
|
6223
6373
|
source: template,
|
|
6224
6374
|
filename,
|
|
@@ -6270,7 +6420,6 @@ function compileVueTemplateToWxml(template, filename, options) {
|
|
|
6270
6420
|
};
|
|
6271
6421
|
}
|
|
6272
6422
|
}
|
|
6273
|
-
|
|
6274
6423
|
//#endregion
|
|
6275
6424
|
//#region src/plugins/vue/transform/config.ts
|
|
6276
6425
|
/**
|
|
@@ -6361,7 +6510,6 @@ async function compileConfigBlocks(blocks, filename, options) {
|
|
|
6361
6510
|
if (Reflect.has(accumulator, "$schema")) delete accumulator.$schema;
|
|
6362
6511
|
return JSON.stringify(accumulator, null, 2);
|
|
6363
6512
|
}
|
|
6364
|
-
|
|
6365
6513
|
//#endregion
|
|
6366
6514
|
//#region src/plugins/vue/transform/compileVueFile/config.ts
|
|
6367
6515
|
function collectTemplateAutoImportTags(template, filename, warn) {
|
|
@@ -6421,7 +6569,6 @@ async function compileConfigPhase(params) {
|
|
|
6421
6569
|
if (scriptSetupMacroConfig && Object.keys(scriptSetupMacroConfig).length > 0) configObj = mergeJson(configObj ?? {}, scriptSetupMacroConfig, "macro");
|
|
6422
6570
|
if (configObj && Object.keys(configObj).length > 0) result.config = JSON.stringify(configObj, null, 2);
|
|
6423
6571
|
}
|
|
6424
|
-
|
|
6425
6572
|
//#endregion
|
|
6426
6573
|
//#region src/plugins/vue/transform/compileVueFile/finalize.ts
|
|
6427
6574
|
function finalizeResult(result, options) {
|
|
@@ -6429,9 +6576,17 @@ function finalizeResult(result, options) {
|
|
|
6429
6576
|
if (result.meta && options.scriptSetupMacroHash) result.meta.jsonMacroHash = options.scriptSetupMacroHash;
|
|
6430
6577
|
if (result.meta && options.defineOptionsHash) result.meta.defineOptionsHash = options.defineOptionsHash;
|
|
6431
6578
|
}
|
|
6432
|
-
|
|
6433
6579
|
//#endregion
|
|
6434
|
-
//#region src/plugins/vue/transform/defineOptions/
|
|
6580
|
+
//#region src/plugins/vue/transform/defineOptions/serialize.ts
|
|
6581
|
+
function getErrorMessage(error) {
|
|
6582
|
+
if (error instanceof Error) return error.message;
|
|
6583
|
+
return typeof error === "string" ? error : "";
|
|
6584
|
+
}
|
|
6585
|
+
const BEHAVIOR_NOT_DEFINED_RE = /\bBehavior is not defined\b/;
|
|
6586
|
+
function shouldFallbackToRawDefineOptions(error) {
|
|
6587
|
+
const message = getErrorMessage(error);
|
|
6588
|
+
return BEHAVIOR_NOT_DEFINED_RE.test(message);
|
|
6589
|
+
}
|
|
6435
6590
|
function normalizeScriptSetupLang(lang) {
|
|
6436
6591
|
if (!lang) return "ts";
|
|
6437
6592
|
const lower = lang.toLowerCase();
|
|
@@ -6443,8 +6598,9 @@ function resolveScriptSetupExtension(lang) {
|
|
|
6443
6598
|
if (normalized === "ts" || normalized === "tsx" || normalized === "cts" || normalized === "mts") return "ts";
|
|
6444
6599
|
return "js";
|
|
6445
6600
|
}
|
|
6601
|
+
const IDENTIFIER_LIKE_KEY_RE = /^[A-Z_$][\w$]*$/i;
|
|
6446
6602
|
function isIdentifierLikeKey(key) {
|
|
6447
|
-
return
|
|
6603
|
+
return IDENTIFIER_LIKE_KEY_RE.test(key);
|
|
6448
6604
|
}
|
|
6449
6605
|
const SERIALIZABLE_NATIVE_FUNCTIONS = new Map([
|
|
6450
6606
|
[String, "String"],
|
|
@@ -6528,6 +6684,8 @@ function serializeStaticValueToExpression(value, seen = /* @__PURE__ */ new Weak
|
|
|
6528
6684
|
}
|
|
6529
6685
|
throw new Error(`defineOptions 的参数中包含不支持的值类型:${valueType}`);
|
|
6530
6686
|
}
|
|
6687
|
+
//#endregion
|
|
6688
|
+
//#region src/plugins/vue/transform/defineOptions/inline.ts
|
|
6531
6689
|
function collectDefineOptionsStatements(content, filename) {
|
|
6532
6690
|
const ast = parse$2(content, BABEL_TS_MODULE_PARSER_OPTIONS);
|
|
6533
6691
|
const statements = [];
|
|
@@ -6623,12 +6781,24 @@ async function inlineScriptSetupDefineOptionsArgs(content, filename, lang) {
|
|
|
6623
6781
|
code: content,
|
|
6624
6782
|
dependencies: []
|
|
6625
6783
|
};
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
6784
|
+
let values = [];
|
|
6785
|
+
let dependencies = [];
|
|
6786
|
+
try {
|
|
6787
|
+
const evaluated = await evaluateDefineOptionsValues({
|
|
6788
|
+
content,
|
|
6789
|
+
filename,
|
|
6790
|
+
lang,
|
|
6791
|
+
statements
|
|
6792
|
+
});
|
|
6793
|
+
values = evaluated.values;
|
|
6794
|
+
dependencies = evaluated.dependencies;
|
|
6795
|
+
} catch (error) {
|
|
6796
|
+
if (shouldFallbackToRawDefineOptions(error)) return {
|
|
6797
|
+
code: content,
|
|
6798
|
+
dependencies: []
|
|
6799
|
+
};
|
|
6800
|
+
throw error;
|
|
6801
|
+
}
|
|
6632
6802
|
const ms = new MagicString(content);
|
|
6633
6803
|
for (let index = 0; index < statements.length; index += 1) {
|
|
6634
6804
|
const argNode = statements[index].argPath?.node;
|
|
@@ -6641,9 +6811,11 @@ async function inlineScriptSetupDefineOptionsArgs(content, filename, lang) {
|
|
|
6641
6811
|
dependencies: dependencies.filter(Boolean)
|
|
6642
6812
|
};
|
|
6643
6813
|
}
|
|
6644
|
-
|
|
6645
6814
|
//#endregion
|
|
6646
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$/;
|
|
6647
6819
|
function extractDefineOptionsHash(content) {
|
|
6648
6820
|
let ast;
|
|
6649
6821
|
try {
|
|
@@ -6686,7 +6858,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6686
6858
|
let descriptorForCompile = resolvedDescriptor;
|
|
6687
6859
|
const meta = {
|
|
6688
6860
|
hasScriptSetup: !!resolvedDescriptor.scriptSetup,
|
|
6689
|
-
hasSetupOption: !!resolvedDescriptor.script &&
|
|
6861
|
+
hasSetupOption: !!resolvedDescriptor.script && SETUP_CALL_RE.test(resolvedDescriptor.script.content),
|
|
6690
6862
|
sfcSrcDeps
|
|
6691
6863
|
};
|
|
6692
6864
|
let scriptSetupMacroConfig;
|
|
@@ -6727,8 +6899,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6727
6899
|
const resolvedNext = await resolveSfcBlockSrc(nextDescriptor, filename, options.sfcSrc);
|
|
6728
6900
|
descriptorForCompile = resolvedNext.descriptor;
|
|
6729
6901
|
if (resolvedNext.deps.length) {
|
|
6730
|
-
|
|
6731
|
-
sfcSrcDeps = Array.from(deps);
|
|
6902
|
+
sfcSrcDeps = [...new Set([...sfcSrcDeps ?? [], ...resolvedNext.deps])];
|
|
6732
6903
|
meta.sfcSrcDeps = sfcSrcDeps;
|
|
6733
6904
|
}
|
|
6734
6905
|
} else descriptorForCompile = nextDescriptor;
|
|
@@ -6739,7 +6910,7 @@ async function parseVueFile(source, filename, options) {
|
|
|
6739
6910
|
defineOptionsHash = extractDefineOptionsHash(scriptSetup.content);
|
|
6740
6911
|
}
|
|
6741
6912
|
const compileScriptSetup = descriptorForCompile.scriptSetup;
|
|
6742
|
-
if (compileScriptSetup?.content &&
|
|
6913
|
+
if (compileScriptSetup?.content && DEFINE_OPTIONS_CALL_RE.test(compileScriptSetup.content)) {
|
|
6743
6914
|
const inlined = await inlineScriptSetupDefineOptionsArgs(compileScriptSetup.content, filename, compileScriptSetup.lang);
|
|
6744
6915
|
if (inlined.code !== compileScriptSetup.content) if (compileScriptSetup.src) descriptorForCompile = {
|
|
6745
6916
|
...descriptorForCompile,
|
|
@@ -6767,15 +6938,14 @@ async function parseVueFile(source, filename, options) {
|
|
|
6767
6938
|
const resolvedNext = await resolveSfcBlockSrc(nextDescriptor, filename, options.sfcSrc);
|
|
6768
6939
|
descriptorForCompile = resolvedNext.descriptor;
|
|
6769
6940
|
if (resolvedNext.deps.length) {
|
|
6770
|
-
|
|
6771
|
-
sfcSrcDeps = Array.from(deps);
|
|
6941
|
+
sfcSrcDeps = [...new Set([...sfcSrcDeps ?? [], ...resolvedNext.deps])];
|
|
6772
6942
|
meta.sfcSrcDeps = sfcSrcDeps;
|
|
6773
6943
|
}
|
|
6774
6944
|
} else descriptorForCompile = nextDescriptor;
|
|
6775
6945
|
descriptorForCompileSource = nextSource;
|
|
6776
6946
|
}
|
|
6777
6947
|
}
|
|
6778
|
-
const isAppFile =
|
|
6948
|
+
const isAppFile = APP_VUE_FILE_RE.test(filename);
|
|
6779
6949
|
return {
|
|
6780
6950
|
descriptor: resolvedDescriptor,
|
|
6781
6951
|
descriptorForCompile,
|
|
@@ -6789,7 +6959,6 @@ async function parseVueFile(source, filename, options) {
|
|
|
6789
6959
|
isAppFile
|
|
6790
6960
|
};
|
|
6791
6961
|
}
|
|
6792
|
-
|
|
6793
6962
|
//#endregion
|
|
6794
6963
|
//#region src/plugins/vue/transform/compileVueFile/script.ts
|
|
6795
6964
|
function collectTemplateComponentNames(template, filename, warn) {
|
|
@@ -6882,7 +7051,6 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
|
|
|
6882
7051
|
autoComponentMeta
|
|
6883
7052
|
};
|
|
6884
7053
|
}
|
|
6885
|
-
|
|
6886
7054
|
//#endregion
|
|
6887
7055
|
//#region src/plugins/vue/transform/scopedId.ts
|
|
6888
7056
|
/**
|
|
@@ -6894,7 +7062,6 @@ function generateScopedId(filename) {
|
|
|
6894
7062
|
}, 0);
|
|
6895
7063
|
return Math.abs(hash).toString(36);
|
|
6896
7064
|
}
|
|
6897
|
-
|
|
6898
7065
|
//#endregion
|
|
6899
7066
|
//#region src/plugins/vue/transform/compileVueFile/style.ts
|
|
6900
7067
|
function compileStylePhase(descriptor, filename, result) {
|
|
@@ -6920,7 +7087,6 @@ const __cssModules = ${JSON.stringify(modulesMap, null, 2)}
|
|
|
6920
7087
|
${result.script}
|
|
6921
7088
|
`;
|
|
6922
7089
|
}
|
|
6923
|
-
|
|
6924
7090
|
//#endregion
|
|
6925
7091
|
//#region src/plugins/vue/transform/compileVueFile/template.ts
|
|
6926
7092
|
function compileTemplatePhase(descriptor, filename, options, result) {
|
|
@@ -6932,7 +7098,6 @@ function compileTemplatePhase(descriptor, filename, options, result) {
|
|
|
6932
7098
|
if (templateCompiled.classStyleWxs) result.classStyleWxs = true;
|
|
6933
7099
|
return templateCompiled;
|
|
6934
7100
|
}
|
|
6935
|
-
|
|
6936
7101
|
//#endregion
|
|
6937
7102
|
//#region src/plugins/vue/transform/compileVueFile/index.ts
|
|
6938
7103
|
/**
|
|
@@ -6965,6 +7130,5 @@ async function compileVueFile(source, filename, options) {
|
|
|
6965
7130
|
});
|
|
6966
7131
|
return result;
|
|
6967
7132
|
}
|
|
6968
|
-
|
|
6969
7133
|
//#endregion
|
|
6970
|
-
export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectVueTemplateTags, collectWevuPageFeatureFlags, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|
|
7134
|
+
export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectVueTemplateTags, collectWevuPageFeatureFlags, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|