@unmagic/vms 0.0.2 → 0.0.3

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.
@@ -939,22 +939,22 @@ function checkSlotsUsage(templateContent) {
939
939
  return templateContent.includes('slot') || templateContent.includes('Slot');
940
940
  }
941
941
  /**
942
- * 确保 @vue-mini/core 中导入了指定的 specifierName。
943
- * 如果已存在则跳过,否则追加到已有的 @vue-mini/core import 或新建一个。
942
+ * 确保 @unmagic/vue-mini 中导入了指定的 specifierName。
943
+ * 如果已存在则跳过,否则追加到已有的 @unmagic/vue-mini import 或新建一个。
944
944
  */
945
945
  function ensureCoreImport(sfcContext, specifierName) {
946
- const hasImport = sfcContext.importAST.some((importNode) => importNode.source.value === '@vue-mini/core' &&
946
+ const hasImport = sfcContext.importAST.some((importNode) => importNode.source.value === '@unmagic/vue-mini' &&
947
947
  importNode.specifiers.some((spec) => t.isImportSpecifier(spec) &&
948
948
  t.isIdentifier(spec.imported) &&
949
949
  spec.imported.name === specifierName));
950
950
  if (hasImport)
951
951
  return;
952
- const vueImport = sfcContext.importAST.find((importNode) => t.isImportDeclaration(importNode) && importNode.source.value === '@vue-mini/core');
952
+ const vueImport = sfcContext.importAST.find((importNode) => t.isImportDeclaration(importNode) && importNode.source.value === '@unmagic/vue-mini');
953
953
  if (vueImport && t.isImportDeclaration(vueImport)) {
954
954
  vueImport.specifiers.push(t.importSpecifier(t.identifier(specifierName), t.identifier(specifierName)));
955
955
  }
956
956
  else {
957
- sfcContext.importAST.push(t.importDeclaration([t.importSpecifier(t.identifier(specifierName), t.identifier(specifierName))], t.stringLiteral('@vue-mini/core')));
957
+ sfcContext.importAST.push(t.importDeclaration([t.importSpecifier(t.identifier(specifierName), t.identifier(specifierName))], t.stringLiteral('@unmagic/vue-mini')));
958
958
  }
959
959
  }
960
960
  async function extractSetupBodyUsingAST(scriptContent, returnValue, bridgedFunctions, internalVars, renderVars, needsProxyRefs, isPage, scriptScope) {
@@ -1273,7 +1273,7 @@ async function parseScript(descriptor, returnValue, bridgedFunctions = new Set()
1273
1273
  const { sfcContext, setupFunAst } = await extractSetupBodyUsingAST(script, returnValue, bridgedFunctions, internalVars, renderVars, needsProxyRefs, isPage, scriptScope);
1274
1274
  // 生成import抽象语法
1275
1275
  const programBody = [
1276
- t.importDeclaration([t.importSpecifier(t.identifier('defineComponent'), t.identifier('defineComponent'))], t.stringLiteral('@vue-mini/core')),
1276
+ t.importDeclaration([t.importSpecifier(t.identifier('defineComponent'), t.identifier('defineComponent'))], t.stringLiteral('@unmagic/vue-mini')),
1277
1277
  ...sfcContext.importAST,
1278
1278
  ];
1279
1279
  // 生成defineComponent参数
@@ -1343,37 +1343,38 @@ async function parseScript(descriptor, returnValue, bridgedFunctions = new Set()
1343
1343
  /**
1344
1344
  * 替换函数中的 props 变量访问
1345
1345
  * 将 __vmsProxyRefs.propName 替换为 __vmsProps.propName
1346
+ * 使用 Babel VISITOR_KEYS 进行正确的 AST 遍历,
1347
+ * 只访问有意义的子节点,避免遍历 Babel 内部属性。
1346
1348
  */
1347
1349
  function replacePropsAccessInFunction(func, propsVarNames, propsVarName) {
1348
- // 递归遍历函数体中的所有 MemberExpression
1350
+ // 使用 Babel VISITOR_KEYS 遍历,只处理有意义的子节点
1349
1351
  function traverseNode(node) {
1350
- if (!node)
1352
+ if (!node || typeof node !== 'object')
1351
1353
  return;
1352
- // 检查当前节点是否是 MemberExpression
1354
+ // 处理 MemberExpression:检查并替换 __vmsProxyRefs.propName
1353
1355
  if (t.isMemberExpression(node)) {
1354
- // 检查是否是 __vmsProxyRefs.propName 形式
1355
1356
  if (t.isIdentifier(node.object, { name: '__vmsProxyRefs' }) &&
1356
1357
  t.isIdentifier(node.property) &&
1357
1358
  propsVarNames.has(node.property.name)) {
1358
- // 替换为 __vmsProps.propName
1359
1359
  node.object = t.identifier(propsVarName);
1360
1360
  }
1361
1361
  }
1362
- // 递归遍历子节点
1363
- if (typeof node === 'object') {
1364
- for (const key in node) {
1365
- const value = node[key];
1366
- if (Array.isArray(value)) {
1367
- value.forEach((item) => {
1368
- if (typeof item === 'object' && item !== null) {
1369
- traverseNode(item);
1370
- }
1371
- });
1372
- }
1373
- else if (typeof value === 'object' && value !== null && value.type) {
1374
- traverseNode(value);
1362
+ // 使用 VISITOR_KEYS 获取该节点类型的有效子节点属性名
1363
+ const visitorKeys = t.VISITOR_KEYS[node.type];
1364
+ if (!visitorKeys)
1365
+ return;
1366
+ for (const key of visitorKeys) {
1367
+ const value = node[key];
1368
+ if (Array.isArray(value)) {
1369
+ for (const child of value) {
1370
+ if (child && typeof child === 'object' && Object.hasOwn(child, 'type')) {
1371
+ traverseNode(child);
1372
+ }
1375
1373
  }
1376
1374
  }
1375
+ else if (value && typeof value === 'object' && Object.hasOwn(value, 'type')) {
1376
+ traverseNode(value);
1377
+ }
1377
1378
  }
1378
1379
  }
1379
1380
  traverseNode(func);
@@ -3442,262 +3443,161 @@ function processArrowFunctionExpression(ast, counter, callExpressionWithArgs, ex
3442
3443
  const wrappedBody = t__default.blockStatement([t__default.expressionStatement(body)]);
3443
3444
  return processInlineArrowFunction(wrappedBody, arrowFunctionArguments, counter, callExpressionWithArgs, excludeBindingVars, node, returnValue, ctx, isAsync);
3444
3445
  }
3445
- else if (t__default.isConditionalExpression(body)) {
3446
+ else if (t__default.isConditionalExpression(body) || t__default.isLogicalExpression(body)) {
3446
3447
  // 处理三元表达式:(e) => flag ? a() : b()
3447
- // 收集条件表达式中使用的外部变量
3448
+ // 处理逻辑表达式:(e) => flag && onClick(e)
3448
3449
  const vForInfoList = getVForInfoList(ctx, node);
3449
3450
  const vForVars = getVForVariables(ctx, node);
3450
- const arrowFunctionArgumentNames = arrowFunctionArguments.length > 0
3451
- ? new Set(arrowFunctionArguments
3452
- .map((p) => (t__default.isIdentifier(p) ? p.name : ''))
3453
- .filter(Boolean))
3454
- : undefined;
3455
- // 收集 test、consequent、alternate 中的外部变量
3456
- const varsToCollect = new Set();
3457
- const collectVarsFromNode = (node) => {
3458
- if (t__default.isIdentifier(node)) {
3459
- const name = node.name;
3460
- if (name !== EVENT_PARAM_NAME &&
3461
- name !== '$event' &&
3462
- !GLOBAL_WHITELIST.has(name) &&
3463
- !(arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) &&
3464
- !vForVars.has(name)) {
3465
- varsToCollect.add(name);
3466
- }
3467
- }
3468
- else if (t__default.isMemberExpression(node)) {
3469
- collectVarsFromNode(node.object);
3470
- }
3471
- else if (t__default.isCallExpression(node)) {
3472
- collectVarsFromNode(node.callee);
3473
- node.arguments.forEach((arg) => collectVarsFromNode(arg));
3474
- }
3475
- else if (t__default.isConditionalExpression(node)) {
3476
- collectVarsFromNode(node.test);
3477
- collectVarsFromNode(node.consequent);
3478
- collectVarsFromNode(node.alternate);
3479
- }
3480
- else if (t__default.isLogicalExpression(node) || t__default.isBinaryExpression(node)) {
3481
- collectVarsFromNode(node.left);
3482
- collectVarsFromNode(node.right);
3483
- }
3484
- else if (t__default.isUnaryExpression(node)) {
3485
- collectVarsFromNode(node.argument);
3451
+ return createShortExprHandler(body, arrowFunctionArguments, callExpressionWithArgs, vForInfoList, vForVars, ctx, counter, returnValue, isAsync);
3452
+ }
3453
+ return '';
3454
+ }
3455
+ function collectExternalVarsFromExpression(body, arrowFunctionArgumentNames, vForVars) {
3456
+ const varsToCollect = new Set();
3457
+ const collectVarsFromNode = (node) => {
3458
+ if (t__default.isIdentifier(node)) {
3459
+ const name = node.name;
3460
+ if (name !== EVENT_PARAM_NAME &&
3461
+ name !== '$event' &&
3462
+ !GLOBAL_WHITELIST.has(name) &&
3463
+ !(arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) &&
3464
+ !vForVars.has(name)) {
3465
+ varsToCollect.add(name);
3486
3466
  }
3487
- };
3467
+ }
3468
+ else if (t__default.isMemberExpression(node)) {
3469
+ collectVarsFromNode(node.object);
3470
+ }
3471
+ else if (t__default.isCallExpression(node)) {
3472
+ collectVarsFromNode(node.callee);
3473
+ node.arguments.forEach((arg) => collectVarsFromNode(arg));
3474
+ }
3475
+ else if (t__default.isConditionalExpression(node)) {
3476
+ collectVarsFromNode(node.test);
3477
+ collectVarsFromNode(node.consequent);
3478
+ collectVarsFromNode(node.alternate);
3479
+ }
3480
+ else if (t__default.isLogicalExpression(node) || t__default.isBinaryExpression(node)) {
3481
+ collectVarsFromNode(node.left);
3482
+ collectVarsFromNode(node.right);
3483
+ }
3484
+ else if (t__default.isUnaryExpression(node)) {
3485
+ collectVarsFromNode(node.argument);
3486
+ }
3487
+ };
3488
+ // 收集对应表达式类型的节点
3489
+ if (t__default.isConditionalExpression(body)) {
3488
3490
  collectVarsFromNode(body.test);
3489
3491
  collectVarsFromNode(body.consequent);
3490
3492
  collectVarsFromNode(body.alternate);
3491
- // 将收集的变量添加到 returnValue
3492
- varsToCollect.forEach((varName) => {
3493
- if (!shouldSkipVariable(varName, ctx.scriptScope)) {
3494
- addProperty(returnValue, varName);
3495
- ctx.internalVars.add(varName);
3496
- }
3497
- });
3498
- // 标记需要 __vmsProxyRefs
3499
- if (varsToCollect.size > 0) {
3500
- ctx.needsProxyRefs = true;
3501
- }
3502
- // 生成桥接函数
3503
- const functionName = counter.generateFunctionPropertyName();
3504
- const dataKey = vForInfoList && vForInfoList.length > 0
3505
- ? getFunctionIndexChar(counter.nodeDataKeyIndex++)
3506
- : '';
3507
- // 处理参数
3508
- const statements = [];
3509
- if (arrowFunctionArguments.length > 0) {
3510
- const param = arrowFunctionArguments[0];
3511
- if (t__default.isIdentifier(param) && param.name !== '$event' && param.name !== EVENT_PARAM_NAME) {
3512
- statements.push(t__default.variableDeclaration('const', [
3513
- t__default.variableDeclarator(param, t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'))),
3514
- ]));
3515
- }
3516
- }
3517
- // 处理 v-for dataset 获取
3518
- if (vForInfoList && vForInfoList.length > 0) {
3519
- const indices = vForInfoList.map((info) => getVForIndexName(info) || 'index');
3520
- const indexVars = indices.map((idx) => t__default.identifier(idx));
3521
- statements.push(t__default.variableDeclaration('const', [
3522
- t__default.variableDeclarator(t__default.objectPattern([
3523
- t__default.objectProperty(t__default.identifier(dataKey), t__default.arrayPattern(indexVars), false, false),
3524
- ]), t__default.memberExpression(t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('currentTarget')), t__default.identifier('dataset'))),
3525
- ]));
3526
- }
3527
- // 构建处理后的条件表达式
3528
- const processConditionalExpr = (expr) => {
3529
- if (t__default.isIdentifier(expr)) {
3530
- const name = expr.name;
3531
- if (arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) {
3532
- return t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'));
3533
- }
3534
- if (ctx.scriptScope?.props.has(name)) {
3535
- const propsVarName = ctx.scriptScope.propsVarName || '__vmsProps';
3536
- return t__default.memberExpression(t__default.identifier(propsVarName), t__default.identifier(name));
3537
- }
3538
- if (varsToCollect.has(name)) {
3539
- return t__default.memberExpression(t__default.identifier('__vmsProxyRefs'), t__default.identifier(name));
3540
- }
3541
- return expr;
3542
- }
3543
- else if (t__default.isMemberExpression(expr)) {
3544
- return t__default.memberExpression(processConditionalExpr(expr.object), expr.property, expr.computed);
3545
- }
3546
- else if (t__default.isCallExpression(expr)) {
3547
- return t__default.callExpression(processConditionalExpr(expr.callee), expr.arguments.map((arg) => processConditionalExpr(arg)));
3548
- }
3549
- else if (t__default.isConditionalExpression(expr)) {
3550
- return t__default.conditionalExpression(processConditionalExpr(expr.test), processConditionalExpr(expr.consequent), processConditionalExpr(expr.alternate));
3551
- }
3552
- else if (t__default.isLogicalExpression(expr)) {
3553
- return t__default.logicalExpression(expr.operator, processConditionalExpr(expr.left), processConditionalExpr(expr.right));
3554
- }
3555
- else if (t__default.isBinaryExpression(expr)) {
3556
- return t__default.binaryExpression(expr.operator, processConditionalExpr(expr.left), processConditionalExpr(expr.right));
3557
- }
3558
- else if (t__default.isUnaryExpression(expr)) {
3559
- return t__default.unaryExpression(expr.operator, processConditionalExpr(expr.argument));
3560
- }
3561
- return expr;
3562
- };
3563
- const processedBody = processConditionalExpr(body);
3564
- statements.push(t__default.returnStatement(processedBody));
3565
- const functionBody = t__default.blockStatement(statements);
3566
- const dataArgsAst = vForInfoList && vForInfoList.length > 0
3567
- ? vForInfoList.map((info) => t__default.identifier(getVForIndexName(info) || 'index'))
3568
- : null;
3569
- callExpressionWithArgs.set(functionName, {
3570
- dataKey,
3571
- dataArgsAst,
3572
- returnValueBodyAst: functionBody,
3573
- isAsync,
3574
- });
3575
- return functionName;
3576
3493
  }
3577
- else if (t__default.isLogicalExpression(body)) {
3578
- // 处理逻辑表达式:(e) => flag && onClick(e)
3579
- // 复用条件表达式的处理逻辑,将逻辑表达式包装为类似条件表达式的处理
3580
- const vForInfoList = getVForInfoList(ctx, node);
3581
- const vForVars = getVForVariables(ctx, node);
3582
- const arrowFunctionArgumentNames = arrowFunctionArguments.length > 0
3583
- ? new Set(arrowFunctionArguments
3584
- .map((p) => (t__default.isIdentifier(p) ? p.name : ''))
3585
- .filter(Boolean))
3586
- : undefined;
3587
- // 收集逻辑表达式中使用的外部变量
3588
- const varsToCollect = new Set();
3589
- const collectVarsFromNode = (node) => {
3590
- if (t__default.isIdentifier(node)) {
3591
- const name = node.name;
3592
- if (name !== EVENT_PARAM_NAME &&
3593
- name !== '$event' &&
3594
- !GLOBAL_WHITELIST.has(name) &&
3595
- !(arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) &&
3596
- !vForVars.has(name)) {
3597
- varsToCollect.add(name);
3598
- }
3599
- }
3600
- else if (t__default.isMemberExpression(node)) {
3601
- collectVarsFromNode(node.object);
3602
- }
3603
- else if (t__default.isCallExpression(node)) {
3604
- collectVarsFromNode(node.callee);
3605
- node.arguments.forEach((arg) => collectVarsFromNode(arg));
3606
- }
3607
- else if (t__default.isLogicalExpression(node) || t__default.isBinaryExpression(node)) {
3608
- collectVarsFromNode(node.left);
3609
- collectVarsFromNode(node.right);
3610
- }
3611
- else if (t__default.isUnaryExpression(node)) {
3612
- collectVarsFromNode(node.argument);
3613
- }
3614
- };
3494
+ else {
3495
+ // LogicalExpression
3615
3496
  collectVarsFromNode(body.left);
3616
3497
  collectVarsFromNode(body.right);
3617
- // 将收集的变量添加到 returnValue
3618
- varsToCollect.forEach((varName) => {
3619
- if (!shouldSkipVariable(varName, ctx.scriptScope)) {
3620
- addProperty(returnValue, varName);
3621
- ctx.internalVars.add(varName);
3498
+ }
3499
+ return varsToCollect;
3500
+ }
3501
+ /**
3502
+ * 重写表达式中的变量引用
3503
+ * 将外部变量、props、箭头函数参数替换为正确的访问路径
3504
+ */
3505
+ function rewriteExpressionVars(expr, varsToCollect, arrowFunctionArgumentNames, ctx) {
3506
+ const processExpr = (node) => {
3507
+ if (t__default.isIdentifier(node)) {
3508
+ const name = node.name;
3509
+ if (arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) {
3510
+ return t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'));
3622
3511
  }
3623
- });
3624
- // 标记需要 __vmsProxyRefs
3625
- if (varsToCollect.size > 0) {
3626
- ctx.needsProxyRefs = true;
3627
- }
3628
- // 生成桥接函数
3629
- const functionName = counter.generateFunctionPropertyName();
3630
- const dataKey = vForInfoList && vForInfoList.length > 0
3631
- ? getFunctionIndexChar(counter.nodeDataKeyIndex++)
3632
- : '';
3633
- // 处理参数
3634
- const statements = [];
3635
- if (arrowFunctionArguments.length > 0) {
3636
- const param = arrowFunctionArguments[0];
3637
- if (t__default.isIdentifier(param) && param.name !== '$event' && param.name !== EVENT_PARAM_NAME) {
3638
- statements.push(t__default.variableDeclaration('const', [
3639
- t__default.variableDeclarator(param, t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'))),
3640
- ]));
3512
+ if (ctx.scriptScope?.props.has(name)) {
3513
+ const propsVarName = ctx.scriptScope.propsVarName || '__vmsProps';
3514
+ return t__default.memberExpression(t__default.identifier(propsVarName), t__default.identifier(name));
3515
+ }
3516
+ if (varsToCollect.has(name)) {
3517
+ return t__default.memberExpression(t__default.identifier('__vmsProxyRefs'), t__default.identifier(name));
3641
3518
  }
3519
+ return node;
3642
3520
  }
3643
- // 处理 v-for dataset 获取
3644
- if (vForInfoList && vForInfoList.length > 0) {
3645
- const indices = vForInfoList.map((info) => getVForIndexName(info) || 'index');
3646
- const indexVars = indices.map((idx) => t__default.identifier(idx));
3521
+ else if (t__default.isMemberExpression(node)) {
3522
+ return t__default.memberExpression(processExpr(node.object), node.property, node.computed);
3523
+ }
3524
+ else if (t__default.isCallExpression(node)) {
3525
+ return t__default.callExpression(processExpr(node.callee), node.arguments.map((arg) => processExpr(arg)));
3526
+ }
3527
+ else if (t__default.isConditionalExpression(node)) {
3528
+ return t__default.conditionalExpression(processExpr(node.test), processExpr(node.consequent), processExpr(node.alternate));
3529
+ }
3530
+ else if (t__default.isLogicalExpression(node)) {
3531
+ return t__default.logicalExpression(node.operator, processExpr(node.left), processExpr(node.right));
3532
+ }
3533
+ else if (t__default.isBinaryExpression(node)) {
3534
+ return t__default.binaryExpression(node.operator, processExpr(node.left), processExpr(node.right));
3535
+ }
3536
+ else if (t__default.isUnaryExpression(node)) {
3537
+ return t__default.unaryExpression(node.operator, processExpr(node.argument));
3538
+ }
3539
+ return node;
3540
+ };
3541
+ return processExpr(expr);
3542
+ }
3543
+ /**
3544
+ * 创建简短表达式(条件/逻辑表达式)的箭头函数处理器
3545
+ * 供 processArrowFunctionExpression 中条件表达式和逻辑表达式分支复用
3546
+ */
3547
+ function createShortExprHandler(body, arrowFunctionArguments, callExpressionWithArgs, vForInfoList, vForVars, ctx, counter, returnValue, isAsync) {
3548
+ const arrowFunctionArgumentNames = arrowFunctionArguments.length > 0
3549
+ ? new Set(arrowFunctionArguments.map((p) => (t__default.isIdentifier(p) ? p.name : '')).filter(Boolean))
3550
+ : undefined;
3551
+ // 收集外部变量
3552
+ const varsToCollect = collectExternalVarsFromExpression(body, arrowFunctionArgumentNames, vForVars);
3553
+ // 将收集的变量添加到 returnValue
3554
+ varsToCollect.forEach((varName) => {
3555
+ if (!shouldSkipVariable(varName, ctx.scriptScope)) {
3556
+ addProperty(returnValue, varName);
3557
+ ctx.internalVars.add(varName);
3558
+ }
3559
+ });
3560
+ // 标记需要 __vmsProxyRefs
3561
+ if (varsToCollect.size > 0) {
3562
+ ctx.needsProxyRefs = true;
3563
+ }
3564
+ // 生成桥接函数
3565
+ const functionName = counter.generateFunctionPropertyName();
3566
+ const dataKey = vForInfoList && vForInfoList.length > 0 ? getFunctionIndexChar(counter.nodeDataKeyIndex++) : '';
3567
+ // 处理参数
3568
+ const statements = [];
3569
+ if (arrowFunctionArguments.length > 0) {
3570
+ const param = arrowFunctionArguments[0];
3571
+ if (t__default.isIdentifier(param) && param.name !== '$event' && param.name !== EVENT_PARAM_NAME) {
3647
3572
  statements.push(t__default.variableDeclaration('const', [
3648
- t__default.variableDeclarator(t__default.objectPattern([
3649
- t__default.objectProperty(t__default.identifier(dataKey), t__default.arrayPattern(indexVars), false, false),
3650
- ]), t__default.memberExpression(t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('currentTarget')), t__default.identifier('dataset'))),
3573
+ t__default.variableDeclarator(param, t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'))),
3651
3574
  ]));
3652
3575
  }
3653
- // 构建处理后的逻辑表达式
3654
- const processLogicalExpr = (expr) => {
3655
- if (t__default.isIdentifier(expr)) {
3656
- const name = expr.name;
3657
- if (arrowFunctionArgumentNames && arrowFunctionArgumentNames.has(name)) {
3658
- return t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('detail'));
3659
- }
3660
- if (ctx.scriptScope?.props.has(name)) {
3661
- const propsVarName = ctx.scriptScope.propsVarName || '__vmsProps';
3662
- return t__default.memberExpression(t__default.identifier(propsVarName), t__default.identifier(name));
3663
- }
3664
- if (varsToCollect.has(name)) {
3665
- return t__default.memberExpression(t__default.identifier('__vmsProxyRefs'), t__default.identifier(name));
3666
- }
3667
- return expr;
3668
- }
3669
- else if (t__default.isMemberExpression(expr)) {
3670
- return t__default.memberExpression(processLogicalExpr(expr.object), expr.property, expr.computed);
3671
- }
3672
- else if (t__default.isCallExpression(expr)) {
3673
- return t__default.callExpression(processLogicalExpr(expr.callee), expr.arguments.map((arg) => processLogicalExpr(arg)));
3674
- }
3675
- else if (t__default.isLogicalExpression(expr)) {
3676
- return t__default.logicalExpression(expr.operator, processLogicalExpr(expr.left), processLogicalExpr(expr.right));
3677
- }
3678
- else if (t__default.isBinaryExpression(expr)) {
3679
- return t__default.binaryExpression(expr.operator, processLogicalExpr(expr.left), processLogicalExpr(expr.right));
3680
- }
3681
- else if (t__default.isUnaryExpression(expr)) {
3682
- return t__default.unaryExpression(expr.operator, processLogicalExpr(expr.argument));
3683
- }
3684
- return expr;
3685
- };
3686
- const processedBody = processLogicalExpr(body);
3687
- statements.push(t__default.returnStatement(processedBody));
3688
- const functionBody = t__default.blockStatement(statements);
3689
- const dataArgsAst = vForInfoList && vForInfoList.length > 0
3690
- ? vForInfoList.map((info) => t__default.identifier(getVForIndexName(info) || 'index'))
3691
- : null;
3692
- callExpressionWithArgs.set(functionName, {
3693
- dataKey,
3694
- dataArgsAst,
3695
- returnValueBodyAst: functionBody,
3696
- isAsync,
3697
- });
3698
- return functionName;
3699
3576
  }
3700
- return '';
3577
+ // 处理 v-for dataset 获取
3578
+ if (vForInfoList && vForInfoList.length > 0) {
3579
+ const indices = vForInfoList.map((info) => getVForIndexName(info) || 'index');
3580
+ const indexVars = indices.map((idx) => t__default.identifier(idx));
3581
+ statements.push(t__default.variableDeclaration('const', [
3582
+ t__default.variableDeclarator(t__default.objectPattern([
3583
+ t__default.objectProperty(t__default.identifier(dataKey), t__default.arrayPattern(indexVars), false, false),
3584
+ ]), t__default.memberExpression(t__default.memberExpression(t__default.identifier(EVENT_PARAM_NAME), t__default.identifier('currentTarget')), t__default.identifier('dataset'))),
3585
+ ]));
3586
+ }
3587
+ // 重写表达式中的变量引用
3588
+ const processedBody = rewriteExpressionVars(body, varsToCollect, arrowFunctionArgumentNames, ctx);
3589
+ statements.push(t__default.returnStatement(processedBody));
3590
+ const functionBody = t__default.blockStatement(statements);
3591
+ const dataArgsAst = vForInfoList && vForInfoList.length > 0
3592
+ ? vForInfoList.map((info) => t__default.identifier(getVForIndexName(info) || 'index'))
3593
+ : null;
3594
+ callExpressionWithArgs.set(functionName, {
3595
+ dataKey,
3596
+ dataArgsAst,
3597
+ returnValueBodyAst: functionBody,
3598
+ isAsync,
3599
+ });
3600
+ return functionName;
3701
3601
  }
3702
3602
  /**
3703
3603
  * 处理事件名转换
@@ -4599,7 +4499,7 @@ function createResult(key, content, priority) {
4599
4499
  * 从 v-for 指令中提取 forItem 和 forIndex
4600
4500
  * 公共逻辑,供 transformVForProp 共用
4601
4501
  */
4602
- function parseForVariables(prop) {
4502
+ function parseForVariables(prop, counter) {
4603
4503
  const directive = prop;
4604
4504
  if (!directive.forParseResult) {
4605
4505
  return undefined;
@@ -4608,15 +4508,9 @@ function parseForVariables(prop) {
4608
4508
  ? directive.forParseResult.value.content
4609
4509
  : 'item';
4610
4510
  const hasExplicitIndex = directive.forParseResult.key?.type === NodeTypes.SIMPLE_EXPRESSION;
4611
- const sourceContent = directive.forParseResult.source?.type === NodeTypes.SIMPLE_EXPRESSION
4612
- ? directive.forParseResult.source.content
4613
- : 'item';
4614
4511
  const forIndex = hasExplicitIndex
4615
4512
  ? directive.forParseResult.key.content
4616
- : `_${sourceContent
4617
- .split('.')
4618
- .pop()
4619
- ?.replace(/[^a-zA-Z0-9_]/g, '_') || 'item'}_index`;
4513
+ : counter.generateVForIndexName(forItem);
4620
4514
  return { forItem, forIndex };
4621
4515
  }
4622
4516
  /**
@@ -4633,7 +4527,7 @@ function transformVForProp(prop, context) {
4633
4527
  }
4634
4528
  // 获取数组表达式
4635
4529
  const { content: arrayName } = getTemplateNodeProp(context.node, { loc: directive.loc, exp: directive.forParseResult.source }, context.returnValue, context.counter, context.wxsExpressionStatements, context.ctx);
4636
- const forVars = parseForVariables(prop);
4530
+ const forVars = parseForVariables(prop, context.counter);
4637
4531
  if (!forVars)
4638
4532
  return undefined;
4639
4533
  // 写回 forParseResult 供后续使用
@@ -4803,12 +4697,16 @@ function parseTemplate(templateAST, filePath, isPage = false, scriptScope) {
4803
4697
  wxsFunctionCounter: 0,
4804
4698
  functionPropertyCounter: 0,
4805
4699
  nodeDataKeyIndex: 0,
4700
+ vForIndexCounter: 0,
4806
4701
  generateWxsFunctionName() {
4807
4702
  return `__wxs_${this.wxsFunctionCounter++}`;
4808
4703
  },
4809
4704
  generateFunctionPropertyName() {
4810
4705
  return `__fun_${this.functionPropertyCounter++}`;
4811
4706
  },
4707
+ generateVForIndexName(forItem) {
4708
+ return `_${forItem}_${this.vForIndexCounter++}_index`;
4709
+ },
4812
4710
  };
4813
4711
  const wxsExpressionStatements = [];
4814
4712
  const returnValue = t.objectExpression([]);
@@ -5220,6 +5118,14 @@ const NODE_ENV = process$1.env.NODE_ENV || 'production';
5220
5118
  let pagePaths = null;
5221
5119
  // 缓存文件路径到是否为页面组件的映射
5222
5120
  const pageComponentCache = new Map();
5121
+ /**
5122
+ * 清空所有缓存(在 app.json 变更时调用)
5123
+ */
5124
+ function clearAllCaches() {
5125
+ pagePaths = null;
5126
+ pageComponentCache.clear();
5127
+ pathCache.clear();
5128
+ }
5223
5129
  /**
5224
5130
  * 读取 app.json 并生成页面路径列表
5225
5131
  * 页面路径格式: pages/index/Index 或 subHome/pages/home/HomeIndex
@@ -5720,6 +5626,12 @@ async function dev() {
5720
5626
  }
5721
5627
  })
5722
5628
  .on('change', async (filePath) => {
5629
+ // 如果 app.json 变更,清空所有缓存并重新加载页面路径
5630
+ if (filePath.endsWith('app.json')) {
5631
+ console.log(bold(green('检测到 app.json 变更,清空缓存并重新加载页面路径...')));
5632
+ clearAllCaches();
5633
+ await loadPagePaths();
5634
+ }
5723
5635
  // 如果文件正在处理中,标记需要重新处理(排队一次),不直接丢弃
5724
5636
  if (processingFiles.has(filePath)) {
5725
5637
  pendingFiles.add(filePath);
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import dotenv from 'dotenv-flow';
2
2
 
3
3
  async function runVMS(options) {
4
4
  dotenv.config({ node_env: options.mode });
5
- const { dev, prod } = await import('./cli-BbBKrAPm.js');
5
+ const { dev, prod } = await import('./cli-R8YB9UUi.js');
6
6
  if (options.mode === 'production') {
7
7
  return prod(options);
8
8
  }
package/dist/macro.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ComponentContext, ShallowRef } from '@vue-mini/core'
1
+ import type { ComponentContext, ShallowRef } from '@unmagic/vue-mini'
2
2
 
3
3
  type TemplateRef<T = unknown> = Readonly<ShallowRef<T | null>>
4
4
 
@@ -12,7 +12,7 @@ declare global {
12
12
  function defineContext(): ComponentContext
13
13
 
14
14
  /**
15
- * 定义@vue-mini/core缺少的组件上下文
15
+ * 定义@unmagic/vue-mini缺少的组件上下文
16
16
  * @param key
17
17
  */
18
18
  function useTemplateRef<T = unknown, Keys extends string = string>(key: Keys): TemplateRef<T>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unmagic/vms",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "基于 @unmagic/vue-mini 的Vue3 单文件组件构建工具",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -38,15 +38,17 @@
38
38
  "@types/babel__traverse": "^7.28.0",
39
39
  "@types/fs-extra": "^11.0.4",
40
40
  "@types/node": "^25.5.0",
41
+ "@vue/reactivity": "3.5.32",
42
+ "execa": "^9.6.1",
41
43
  "fast-check": "^4.7.0",
44
+ "husky": "^9.1.7",
45
+ "lint-staged": "^16.4.0",
46
+ "miniprogram-api-typings": "4.0.8",
42
47
  "oxfmt": "^0.46.0",
43
48
  "oxlint": "^1.61.0",
44
49
  "oxlint-tsgolint": "^0.21.1",
45
- "typescript": "~6.0.3",
46
- "lint-staged": "^16.4.0",
47
50
  "tsx": "^4.21.0",
48
- "husky": "^9.1.7",
49
- "execa": "^9.6.1",
51
+ "typescript": "~6.0.3",
50
52
  "vitest": "^4.1.5"
51
53
  },
52
54
  "dependencies": {