@vureact/compiler-core 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/lib/{chunk-SQRJUILR.js → chunk-IVRFEV6H.js} +1411 -1249
- package/lib/{chunk-7FIMRVQS.esm.js → chunk-NF5BSPYE.esm.js} +1352 -1190
- package/lib/cli.d.cts +1 -2
- package/lib/cli.d.ts +1 -2
- package/lib/cli.esm.js +104 -47
- package/lib/cli.js +106 -49
- package/lib/compiler-core.d.cts +1117 -1179
- package/lib/compiler-core.d.ts +1117 -1179
- package/lib/compiler-core.esm.js +2 -2
- package/lib/compiler-core.js +3 -3
- package/package.json +99 -83
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vureact/compiler-core v1.
|
|
2
|
+
* @vureact/compiler-core v1.4.0
|
|
3
3
|
* (c) 2025-present Ruihong Zhong (Ryan John)
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
@@ -24,7 +24,7 @@ function executePlugins(map, result, ctx) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// src/core/codegen/component/jsx/syntax-processor/postprocess/build-ctx-provider.ts
|
|
27
|
-
import * as
|
|
27
|
+
import * as t11 from "@babel/types";
|
|
28
28
|
|
|
29
29
|
// src/consts/other.ts
|
|
30
30
|
var PACKAGE_NAME = {
|
|
@@ -32,6 +32,16 @@ var PACKAGE_NAME = {
|
|
|
32
32
|
runtime: "@vureact/runtime-core",
|
|
33
33
|
router: "@vureact/router"
|
|
34
34
|
};
|
|
35
|
+
var RUNTIME_PACKAGES = {
|
|
36
|
+
router: {
|
|
37
|
+
name: PACKAGE_NAME.router,
|
|
38
|
+
version: "^1.0.0"
|
|
39
|
+
},
|
|
40
|
+
runtime: {
|
|
41
|
+
name: PACKAGE_NAME.runtime,
|
|
42
|
+
version: "^1.0.0"
|
|
43
|
+
}
|
|
44
|
+
};
|
|
35
45
|
var STYLE_MODULE_NAME = "$style";
|
|
36
46
|
var MACRO_API_NAMES = {
|
|
37
47
|
props: "defineProps",
|
|
@@ -418,8 +428,8 @@ function getBabelParseOptions(lang = "js", context = "script", filename) {
|
|
|
418
428
|
function stringToExpr(input, lang, filename = "") {
|
|
419
429
|
return parseExpression(input, getBabelParseOptions(lang, "expression", filename));
|
|
420
430
|
}
|
|
421
|
-
function atComponentOrHookRoot(
|
|
422
|
-
const { parentPath, scope } =
|
|
431
|
+
function atComponentOrHookRoot(path9, rootScope, inScriptFile = false) {
|
|
432
|
+
const { parentPath, scope } = path9;
|
|
423
433
|
const parentBlock = scope.block;
|
|
424
434
|
if (!parentPath) return !inScriptFile;
|
|
425
435
|
if (parentBlock === rootScope) {
|
|
@@ -448,7 +458,7 @@ function createJsxElement(tag, props, children, selfClosing) {
|
|
|
448
458
|
}
|
|
449
459
|
|
|
450
460
|
// src/core/codegen/component/jsx/syntax-processor/process/build-condition-node.ts
|
|
451
|
-
import * as
|
|
461
|
+
import * as t10 from "@babel/types";
|
|
452
462
|
|
|
453
463
|
// src/core/codegen/component/jsx/utils/jsx-expression-utils.ts
|
|
454
464
|
import * as t2 from "@babel/types";
|
|
@@ -544,7 +554,82 @@ function buildJsxChildren(children, ctx) {
|
|
|
544
554
|
}
|
|
545
555
|
|
|
546
556
|
// src/core/codegen/component/jsx/syntax-processor/process/build-loop-node.ts
|
|
557
|
+
import * as t6 from "@babel/types";
|
|
558
|
+
|
|
559
|
+
// src/core/transform/sfc/template/shared/resolve-string-expression/index.ts
|
|
547
560
|
import * as t5 from "@babel/types";
|
|
561
|
+
|
|
562
|
+
// src/utils/camelCase.ts
|
|
563
|
+
var camelCase = (str) => {
|
|
564
|
+
if (str.includes("-")) {
|
|
565
|
+
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
566
|
+
}
|
|
567
|
+
return str;
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
// src/utils/capitalize.ts
|
|
571
|
+
var capitalize = (str) => {
|
|
572
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
// src/core/transform/sfc/template/shared/resolve-string-expression/special-expressions.ts
|
|
576
|
+
function resolveSpecialExpressions(input, ctx) {
|
|
577
|
+
input = resolveEmitsCalls(input, ctx);
|
|
578
|
+
input = resolveRefVariable(input, ctx);
|
|
579
|
+
return input;
|
|
580
|
+
}
|
|
581
|
+
function resolveEmitsCalls(input, ctx) {
|
|
582
|
+
const result = matchEmitCalls(input, ctx);
|
|
583
|
+
if (!result) return input;
|
|
584
|
+
const [, , eventName, args] = result;
|
|
585
|
+
const callee = eventName.split(/[:\-]/).map((part) => capitalize(camelCase(part))).join("");
|
|
586
|
+
const event = args ? `on${callee}?.(${args})` : `on${callee}?.()`;
|
|
587
|
+
return `${ctx.propField}?.${event}`;
|
|
588
|
+
}
|
|
589
|
+
function matchEmitCalls(input, ctx) {
|
|
590
|
+
const { reactiveBindings } = ctx.templateData;
|
|
591
|
+
const macroBinding = Object.values(reactiveBindings).find((b) => b.source === "defineEmits");
|
|
592
|
+
if (!macroBinding) return null;
|
|
593
|
+
const escapedName = macroBinding.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
594
|
+
const regex = new RegExp(
|
|
595
|
+
`${escapedName}\\s*\\(\\s*(['"\`])([^\\1]*?)\\1\\s*(?:,\\s*(.*?))?\\s*\\)$`,
|
|
596
|
+
// 可选的第二个参数
|
|
597
|
+
"s"
|
|
598
|
+
// s 标志让 . 匹配换行符
|
|
599
|
+
);
|
|
600
|
+
return input.trim().match(regex);
|
|
601
|
+
}
|
|
602
|
+
function resolveRefVariable(input, ctx) {
|
|
603
|
+
const { reactiveBindings } = ctx.templateData;
|
|
604
|
+
const addValueProperty = (input2, varName) => {
|
|
605
|
+
const escapedVarName = varName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
606
|
+
const regex = new RegExp(
|
|
607
|
+
`(?<![a-zA-Z0-9_\\.])${escapedVarName}(?![a-zA-Z0-9_])(?!\\.value)`,
|
|
608
|
+
"g"
|
|
609
|
+
);
|
|
610
|
+
return input2.replace(regex, `${varName}.value`);
|
|
611
|
+
};
|
|
612
|
+
for (const name in reactiveBindings) {
|
|
613
|
+
const binding = reactiveBindings[name];
|
|
614
|
+
if (binding?.reactiveType !== "ref") continue;
|
|
615
|
+
input = addValueProperty(input, name);
|
|
616
|
+
}
|
|
617
|
+
return input;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/core/transform/sfc/template/shared/resolve-string-expression/index.ts
|
|
621
|
+
function resolveStringExpr(input, ctx, toStrLiteral = false) {
|
|
622
|
+
if (toStrLiteral) return t5.stringLiteral(input);
|
|
623
|
+
const { filename, scriptData } = ctx;
|
|
624
|
+
const newContent = resolveSpecialExpressions(input, ctx);
|
|
625
|
+
try {
|
|
626
|
+
return stringToExpr(newContent, scriptData.lang, filename);
|
|
627
|
+
} catch {
|
|
628
|
+
return t5.identifier(newContent);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// src/core/codegen/component/jsx/syntax-processor/process/build-loop-node.ts
|
|
548
633
|
function buildLoopNode(nodeIR, ctx) {
|
|
549
634
|
const loop = nodeIR.meta.loop;
|
|
550
635
|
loop.isHandled = true;
|
|
@@ -554,15 +639,15 @@ function buildLoopNode(nodeIR, ctx) {
|
|
|
554
639
|
function buildArrayLoopNode(nodeIR, ctx) {
|
|
555
640
|
const loop = nodeIR.meta.loop;
|
|
556
641
|
const { source, value, index, key } = loop.value;
|
|
557
|
-
const
|
|
558
|
-
const params = [
|
|
642
|
+
const sourceExpression = resolveStringExpr(source, ctx);
|
|
643
|
+
const params = [t6.identifier(value)];
|
|
559
644
|
if (index ?? key) {
|
|
560
|
-
params.push(
|
|
645
|
+
params.push(t6.identifier(index ?? key));
|
|
561
646
|
}
|
|
562
|
-
const mapCallExpression =
|
|
563
|
-
|
|
647
|
+
const mapCallExpression = t6.callExpression(
|
|
648
|
+
t6.memberExpression(sourceExpression, t6.identifier("map")),
|
|
564
649
|
[
|
|
565
|
-
|
|
650
|
+
t6.arrowFunctionExpression(
|
|
566
651
|
params,
|
|
567
652
|
convertJsxChildToExpression(buildElementNode(nodeIR, ctx))
|
|
568
653
|
)
|
|
@@ -573,21 +658,21 @@ function buildArrayLoopNode(nodeIR, ctx) {
|
|
|
573
658
|
function buildObjectLoopNode(nodeIR, ctx) {
|
|
574
659
|
const loop = nodeIR.meta.loop;
|
|
575
660
|
const { source, value, key, index } = loop.value;
|
|
576
|
-
const
|
|
577
|
-
const objectEntriesCallExpression =
|
|
578
|
-
|
|
579
|
-
[
|
|
661
|
+
const sourceExpression = resolveStringExpr(source, ctx);
|
|
662
|
+
const objectEntriesCallExpression = t6.callExpression(
|
|
663
|
+
t6.memberExpression(t6.identifier("Object"), t6.identifier("entries")),
|
|
664
|
+
[sourceExpression]
|
|
580
665
|
);
|
|
581
666
|
const params = [
|
|
582
|
-
|
|
667
|
+
t6.arrayPattern([t6.identifier(key || "key"), t6.identifier(value)])
|
|
583
668
|
];
|
|
584
669
|
if (index) {
|
|
585
|
-
params.push(
|
|
670
|
+
params.push(t6.identifier(index));
|
|
586
671
|
}
|
|
587
|
-
const mapCallExpression =
|
|
588
|
-
|
|
672
|
+
const mapCallExpression = t6.callExpression(
|
|
673
|
+
t6.memberExpression(objectEntriesCallExpression, t6.identifier("map")),
|
|
589
674
|
[
|
|
590
|
-
|
|
675
|
+
t6.arrowFunctionExpression(
|
|
591
676
|
params,
|
|
592
677
|
convertJsxChildToExpression(buildElementNode(nodeIR, ctx))
|
|
593
678
|
)
|
|
@@ -597,25 +682,25 @@ function buildObjectLoopNode(nodeIR, ctx) {
|
|
|
597
682
|
}
|
|
598
683
|
|
|
599
684
|
// src/core/codegen/component/jsx/syntax-processor/process/build-memo-node.ts
|
|
600
|
-
import * as
|
|
685
|
+
import * as t7 from "@babel/types";
|
|
601
686
|
function buildMemoNode(nodeIR, ctx) {
|
|
602
687
|
const memo = nodeIR.meta.memo;
|
|
603
688
|
memo.isHandled = true;
|
|
604
689
|
const depsExpression = memo.babelExp.ast;
|
|
605
690
|
const bodyExpression = convertJsxChildToExpression(buildElementNode(nodeIR, ctx));
|
|
606
|
-
const useMemoCallExpression =
|
|
607
|
-
|
|
691
|
+
const useMemoCallExpression = t7.callExpression(t7.identifier("useMemo"), [
|
|
692
|
+
t7.arrowFunctionExpression([], bodyExpression),
|
|
608
693
|
depsExpression
|
|
609
694
|
]);
|
|
610
695
|
return buildJsxExpressionNode(useMemoCallExpression);
|
|
611
696
|
}
|
|
612
697
|
|
|
613
698
|
// src/core/codegen/component/jsx/syntax-processor/process/build-props.ts
|
|
614
|
-
import * as
|
|
699
|
+
import * as t9 from "@babel/types";
|
|
615
700
|
|
|
616
701
|
// src/core/codegen/component/jsx/syntax-processor/process/build-slot-prop.ts
|
|
617
702
|
import { parseExpression as parseExpression2 } from "@babel/parser";
|
|
618
|
-
import * as
|
|
703
|
+
import * as t8 from "@babel/types";
|
|
619
704
|
|
|
620
705
|
// src/shared/logger.ts
|
|
621
706
|
import kleur2 from "kleur";
|
|
@@ -624,6 +709,9 @@ import kleur2 from "kleur";
|
|
|
624
709
|
import { minimatch } from "minimatch";
|
|
625
710
|
import { fileURLToPath } from "url";
|
|
626
711
|
import path from "path";
|
|
712
|
+
function getDirname(metaUrl) {
|
|
713
|
+
return path.dirname(fileURLToPath(metaUrl));
|
|
714
|
+
}
|
|
627
715
|
var PathFilter = class {
|
|
628
716
|
patterns = [];
|
|
629
717
|
cwd;
|
|
@@ -864,7 +952,7 @@ var logger = new Logger();
|
|
|
864
952
|
|
|
865
953
|
// src/core/codegen/component/jsx/syntax-processor/process/build-slot-prop.ts
|
|
866
954
|
function buildSlotProp(nodeIR, ctx) {
|
|
867
|
-
const slotKey =
|
|
955
|
+
const slotKey = t8.jsxIdentifier(nodeIR.name);
|
|
868
956
|
const childrenNodeIR = !nodeIR.isScoped ? nodeIR.content : nodeIR.callback?.exp;
|
|
869
957
|
if (!childrenNodeIR?.length) {
|
|
870
958
|
return null;
|
|
@@ -873,7 +961,7 @@ function buildSlotProp(nodeIR, ctx) {
|
|
|
873
961
|
if (!jsxChild) {
|
|
874
962
|
return null;
|
|
875
963
|
}
|
|
876
|
-
const slotValue = nodeIR.isScoped ?
|
|
964
|
+
const slotValue = nodeIR.isScoped ? t8.arrowFunctionExpression(
|
|
877
965
|
buildSlotCallbackParams(nodeIR, ctx),
|
|
878
966
|
convertJsxChildToExpression(jsxChild)
|
|
879
967
|
) : jsxChild;
|
|
@@ -882,15 +970,15 @@ function buildSlotProp(nodeIR, ctx) {
|
|
|
882
970
|
}
|
|
883
971
|
if (!nodeIR.isStatic) {
|
|
884
972
|
const dynamicSlotKey = parseExpression2(nodeIR.name);
|
|
885
|
-
const spreadObject =
|
|
886
|
-
|
|
973
|
+
const spreadObject = t8.objectExpression([
|
|
974
|
+
t8.objectProperty(dynamicSlotKey, convertSlotValueToExpression(slotValue), true)
|
|
887
975
|
]);
|
|
888
|
-
return
|
|
976
|
+
return t8.jsxSpreadAttribute(spreadObject);
|
|
889
977
|
}
|
|
890
|
-
return
|
|
978
|
+
return t8.jsxAttribute(slotKey, buildJsxExpressionNode(convertSlotValueToExpression(slotValue)));
|
|
891
979
|
}
|
|
892
980
|
function convertSlotValueToExpression(nodeIR) {
|
|
893
|
-
if (
|
|
981
|
+
if (t8.isArrowFunctionExpression(nodeIR)) {
|
|
894
982
|
return nodeIR;
|
|
895
983
|
}
|
|
896
984
|
return convertJsxChildToExpression(nodeIR);
|
|
@@ -903,7 +991,7 @@ function buildSlotCallbackParams(nodeIR, ctx) {
|
|
|
903
991
|
const source = rawArg.startsWith("(") ? `${rawArg} => null` : `(${rawArg}) => null`;
|
|
904
992
|
try {
|
|
905
993
|
const expression = parseExpression2(source);
|
|
906
|
-
if (!
|
|
994
|
+
if (!t8.isArrowFunctionExpression(expression)) {
|
|
907
995
|
return [];
|
|
908
996
|
}
|
|
909
997
|
return expression.params;
|
|
@@ -946,13 +1034,13 @@ function buildStandardProp(nodeIR) {
|
|
|
946
1034
|
}
|
|
947
1035
|
} = nodeIR;
|
|
948
1036
|
if (!isStatic || isKeyLessVBind) {
|
|
949
|
-
return
|
|
1037
|
+
return t9.jsxSpreadAttribute(valueAST);
|
|
950
1038
|
}
|
|
951
1039
|
let value;
|
|
952
1040
|
if (content !== "true") {
|
|
953
|
-
value = isStringLiteral13 ?
|
|
1041
|
+
value = isStringLiteral13 ? t9.stringLiteral(content) : buildJsxExpressionNode(valueAST);
|
|
954
1042
|
}
|
|
955
|
-
return
|
|
1043
|
+
return t9.jsxAttribute(keyAST, value);
|
|
956
1044
|
}
|
|
957
1045
|
|
|
958
1046
|
// src/core/codegen/component/jsx/syntax-processor/process/build-element-node.ts
|
|
@@ -998,8 +1086,8 @@ function buildConditionNode(nodeIR, ctx) {
|
|
|
998
1086
|
}
|
|
999
1087
|
const testExpression = condition.babelExp.ast;
|
|
1000
1088
|
const trueBranchExpression = convertJsxChildToExpression(buildCurrentNode());
|
|
1001
|
-
const falseBranchExpression = nextNodeIR ? convertJsxChildToExpression(buildElementNode(nextNodeIR, ctx)) :
|
|
1002
|
-
const conditionalExpression2 =
|
|
1089
|
+
const falseBranchExpression = nextNodeIR ? convertJsxChildToExpression(buildElementNode(nextNodeIR, ctx)) : t10.nullLiteral();
|
|
1090
|
+
const conditionalExpression2 = t10.conditionalExpression(
|
|
1003
1091
|
testExpression,
|
|
1004
1092
|
// 条件测试部分
|
|
1005
1093
|
trueBranchExpression,
|
|
@@ -1019,19 +1107,19 @@ function buildCtxProviderNode(nodeIR, ctx, children) {
|
|
|
1019
1107
|
childNodes = [buildCtxProviderNode(nextProvide, ctx, children)];
|
|
1020
1108
|
}
|
|
1021
1109
|
const parseProviderExpr = (raw) => {
|
|
1022
|
-
if (!raw) return
|
|
1110
|
+
if (!raw) return t11.stringLiteral("");
|
|
1023
1111
|
try {
|
|
1024
1112
|
return stringToExpr(raw, ctx.scriptData.lang, ctx.filename);
|
|
1025
1113
|
} catch {
|
|
1026
|
-
return
|
|
1114
|
+
return t11.stringLiteral(raw);
|
|
1027
1115
|
}
|
|
1028
1116
|
};
|
|
1029
|
-
const nameProp =
|
|
1030
|
-
|
|
1117
|
+
const nameProp = t11.jsxAttribute(
|
|
1118
|
+
t11.jsxIdentifier("name"),
|
|
1031
1119
|
buildJsxExpressionNode(parseProviderExpr(name))
|
|
1032
1120
|
);
|
|
1033
|
-
const valueProp =
|
|
1034
|
-
|
|
1121
|
+
const valueProp = t11.jsxAttribute(
|
|
1122
|
+
t11.jsxIdentifier("value"),
|
|
1035
1123
|
buildJsxExpressionNode(parseProviderExpr(value))
|
|
1036
1124
|
);
|
|
1037
1125
|
void ctx;
|
|
@@ -1085,29 +1173,29 @@ function buildJSX(nodeIR, ctx) {
|
|
|
1085
1173
|
}
|
|
1086
1174
|
|
|
1087
1175
|
// src/core/codegen/component/script/syntax-processor/index.ts
|
|
1088
|
-
import * as
|
|
1176
|
+
import * as t14 from "@babel/types";
|
|
1089
1177
|
|
|
1090
1178
|
// src/core/codegen/component/script/syntax-processor/postprocess/build-program-node.ts
|
|
1091
|
-
import * as
|
|
1179
|
+
import * as t12 from "@babel/types";
|
|
1092
1180
|
function buildProgramNode(nodeIR, ctx, state) {
|
|
1093
1181
|
const statements = [...state.preambleStatements];
|
|
1094
1182
|
if (!state.component) {
|
|
1095
|
-
state.result =
|
|
1183
|
+
state.result = t12.program(statements, void 0, "module");
|
|
1096
1184
|
return;
|
|
1097
1185
|
}
|
|
1098
1186
|
statements.push(state.component);
|
|
1099
1187
|
if (state.expose) {
|
|
1100
1188
|
const [declarator] = state.component.declarations;
|
|
1101
1189
|
const { name } = declarator.id;
|
|
1102
|
-
statements.push(
|
|
1190
|
+
statements.push(t12.exportDefaultDeclaration(t12.identifier(name)));
|
|
1103
1191
|
}
|
|
1104
|
-
state.result =
|
|
1192
|
+
state.result = t12.program(statements, void 0, "module");
|
|
1105
1193
|
void nodeIR;
|
|
1106
1194
|
void ctx;
|
|
1107
1195
|
}
|
|
1108
1196
|
|
|
1109
1197
|
// src/core/codegen/component/script/syntax-processor/process/build-component-function.ts
|
|
1110
|
-
import * as
|
|
1198
|
+
import * as t13 from "@babel/types";
|
|
1111
1199
|
|
|
1112
1200
|
// src/consts/react-api-map.ts
|
|
1113
1201
|
var REACT_API_MAP = {
|
|
@@ -1121,19 +1209,6 @@ var REACT_API_MAP = {
|
|
|
1121
1209
|
useImperativeHandle: "useImperativeHandle"
|
|
1122
1210
|
};
|
|
1123
1211
|
|
|
1124
|
-
// src/utils/camelCase.ts
|
|
1125
|
-
var camelCase = (str) => {
|
|
1126
|
-
if (str.includes("-")) {
|
|
1127
|
-
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
1128
|
-
}
|
|
1129
|
-
return str;
|
|
1130
|
-
};
|
|
1131
|
-
|
|
1132
|
-
// src/utils/capitalize.ts
|
|
1133
|
-
var capitalize = (str) => {
|
|
1134
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1135
|
-
};
|
|
1136
|
-
|
|
1137
1212
|
// src/utils/hash.ts
|
|
1138
1213
|
import XXH from "xxhashjs";
|
|
1139
1214
|
function genHashByXXH(str) {
|
|
@@ -1157,7 +1232,7 @@ function buildComponent(scriptIR, ctx, state) {
|
|
|
1157
1232
|
} = ctx;
|
|
1158
1233
|
const hasProps = getHasProps(propsTSIface.propsTypes) || getHasProps(propsTSIface.emitTypes) || getHasProps(propsTSIface.slotTypes);
|
|
1159
1234
|
const shouldMemo = scriptIR !== null || hasProps;
|
|
1160
|
-
const jsxStatement =
|
|
1235
|
+
const jsxStatement = t13.returnStatement(state.jsx || t13.nullLiteral());
|
|
1161
1236
|
const component = !shouldMemo ? resolvePureUIComponent(jsxStatement, ctx) : resolveMemoComponent(scriptIR.statement.local, jsxStatement, ctx);
|
|
1162
1237
|
state.component = component;
|
|
1163
1238
|
}
|
|
@@ -1165,24 +1240,24 @@ function getHasProps(list) {
|
|
|
1165
1240
|
return list.length > 0;
|
|
1166
1241
|
}
|
|
1167
1242
|
function resolvePureUIComponent(jsxStmt, ctx) {
|
|
1168
|
-
return
|
|
1169
|
-
|
|
1243
|
+
return t13.variableDeclaration("const", [
|
|
1244
|
+
t13.variableDeclarator(
|
|
1170
1245
|
resolveComponentName(ctx),
|
|
1171
|
-
|
|
1246
|
+
t13.arrowFunctionExpression([], t13.blockStatement([jsxStmt]))
|
|
1172
1247
|
)
|
|
1173
1248
|
]);
|
|
1174
1249
|
}
|
|
1175
1250
|
function resolveMemoComponent(local, jsxStmt, ctx) {
|
|
1176
1251
|
const name = resolveComponentName(ctx);
|
|
1177
1252
|
const param = resolvePropsParam(ctx);
|
|
1178
|
-
const body =
|
|
1253
|
+
const body = t13.blockStatement(resolveLocalStatements(local, jsxStmt));
|
|
1179
1254
|
const component = resolveComponent(param, body, ctx);
|
|
1180
1255
|
let compFn = component;
|
|
1181
1256
|
if (ctx.scriptData.forwardRef.enabled) {
|
|
1182
1257
|
compFn = resolveForwardRef(body, ctx);
|
|
1183
1258
|
}
|
|
1184
|
-
const memoCall =
|
|
1185
|
-
return
|
|
1259
|
+
const memoCall = t13.callExpression(t13.identifier(REACT_API_MAP.memo), [compFn]);
|
|
1260
|
+
return t13.variableDeclaration("const", [t13.variableDeclarator(name, memoCall)]);
|
|
1186
1261
|
}
|
|
1187
1262
|
function resolveComponentName(ctx) {
|
|
1188
1263
|
const { filename, compName } = ctx;
|
|
@@ -1196,7 +1271,7 @@ function resolveComponentName(ctx) {
|
|
|
1196
1271
|
file: filename
|
|
1197
1272
|
});
|
|
1198
1273
|
}
|
|
1199
|
-
return
|
|
1274
|
+
return t13.identifier(name);
|
|
1200
1275
|
}
|
|
1201
1276
|
function resolveLocalStatements(local, jsx) {
|
|
1202
1277
|
const stmts = [jsx];
|
|
@@ -1216,7 +1291,7 @@ function resolveComponent(param, body, ctx) {
|
|
|
1216
1291
|
if (forwardRef.enabled) {
|
|
1217
1292
|
return resolveForwardRef(body, ctx);
|
|
1218
1293
|
}
|
|
1219
|
-
const baseComponent =
|
|
1294
|
+
const baseComponent = t13.arrowFunctionExpression(!param ? [] : [param], body);
|
|
1220
1295
|
return baseComponent;
|
|
1221
1296
|
}
|
|
1222
1297
|
function resolveForwardRef(body, ctx) {
|
|
@@ -1224,18 +1299,18 @@ function resolveForwardRef(body, ctx) {
|
|
|
1224
1299
|
propField,
|
|
1225
1300
|
scriptData: { forwardRef, lang }
|
|
1226
1301
|
} = ctx;
|
|
1227
|
-
const params = [
|
|
1302
|
+
const params = [t13.identifier(forwardRef.refField)];
|
|
1228
1303
|
const propsId = resolvePropsParam(ctx);
|
|
1229
|
-
const callExpr =
|
|
1230
|
-
|
|
1304
|
+
const callExpr = t13.callExpression(t13.identifier(REACT_API_MAP.forwardRef), [
|
|
1305
|
+
t13.arrowFunctionExpression(params, body)
|
|
1231
1306
|
]);
|
|
1232
1307
|
if (lang.startsWith("ts")) {
|
|
1233
|
-
const types = [
|
|
1308
|
+
const types = [t13.tsAnyKeyword()];
|
|
1234
1309
|
if (propsId) {
|
|
1235
1310
|
const propsType = propsId?.typeAnnotation?.typeAnnotation;
|
|
1236
|
-
types.push(propsType ||
|
|
1311
|
+
types.push(propsType || t13.tsAnyKeyword());
|
|
1237
1312
|
}
|
|
1238
|
-
callExpr.typeParameters =
|
|
1313
|
+
callExpr.typeParameters = t13.tsTypeParameterInstantiation(types);
|
|
1239
1314
|
}
|
|
1240
1315
|
if (propsId) {
|
|
1241
1316
|
propsId.typeAnnotation = null;
|
|
@@ -1246,7 +1321,7 @@ function resolveForwardRef(body, ctx) {
|
|
|
1246
1321
|
function resolvePropsParam(ctx) {
|
|
1247
1322
|
const { propField, scriptData } = ctx;
|
|
1248
1323
|
const { propsTSIface } = scriptData;
|
|
1249
|
-
const propsIdentifier =
|
|
1324
|
+
const propsIdentifier = t13.identifier(propField);
|
|
1250
1325
|
if (scriptData.lang.startsWith("js")) {
|
|
1251
1326
|
if (propsTSIface.hasPropsInJsEnv) {
|
|
1252
1327
|
return propsIdentifier;
|
|
@@ -1256,8 +1331,8 @@ function resolvePropsParam(ctx) {
|
|
|
1256
1331
|
if (!propsTSIface.name) {
|
|
1257
1332
|
return;
|
|
1258
1333
|
}
|
|
1259
|
-
const typeIdentifier =
|
|
1260
|
-
propsIdentifier.typeAnnotation =
|
|
1334
|
+
const typeIdentifier = t13.identifier(propsTSIface.name);
|
|
1335
|
+
propsIdentifier.typeAnnotation = t13.tsTypeAnnotation(t13.tsTypeReference(typeIdentifier));
|
|
1261
1336
|
return propsIdentifier;
|
|
1262
1337
|
}
|
|
1263
1338
|
|
|
@@ -1282,7 +1357,7 @@ function buildScriptSyntax(nodeIR, ctx, jsx, expose = true) {
|
|
|
1282
1357
|
process: [buildProgramPreamble, buildComponent],
|
|
1283
1358
|
postprocess: [buildProgramNode]
|
|
1284
1359
|
});
|
|
1285
|
-
return state.result ||
|
|
1360
|
+
return state.result || t14.program([], void 0, "module");
|
|
1286
1361
|
}
|
|
1287
1362
|
function scriptSyntaxProcessor(nodeIR, ctx, state, options) {
|
|
1288
1363
|
const run = (p) => {
|
|
@@ -1377,7 +1452,7 @@ import {
|
|
|
1377
1452
|
// src/core/parse/sfc/process/resolve-script.ts
|
|
1378
1453
|
import { generate as generate2 } from "@babel/generator";
|
|
1379
1454
|
import { parse as babelParse2 } from "@babel/parser";
|
|
1380
|
-
import * as
|
|
1455
|
+
import * as t15 from "@babel/types";
|
|
1381
1456
|
function resolveScript(descriptor, ctx, pResult) {
|
|
1382
1457
|
const scriptBlock = descriptor.scriptSetup || descriptor.script;
|
|
1383
1458
|
if (!scriptBlock) return null;
|
|
@@ -1419,41 +1494,41 @@ function extractSetupBodyToTopLevel(content, options) {
|
|
|
1419
1494
|
const otherTopLevel = [];
|
|
1420
1495
|
let setupStatements = [];
|
|
1421
1496
|
for (const node of ast.program.body) {
|
|
1422
|
-
if (
|
|
1497
|
+
if (t15.isImportDeclaration(node)) {
|
|
1423
1498
|
importNodes.push(node);
|
|
1424
1499
|
continue;
|
|
1425
1500
|
}
|
|
1426
|
-
if (
|
|
1501
|
+
if (t15.isExportDefaultDeclaration(node)) {
|
|
1427
1502
|
const decl = node.declaration;
|
|
1428
|
-
if (decl &&
|
|
1503
|
+
if (decl && t15.isObjectExpression(decl)) {
|
|
1429
1504
|
const nameProp = decl.properties.find((p) => {
|
|
1430
|
-
if (
|
|
1505
|
+
if (t15.isObjectProperty(p)) {
|
|
1431
1506
|
const key = p.key;
|
|
1432
|
-
return
|
|
1507
|
+
return t15.isIdentifier(key) && key.name === "name" || t15.isStringLiteral(key) && key.value === "name";
|
|
1433
1508
|
}
|
|
1434
1509
|
return false;
|
|
1435
1510
|
});
|
|
1436
|
-
if (nameProp &&
|
|
1437
|
-
if (
|
|
1511
|
+
if (nameProp && t15.isObjectProperty(nameProp)) {
|
|
1512
|
+
if (t15.isStringLiteral(nameProp.value)) {
|
|
1438
1513
|
name = nameProp.value.value;
|
|
1439
1514
|
}
|
|
1440
1515
|
}
|
|
1441
1516
|
const setupProp = decl.properties.find((p) => {
|
|
1442
|
-
if (
|
|
1517
|
+
if (t15.isObjectMethod(p)) {
|
|
1443
1518
|
return p.key && p.key.name === "setup";
|
|
1444
1519
|
}
|
|
1445
|
-
if (
|
|
1520
|
+
if (t15.isObjectProperty(p)) {
|
|
1446
1521
|
const key = p.key;
|
|
1447
|
-
return
|
|
1522
|
+
return t15.isIdentifier(key) && key.name === "setup" || t15.isStringLiteral(key) && key.value === "setup";
|
|
1448
1523
|
}
|
|
1449
1524
|
return false;
|
|
1450
1525
|
});
|
|
1451
1526
|
if (setupProp) {
|
|
1452
|
-
const value =
|
|
1453
|
-
if (value && (
|
|
1454
|
-
const fnBody =
|
|
1527
|
+
const value = t15.isObjectMethod(setupProp) ? setupProp : t15.isObjectProperty(setupProp) ? setupProp.value : null;
|
|
1528
|
+
if (value && (t15.isFunction(value) || t15.isObjectMethod(value))) {
|
|
1529
|
+
const fnBody = t15.isBlockStatement(value.body) ? value.body.body : [];
|
|
1455
1530
|
for (const stmt of fnBody) {
|
|
1456
|
-
if (
|
|
1531
|
+
if (t15.isReturnStatement(stmt)) continue;
|
|
1457
1532
|
setupStatements.push(stmt);
|
|
1458
1533
|
}
|
|
1459
1534
|
}
|
|
@@ -1481,7 +1556,7 @@ function extractCompName(source) {
|
|
|
1481
1556
|
|
|
1482
1557
|
// src/core/parse/sfc/process/resolve-script-meta.ts
|
|
1483
1558
|
import { traverse } from "@babel/core";
|
|
1484
|
-
import * as
|
|
1559
|
+
import * as t16 from "@babel/types";
|
|
1485
1560
|
|
|
1486
1561
|
// src/consts/html-tag-types.ts
|
|
1487
1562
|
var HTML_TAG_TYPES = {
|
|
@@ -1585,12 +1660,12 @@ function resolveScriptMeta(result, ctx) {
|
|
|
1585
1660
|
const scriptAST = result.script?.ast;
|
|
1586
1661
|
if (!scriptAST) return;
|
|
1587
1662
|
traverse(scriptAST, {
|
|
1588
|
-
VariableDeclarator(
|
|
1589
|
-
const { node } =
|
|
1590
|
-
if (!atComponentOrHookRoot(
|
|
1663
|
+
VariableDeclarator(path9) {
|
|
1664
|
+
const { node } = path9;
|
|
1665
|
+
if (!atComponentOrHookRoot(path9, scriptAST.program) || !t16.isIdentifier(node.id)) {
|
|
1591
1666
|
return;
|
|
1592
1667
|
}
|
|
1593
|
-
if (node.init &&
|
|
1668
|
+
if (node.init && t16.isCallExpression(node.init) && t16.isIdentifier(node.init.callee)) {
|
|
1594
1669
|
collectReactiveBindings(node, ctx);
|
|
1595
1670
|
collectRefBindings(node, ctx);
|
|
1596
1671
|
}
|
|
@@ -1868,7 +1943,7 @@ import { parse as babelParse3 } from "@babel/parser";
|
|
|
1868
1943
|
import { traverse as traverse3 } from "@babel/core";
|
|
1869
1944
|
|
|
1870
1945
|
// src/core/transform/sfc/script/syntax-processor/postprocess/insert-css-import.ts
|
|
1871
|
-
import * as
|
|
1946
|
+
import * as t17 from "@babel/types";
|
|
1872
1947
|
function insertCSSImport(ctx) {
|
|
1873
1948
|
const { inputType } = ctx;
|
|
1874
1949
|
if (inputType !== "sfc") return;
|
|
@@ -1877,15 +1952,15 @@ function insertCSSImport(ctx) {
|
|
|
1877
1952
|
const scriptIR = getScriptIR(ctx);
|
|
1878
1953
|
const filename = normalizePath(filePath).split("/").pop();
|
|
1879
1954
|
const importPath = `./${filename}`;
|
|
1880
|
-
const importDecl =
|
|
1881
|
-
!moduleName ? [] : [
|
|
1882
|
-
|
|
1955
|
+
const importDecl = t17.importDeclaration(
|
|
1956
|
+
!moduleName ? [] : [t17.importDefaultSpecifier(t17.identifier(moduleName))],
|
|
1957
|
+
t17.stringLiteral(importPath)
|
|
1883
1958
|
);
|
|
1884
1959
|
scriptIR.imports.push(importDecl);
|
|
1885
1960
|
}
|
|
1886
1961
|
|
|
1887
1962
|
// src/core/transform/sfc/script/syntax-processor/postprocess/insert-required-imports.ts
|
|
1888
|
-
import * as
|
|
1963
|
+
import * as t18 from "@babel/types";
|
|
1889
1964
|
|
|
1890
1965
|
// src/core/transform/shared.ts
|
|
1891
1966
|
function recordImport(ctx, pkg, name, onDemand = true) {
|
|
@@ -1921,36 +1996,36 @@ function insertRequiredImports(ctx) {
|
|
|
1921
1996
|
const processedModules = /* @__PURE__ */ new Set();
|
|
1922
1997
|
let hasProcessedImports = false;
|
|
1923
1998
|
recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.memo);
|
|
1924
|
-
function resolveRequiredImport(
|
|
1925
|
-
const { node } =
|
|
1999
|
+
function resolveRequiredImport(path9) {
|
|
2000
|
+
const { node } = path9;
|
|
1926
2001
|
const moduleName = node.source.value.toLowerCase();
|
|
1927
2002
|
const isVueLike = isVueEcosystemPackage(moduleName);
|
|
1928
2003
|
mergeImports(node, ctx);
|
|
1929
|
-
if (processedModules.has(moduleName) && !
|
|
1930
|
-
|
|
2004
|
+
if (processedModules.has(moduleName) && !path9.removed) {
|
|
2005
|
+
path9.remove();
|
|
1931
2006
|
return;
|
|
1932
2007
|
}
|
|
1933
2008
|
processedModules.add(moduleName);
|
|
1934
2009
|
if (!hasProcessedImports) {
|
|
1935
2010
|
const required = createRequiredImports(ctx);
|
|
1936
2011
|
if (isVueLike) {
|
|
1937
|
-
|
|
2012
|
+
path9.replaceWithMultiple(required);
|
|
1938
2013
|
} else if (moduleName === PACKAGE_NAME.react) {
|
|
1939
|
-
|
|
2014
|
+
path9.insertAfter(required);
|
|
1940
2015
|
} else {
|
|
1941
|
-
|
|
2016
|
+
path9.insertBefore(required);
|
|
1942
2017
|
}
|
|
1943
2018
|
hasProcessedImports = true;
|
|
1944
2019
|
}
|
|
1945
|
-
if (isVueLike && !
|
|
1946
|
-
|
|
2020
|
+
if (isVueLike && !path9.removed) {
|
|
2021
|
+
path9.remove();
|
|
1947
2022
|
return;
|
|
1948
2023
|
}
|
|
1949
2024
|
replaceVueSuffix(ctx, node.source);
|
|
1950
2025
|
}
|
|
1951
|
-
function resolveStyleFileExt(
|
|
2026
|
+
function resolveStyleFileExt(path9) {
|
|
1952
2027
|
if (!ctx.preprocessStyles) return;
|
|
1953
|
-
const { node } =
|
|
2028
|
+
const { node } = path9;
|
|
1954
2029
|
if (!node || !node.source || !node.source.value) return;
|
|
1955
2030
|
const importSource = node.source.value;
|
|
1956
2031
|
if (typeof importSource !== "string") return;
|
|
@@ -1962,16 +2037,16 @@ function insertRequiredImports(ctx) {
|
|
|
1962
2037
|
return {
|
|
1963
2038
|
// 增加 Program.exit 兜底注入 required imports(处理无 ImportDeclaration 的 SFC)
|
|
1964
2039
|
Program: {
|
|
1965
|
-
exit(
|
|
2040
|
+
exit(path9) {
|
|
1966
2041
|
if (hasProcessedImports) return;
|
|
1967
2042
|
const required = createRequiredImports(ctx);
|
|
1968
|
-
|
|
2043
|
+
path9.unshiftContainer("body", required);
|
|
1969
2044
|
hasProcessedImports = true;
|
|
1970
2045
|
}
|
|
1971
2046
|
},
|
|
1972
|
-
ImportDeclaration(
|
|
1973
|
-
resolveRequiredImport(
|
|
1974
|
-
resolveStyleFileExt(
|
|
2047
|
+
ImportDeclaration(path9) {
|
|
2048
|
+
resolveRequiredImport(path9);
|
|
2049
|
+
resolveStyleFileExt(path9);
|
|
1975
2050
|
}
|
|
1976
2051
|
};
|
|
1977
2052
|
}
|
|
@@ -1995,17 +2070,17 @@ function mergeImports(currentNode, ctx) {
|
|
|
1995
2070
|
}
|
|
1996
2071
|
const currentImports = /* @__PURE__ */ new Set();
|
|
1997
2072
|
for (const spec of currentNode.specifiers) {
|
|
1998
|
-
if (
|
|
2073
|
+
if (t18.isImportSpecifier(spec) && t18.isIdentifier(spec.imported)) {
|
|
1999
2074
|
currentImports.add(spec.imported.name);
|
|
2000
2075
|
}
|
|
2001
|
-
if (
|
|
2076
|
+
if (t18.isImportDefaultSpecifier(spec) && t18.isIdentifier(spec.local)) {
|
|
2002
2077
|
currentImports.add(spec.local.name);
|
|
2003
2078
|
}
|
|
2004
2079
|
}
|
|
2005
2080
|
for (const item of ctxImportItems) {
|
|
2006
2081
|
if (currentImports.has(item.name)) return;
|
|
2007
|
-
const local =
|
|
2008
|
-
const newNode = !item.onDemand ?
|
|
2082
|
+
const local = t18.identifier(item.name);
|
|
2083
|
+
const newNode = !item.onDemand ? t18.importDefaultSpecifier(local) : t18.importSpecifier(local, local);
|
|
2009
2084
|
currentNode.specifiers.push(newNode);
|
|
2010
2085
|
}
|
|
2011
2086
|
ctx.imports.delete(moduleName);
|
|
@@ -2016,18 +2091,18 @@ function createRequiredImports(ctx) {
|
|
|
2016
2091
|
ctx.imports.forEach((items, moduleName) => {
|
|
2017
2092
|
const specifier = [];
|
|
2018
2093
|
for (const item of items) {
|
|
2019
|
-
const local =
|
|
2094
|
+
const local = t18.identifier(item.name);
|
|
2020
2095
|
if (!item.onDemand) {
|
|
2021
|
-
specifier.push(
|
|
2096
|
+
specifier.push(t18.importDefaultSpecifier(local));
|
|
2022
2097
|
} else {
|
|
2023
|
-
specifier.push(
|
|
2098
|
+
specifier.push(t18.importSpecifier(local, local));
|
|
2024
2099
|
}
|
|
2025
2100
|
}
|
|
2026
2101
|
importMap[moduleName] = specifier;
|
|
2027
2102
|
});
|
|
2028
2103
|
for (const name in importMap) {
|
|
2029
2104
|
const specifiers = importMap[name];
|
|
2030
|
-
const importDecl =
|
|
2105
|
+
const importDecl = t18.importDeclaration(specifiers, t18.stringLiteral(name));
|
|
2031
2106
|
if (name === PACKAGE_NAME.react) {
|
|
2032
2107
|
result.unshift(importDecl);
|
|
2033
2108
|
} else {
|
|
@@ -2038,33 +2113,33 @@ function createRequiredImports(ctx) {
|
|
|
2038
2113
|
}
|
|
2039
2114
|
|
|
2040
2115
|
// src/core/transform/sfc/script/syntax-processor/postprocess/resolve-static-hoisting.ts
|
|
2041
|
-
import * as
|
|
2116
|
+
import * as t20 from "@babel/types";
|
|
2042
2117
|
|
|
2043
2118
|
// src/core/transform/sfc/script/shared/babel-utils.ts
|
|
2044
|
-
import * as
|
|
2045
|
-
function findRootVariablePath(
|
|
2046
|
-
const rootId = findRootIdentifier(
|
|
2119
|
+
import * as t19 from "@babel/types";
|
|
2120
|
+
function findRootVariablePath(path9) {
|
|
2121
|
+
const rootId = findRootIdentifier(path9.node);
|
|
2047
2122
|
if (!rootId?.name) return null;
|
|
2048
|
-
const binding =
|
|
2123
|
+
const binding = path9.scope.getBinding(rootId.name);
|
|
2049
2124
|
if (!binding) return null;
|
|
2050
2125
|
const rootPath = getVariableDeclaratorPath(binding.path);
|
|
2051
2126
|
return rootPath;
|
|
2052
2127
|
}
|
|
2053
2128
|
function findRootIdentifier(node) {
|
|
2054
2129
|
let current = node.object;
|
|
2055
|
-
while (
|
|
2130
|
+
while (t19.isMemberExpression(current) || t19.isOptionalMemberExpression(current)) {
|
|
2056
2131
|
current = current.object;
|
|
2057
2132
|
}
|
|
2058
|
-
return
|
|
2133
|
+
return t19.isIdentifier(current) ? current : null;
|
|
2059
2134
|
}
|
|
2060
|
-
function getVariableDeclaratorPath(
|
|
2061
|
-
if (
|
|
2062
|
-
return
|
|
2135
|
+
function getVariableDeclaratorPath(path9) {
|
|
2136
|
+
if (path9.isVariableDeclarator()) {
|
|
2137
|
+
return path9;
|
|
2063
2138
|
}
|
|
2064
|
-
return
|
|
2139
|
+
return path9.findParent((p) => p.isVariableDeclarator());
|
|
2065
2140
|
}
|
|
2066
|
-
function isVariableDeclTopLevel(
|
|
2067
|
-
const variableDeclaratorPath =
|
|
2141
|
+
function isVariableDeclTopLevel(path9) {
|
|
2142
|
+
const variableDeclaratorPath = path9;
|
|
2068
2143
|
const variableDeclarationPath = variableDeclaratorPath.parentPath;
|
|
2069
2144
|
if (!variableDeclarationPath) {
|
|
2070
2145
|
return false;
|
|
@@ -2078,75 +2153,75 @@ function isVariableDeclTopLevel(path7) {
|
|
|
2078
2153
|
}
|
|
2079
2154
|
return false;
|
|
2080
2155
|
}
|
|
2081
|
-
function isRealVariableAccess(
|
|
2082
|
-
return isIdentifierAccess(
|
|
2156
|
+
function isRealVariableAccess(path9) {
|
|
2157
|
+
return isIdentifierAccess(path9) && !isPropertyName(path9);
|
|
2083
2158
|
}
|
|
2084
|
-
function isIdentifierAccess(
|
|
2085
|
-
if (isIdentifierDeclaration(
|
|
2159
|
+
function isIdentifierAccess(path9) {
|
|
2160
|
+
if (isIdentifierDeclaration(path9)) {
|
|
2086
2161
|
return false;
|
|
2087
2162
|
}
|
|
2088
|
-
const binding =
|
|
2163
|
+
const binding = path9.scope.getBinding(path9.node.name);
|
|
2089
2164
|
if (!binding) {
|
|
2090
2165
|
return true;
|
|
2091
2166
|
}
|
|
2092
|
-
return binding.identifier !==
|
|
2167
|
+
return binding.identifier !== path9.node;
|
|
2093
2168
|
}
|
|
2094
|
-
function isIdentifierDeclaration(
|
|
2095
|
-
const parent =
|
|
2169
|
+
function isIdentifierDeclaration(path9) {
|
|
2170
|
+
const parent = path9.parentPath;
|
|
2096
2171
|
if (!parent) return false;
|
|
2097
|
-
if (parent.isVariableDeclarator() && parent.node.id ===
|
|
2172
|
+
if (parent.isVariableDeclarator() && parent.node.id === path9.node) {
|
|
2098
2173
|
return true;
|
|
2099
2174
|
}
|
|
2100
|
-
if (parent.isFunctionDeclaration() && parent.node.id ===
|
|
2175
|
+
if (parent.isFunctionDeclaration() && parent.node.id === path9.node) {
|
|
2101
2176
|
return true;
|
|
2102
2177
|
}
|
|
2103
|
-
if (parent.isFunctionExpression() && parent.node.id ===
|
|
2178
|
+
if (parent.isFunctionExpression() && parent.node.id === path9.node) {
|
|
2104
2179
|
return true;
|
|
2105
2180
|
}
|
|
2106
|
-
if (parent.isClassDeclaration() && parent.node.id ===
|
|
2181
|
+
if (parent.isClassDeclaration() && parent.node.id === path9.node) {
|
|
2107
2182
|
return true;
|
|
2108
2183
|
}
|
|
2109
|
-
if (parent.isImportSpecifier() && parent.node.local ===
|
|
2184
|
+
if (parent.isImportSpecifier() && parent.node.local === path9.node) {
|
|
2110
2185
|
return true;
|
|
2111
2186
|
}
|
|
2112
|
-
if (parent.isImportDefaultSpecifier() && parent.node.local ===
|
|
2187
|
+
if (parent.isImportDefaultSpecifier() && parent.node.local === path9.node) {
|
|
2113
2188
|
return true;
|
|
2114
2189
|
}
|
|
2115
|
-
if (parent.isImportNamespaceSpecifier() && parent.node.local ===
|
|
2190
|
+
if (parent.isImportNamespaceSpecifier() && parent.node.local === path9.node) {
|
|
2116
2191
|
return true;
|
|
2117
2192
|
}
|
|
2118
|
-
if (parent.isFunction() && parent.node.params.includes(
|
|
2193
|
+
if (parent.isFunction() && parent.node.params.includes(path9.node)) {
|
|
2119
2194
|
return true;
|
|
2120
2195
|
}
|
|
2121
|
-
if (parent.isCatchClause() && parent.node.param ===
|
|
2196
|
+
if (parent.isCatchClause() && parent.node.param === path9.node) {
|
|
2122
2197
|
return true;
|
|
2123
2198
|
}
|
|
2124
2199
|
return false;
|
|
2125
2200
|
}
|
|
2126
|
-
function isPropertyName(
|
|
2127
|
-
const parent =
|
|
2201
|
+
function isPropertyName(path9) {
|
|
2202
|
+
const parent = path9.parentPath;
|
|
2128
2203
|
if (!parent) return false;
|
|
2129
|
-
if (parent.isObjectProperty() && parent.node.key ===
|
|
2204
|
+
if (parent.isObjectProperty() && parent.node.key === path9.node) {
|
|
2130
2205
|
return true;
|
|
2131
2206
|
}
|
|
2132
|
-
if (parent.isClassProperty() && parent.node.key ===
|
|
2207
|
+
if (parent.isClassProperty() && parent.node.key === path9.node) {
|
|
2133
2208
|
return true;
|
|
2134
2209
|
}
|
|
2135
|
-
if (parent.isMemberExpression() && parent.node.property ===
|
|
2210
|
+
if (parent.isMemberExpression() && parent.node.property === path9.node) {
|
|
2136
2211
|
return true;
|
|
2137
2212
|
}
|
|
2138
2213
|
return false;
|
|
2139
2214
|
}
|
|
2140
2215
|
function replaceCallName(callExp, identifierName) {
|
|
2141
2216
|
const { callee } = callExp;
|
|
2142
|
-
if (!
|
|
2217
|
+
if (!t19.isIdentifier(callee)) return;
|
|
2143
2218
|
callee.name = identifierName;
|
|
2144
2219
|
if (callee.loc) {
|
|
2145
2220
|
callee.loc.identifierName = identifierName;
|
|
2146
2221
|
}
|
|
2147
2222
|
}
|
|
2148
2223
|
function replaceIdName(id, newName) {
|
|
2149
|
-
if (!
|
|
2224
|
+
if (!t19.isIdentifier(id)) return;
|
|
2150
2225
|
id.name = newName;
|
|
2151
2226
|
if (id.loc) {
|
|
2152
2227
|
id.loc.identifierName = newName;
|
|
@@ -2156,65 +2231,65 @@ function stringValueToTSType(ctx, input, tsTypeAnnotation7) {
|
|
|
2156
2231
|
const { filename, scriptData } = ctx;
|
|
2157
2232
|
const exp = stringToExpr(input, scriptData.lang, filename);
|
|
2158
2233
|
const ts = expressionToTSType(exp);
|
|
2159
|
-
return tsTypeAnnotation7 ?
|
|
2234
|
+
return tsTypeAnnotation7 ? t19.tsTypeAnnotation(ts) : ts;
|
|
2160
2235
|
}
|
|
2161
2236
|
function expressionToTSType(exp) {
|
|
2162
|
-
if (
|
|
2163
|
-
if (
|
|
2164
|
-
if (
|
|
2165
|
-
if (
|
|
2166
|
-
if (
|
|
2237
|
+
if (t19.isStringLiteral(exp)) return t19.tsStringKeyword();
|
|
2238
|
+
if (t19.isNumericLiteral(exp)) return t19.tsNumberKeyword();
|
|
2239
|
+
if (t19.isBooleanLiteral(exp)) return t19.tsBooleanKeyword();
|
|
2240
|
+
if (t19.isArrayExpression(exp)) return t19.tsArrayType(t19.tsAnyKeyword());
|
|
2241
|
+
if (t19.isObjectExpression(exp)) {
|
|
2167
2242
|
const members = [];
|
|
2168
2243
|
for (const p of exp.properties) {
|
|
2169
|
-
if (!
|
|
2244
|
+
if (!t19.isObjectProperty(p)) continue;
|
|
2170
2245
|
let key;
|
|
2171
|
-
if (
|
|
2172
|
-
else if (
|
|
2246
|
+
if (t19.isIdentifier(p.key)) key = p.key.name;
|
|
2247
|
+
else if (t19.isStringLiteral(p.key)) key = p.key.value;
|
|
2173
2248
|
if (!key) continue;
|
|
2174
|
-
if (
|
|
2249
|
+
if (t19.isExpression(p.value)) {
|
|
2175
2250
|
members.push(
|
|
2176
|
-
|
|
2251
|
+
t19.tsPropertySignature(t19.identifier(key), t19.tsTypeAnnotation(expressionToTSType(p.value)))
|
|
2177
2252
|
);
|
|
2178
2253
|
} else {
|
|
2179
2254
|
members.push(
|
|
2180
|
-
|
|
2255
|
+
t19.tsPropertySignature(t19.identifier(key), t19.tsTypeAnnotation(t19.tsAnyKeyword()))
|
|
2181
2256
|
);
|
|
2182
2257
|
}
|
|
2183
2258
|
}
|
|
2184
|
-
return
|
|
2259
|
+
return t19.tsTypeLiteral(members);
|
|
2185
2260
|
}
|
|
2186
|
-
if (
|
|
2261
|
+
if (t19.isArrowFunctionExpression(exp) || t19.isFunctionExpression(exp)) {
|
|
2187
2262
|
const params = exp.params.map((p, i) => {
|
|
2188
|
-
const id =
|
|
2189
|
-
id.typeAnnotation =
|
|
2263
|
+
const id = t19.isIdentifier(p) ? t19.identifier(p.name) : t19.identifier(`arg${i}`);
|
|
2264
|
+
id.typeAnnotation = t19.tsTypeAnnotation(t19.tsAnyKeyword());
|
|
2190
2265
|
return id;
|
|
2191
2266
|
});
|
|
2192
|
-
let returnType =
|
|
2193
|
-
if (
|
|
2267
|
+
let returnType = t19.tsAnyKeyword();
|
|
2268
|
+
if (t19.isBlockStatement(exp.body)) {
|
|
2194
2269
|
for (const stmt of exp.body.body) {
|
|
2195
|
-
if (
|
|
2196
|
-
if (
|
|
2270
|
+
if (t19.isReturnStatement(stmt) && stmt.argument) {
|
|
2271
|
+
if (t19.isExpression(stmt.argument)) {
|
|
2197
2272
|
returnType = expressionToTSType(stmt.argument);
|
|
2198
2273
|
break;
|
|
2199
2274
|
}
|
|
2200
2275
|
}
|
|
2201
2276
|
}
|
|
2202
|
-
} else if (
|
|
2277
|
+
} else if (t19.isExpression(exp.body)) {
|
|
2203
2278
|
returnType = expressionToTSType(exp.body);
|
|
2204
2279
|
}
|
|
2205
|
-
return
|
|
2280
|
+
return t19.tsFunctionType(null, params, t19.tsTypeAnnotation(returnType));
|
|
2206
2281
|
}
|
|
2207
|
-
return
|
|
2282
|
+
return t19.tsAnyKeyword();
|
|
2208
2283
|
}
|
|
2209
2284
|
function isCalleeNamed(node, name) {
|
|
2210
|
-
if (!
|
|
2285
|
+
if (!t19.isIdentifier(node.callee)) {
|
|
2211
2286
|
return false;
|
|
2212
2287
|
}
|
|
2213
2288
|
return node.callee.name === name;
|
|
2214
2289
|
}
|
|
2215
2290
|
function isSimpleLiteral(node) {
|
|
2216
2291
|
if (!node) return false;
|
|
2217
|
-
if (
|
|
2292
|
+
if (t19.isStringLiteral(node) || t19.isNumericLiteral(node) || t19.isBooleanLiteral(node) || t19.isNullLiteral(node) || t19.isRegExpLiteral(node) || t19.isBigIntLiteral(node) || t19.isDecimalLiteral(node)) {
|
|
2218
2293
|
return true;
|
|
2219
2294
|
}
|
|
2220
2295
|
return false;
|
|
@@ -2243,26 +2318,26 @@ function resolveStaticHoisting(ctx) {
|
|
|
2243
2318
|
return {};
|
|
2244
2319
|
}
|
|
2245
2320
|
return {
|
|
2246
|
-
"ImportDeclaration|ExportDeclaration"(
|
|
2247
|
-
if (
|
|
2248
|
-
scriptIR.imports.push(
|
|
2249
|
-
} else if (
|
|
2250
|
-
scriptIR.exports.push(
|
|
2321
|
+
"ImportDeclaration|ExportDeclaration"(path9) {
|
|
2322
|
+
if (t20.isImportDeclaration(path9.node)) {
|
|
2323
|
+
scriptIR.imports.push(path9.node);
|
|
2324
|
+
} else if (t20.isExportDeclaration(path9.node)) {
|
|
2325
|
+
scriptIR.exports.push(path9.node);
|
|
2251
2326
|
}
|
|
2252
|
-
|
|
2327
|
+
path9.remove();
|
|
2253
2328
|
},
|
|
2254
|
-
"TSInterfaceDeclaration|TSTypeAliasDeclaration|TSEnumDeclaration|TSModuleDeclaration|TSModuleDeclaration"(
|
|
2255
|
-
if (
|
|
2256
|
-
scriptIR.tsTypes.push(
|
|
2257
|
-
|
|
2329
|
+
"TSInterfaceDeclaration|TSTypeAliasDeclaration|TSEnumDeclaration|TSModuleDeclaration|TSModuleDeclaration"(path9) {
|
|
2330
|
+
if (t20.isProgram(path9.parent)) {
|
|
2331
|
+
scriptIR.tsTypes.push(path9.node);
|
|
2332
|
+
path9.remove();
|
|
2258
2333
|
}
|
|
2259
2334
|
},
|
|
2260
|
-
VariableDeclarator(
|
|
2261
|
-
const { node } =
|
|
2262
|
-
if (!isVariableDeclTopLevel(
|
|
2335
|
+
VariableDeclarator(path9) {
|
|
2336
|
+
const { node } = path9;
|
|
2337
|
+
if (!isVariableDeclTopLevel(path9) || !isSimpleLiteral(node.init) || getScriptNodeMeta(node)) {
|
|
2263
2338
|
return;
|
|
2264
2339
|
}
|
|
2265
|
-
const declarationPath =
|
|
2340
|
+
const declarationPath = path9.findParent((p) => p.isVariableDeclaration());
|
|
2266
2341
|
if (!declarationPath) return;
|
|
2267
2342
|
scriptIR.statement.global.push(declarationPath.node);
|
|
2268
2343
|
declarationPath.remove();
|
|
@@ -2276,27 +2351,27 @@ function collectLocalStatements(ctx, ast) {
|
|
|
2276
2351
|
}
|
|
2277
2352
|
|
|
2278
2353
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-define-async-component.ts
|
|
2279
|
-
import * as
|
|
2354
|
+
import * as t21 from "@babel/types";
|
|
2280
2355
|
function resolveDefineAsyncComponent(ctx) {
|
|
2281
2356
|
return {
|
|
2282
|
-
CallExpression(
|
|
2283
|
-
const { node } =
|
|
2357
|
+
CallExpression(path9) {
|
|
2358
|
+
const { node } = path9;
|
|
2284
2359
|
if (!isCalleeNamed(node, VUE_API_MAP.defineAsyncComponent)) {
|
|
2285
2360
|
return;
|
|
2286
2361
|
}
|
|
2287
2362
|
const [arg] = node.arguments;
|
|
2288
2363
|
checkIsUnsupported(ctx, arg);
|
|
2289
|
-
pushToGlobalScope(
|
|
2364
|
+
pushToGlobalScope(path9, ctx);
|
|
2290
2365
|
recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.lazy);
|
|
2291
2366
|
}
|
|
2292
2367
|
};
|
|
2293
2368
|
}
|
|
2294
2369
|
function checkIsUnsupported(ctx, arg) {
|
|
2295
|
-
if (
|
|
2370
|
+
if (t21.isFunction(arg)) {
|
|
2296
2371
|
checkIsDynamicImport(ctx, arg);
|
|
2297
|
-
} else if (
|
|
2372
|
+
} else if (t21.isObjectExpression(arg)) {
|
|
2298
2373
|
const { value } = arg.properties.find(
|
|
2299
|
-
(p) =>
|
|
2374
|
+
(p) => t21.isObjectProperty(p) && t21.isIdentifier(p.key) && p.key.name === "loader"
|
|
2300
2375
|
);
|
|
2301
2376
|
checkIsDynamicImport(ctx, value);
|
|
2302
2377
|
if (arg.properties.length > 1) {
|
|
@@ -2307,7 +2382,7 @@ function checkIsUnsupported(ctx, arg) {
|
|
|
2307
2382
|
function checkIsDynamicImport(ctx, node) {
|
|
2308
2383
|
const { scriptData, filename } = ctx;
|
|
2309
2384
|
const warnIsNotImport = (target) => {
|
|
2310
|
-
if (!target || !
|
|
2385
|
+
if (!target || !t21.isImport(target)) {
|
|
2311
2386
|
logger.error(
|
|
2312
2387
|
`Only ES module dynamic imports are supported. You must use and return import('...').`,
|
|
2313
2388
|
{
|
|
@@ -2318,20 +2393,20 @@ function checkIsDynamicImport(ctx, node) {
|
|
|
2318
2393
|
);
|
|
2319
2394
|
}
|
|
2320
2395
|
};
|
|
2321
|
-
if (
|
|
2396
|
+
if (t21.isFunction(node)) {
|
|
2322
2397
|
checkIsDynamicImport(ctx, node.body);
|
|
2323
2398
|
return;
|
|
2324
2399
|
}
|
|
2325
|
-
if (
|
|
2400
|
+
if (t21.isBlockStatement(node)) {
|
|
2326
2401
|
const [returnSmt] = node.body;
|
|
2327
|
-
if (
|
|
2402
|
+
if (t21.isReturnStatement(returnSmt)) {
|
|
2328
2403
|
warnIsNotImport(returnSmt.argument);
|
|
2329
2404
|
}
|
|
2330
2405
|
return;
|
|
2331
2406
|
}
|
|
2332
|
-
if (
|
|
2407
|
+
if (t21.isCallExpression(node)) {
|
|
2333
2408
|
warnIsNotImport(node.callee);
|
|
2334
|
-
if (
|
|
2409
|
+
if (t21.isStringLiteral(node.arguments[0])) {
|
|
2335
2410
|
replaceVueSuffix(ctx, node.arguments[0]);
|
|
2336
2411
|
}
|
|
2337
2412
|
return;
|
|
@@ -2349,15 +2424,15 @@ function warnMultipleOptionsUsed(ctx, node) {
|
|
|
2349
2424
|
}
|
|
2350
2425
|
);
|
|
2351
2426
|
}
|
|
2352
|
-
function pushToGlobalScope(
|
|
2353
|
-
const { node } =
|
|
2427
|
+
function pushToGlobalScope(path9, ctx) {
|
|
2428
|
+
const { node } = path9;
|
|
2354
2429
|
const callee = node.callee;
|
|
2355
2430
|
callee.name = REACT_API_MAP.lazy;
|
|
2356
2431
|
callee.loc.identifierName = REACT_API_MAP.lazy;
|
|
2357
2432
|
if (node.typeParameters) {
|
|
2358
2433
|
node.typeParameters = void 0;
|
|
2359
2434
|
}
|
|
2360
|
-
let declarationPath =
|
|
2435
|
+
let declarationPath = path9.parentPath;
|
|
2361
2436
|
while (declarationPath) {
|
|
2362
2437
|
if (declarationPath.isVariableDeclaration()) {
|
|
2363
2438
|
break;
|
|
@@ -2368,78 +2443,78 @@ function pushToGlobalScope(path7, ctx) {
|
|
|
2368
2443
|
if (declarationPath?.isVariableDeclaration()) {
|
|
2369
2444
|
fullNode = declarationPath.node;
|
|
2370
2445
|
declarationPath.remove();
|
|
2371
|
-
} else if (
|
|
2372
|
-
fullNode =
|
|
2373
|
-
|
|
2446
|
+
} else if (path9.parentPath.isVariableDeclarator()) {
|
|
2447
|
+
fullNode = path9.parent;
|
|
2448
|
+
path9.parentPath.remove();
|
|
2374
2449
|
} else {
|
|
2375
|
-
fullNode =
|
|
2376
|
-
|
|
2450
|
+
fullNode = path9.node;
|
|
2451
|
+
path9.remove();
|
|
2377
2452
|
}
|
|
2378
2453
|
const scriptIR = getScriptIR(ctx);
|
|
2379
2454
|
scriptIR.statement.global.push(fullNode);
|
|
2380
2455
|
}
|
|
2381
2456
|
|
|
2382
2457
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-define-expose.ts
|
|
2383
|
-
import * as
|
|
2458
|
+
import * as t23 from "@babel/types";
|
|
2384
2459
|
|
|
2385
2460
|
// src/core/transform/sfc/script/shared/hook-creator.ts
|
|
2386
|
-
import * as
|
|
2461
|
+
import * as t22 from "@babel/types";
|
|
2387
2462
|
function createUseCallback(body, deps) {
|
|
2388
|
-
return
|
|
2463
|
+
return t22.callExpression(t22.identifier(REACT_API_MAP.useCallback), [
|
|
2389
2464
|
body,
|
|
2390
|
-
deps ??
|
|
2465
|
+
deps ?? t22.arrayExpression([])
|
|
2391
2466
|
]);
|
|
2392
2467
|
}
|
|
2393
2468
|
function createUseMemo(body, deps) {
|
|
2394
|
-
return
|
|
2395
|
-
|
|
2396
|
-
deps ??
|
|
2469
|
+
return t22.callExpression(t22.identifier(REACT_API_MAP.useMemo), [
|
|
2470
|
+
t22.arrowFunctionExpression([], body),
|
|
2471
|
+
deps ?? t22.arrayExpression([])
|
|
2397
2472
|
]);
|
|
2398
2473
|
}
|
|
2399
2474
|
function createUseImperativeHandle(refId, init) {
|
|
2400
|
-
return
|
|
2475
|
+
return t22.callExpression(t22.identifier(REACT_API_MAP.useImperativeHandle), [refId, init]);
|
|
2401
2476
|
}
|
|
2402
2477
|
|
|
2403
2478
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-define-expose.ts
|
|
2404
2479
|
function resolveDefineExpose(ctx) {
|
|
2405
2480
|
if (ctx.inputType !== "sfc") return {};
|
|
2406
2481
|
return {
|
|
2407
|
-
CallExpression(
|
|
2408
|
-
const { node } =
|
|
2482
|
+
CallExpression(path9) {
|
|
2483
|
+
const { node } = path9;
|
|
2409
2484
|
const { filename, scriptData } = ctx;
|
|
2410
2485
|
if (!isCalleeNamed(node, MACRO_API_NAMES.expose)) {
|
|
2411
2486
|
return;
|
|
2412
2487
|
}
|
|
2413
2488
|
const [expose] = node.arguments;
|
|
2414
2489
|
if (!expose) {
|
|
2415
|
-
|
|
2490
|
+
path9.remove();
|
|
2416
2491
|
return;
|
|
2417
2492
|
}
|
|
2418
2493
|
const adapter = ADAPTER_RULES.react[MACRO_API_NAMES.expose];
|
|
2419
2494
|
recordImport(ctx, adapter.package, REACT_API_MAP.forwardRef);
|
|
2420
2495
|
recordImport(ctx, adapter.package, adapter.target);
|
|
2421
|
-
if (!
|
|
2496
|
+
if (!t23.isObjectExpression(expose) && !t23.isFunction(expose)) {
|
|
2422
2497
|
logger.warn("Non-deterministic object literal may cause unknown risks.", {
|
|
2423
2498
|
file: filename,
|
|
2424
2499
|
loc: expose.loc,
|
|
2425
2500
|
source: scriptData.source
|
|
2426
2501
|
});
|
|
2427
2502
|
}
|
|
2428
|
-
const init = !
|
|
2503
|
+
const init = !t23.isFunction(expose) ? t23.arrowFunctionExpression([], expose) : expose;
|
|
2429
2504
|
const { forwardRef } = scriptData;
|
|
2430
|
-
const newNode = createUseImperativeHandle(
|
|
2505
|
+
const newNode = createUseImperativeHandle(t23.identifier(forwardRef.refField), init);
|
|
2431
2506
|
forwardRef.enabled = true;
|
|
2432
|
-
|
|
2507
|
+
path9.replaceWith(newNode);
|
|
2433
2508
|
}
|
|
2434
2509
|
};
|
|
2435
2510
|
}
|
|
2436
2511
|
|
|
2437
2512
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-define-options.ts
|
|
2438
|
-
import * as
|
|
2513
|
+
import * as t24 from "@babel/types";
|
|
2439
2514
|
function resolveDefineOptions(ctx) {
|
|
2440
2515
|
return {
|
|
2441
|
-
CallExpression(
|
|
2442
|
-
const { node } =
|
|
2516
|
+
CallExpression(path9) {
|
|
2517
|
+
const { node } = path9;
|
|
2443
2518
|
if (!isCalleeNamed(node, MACRO_API_NAMES.options)) {
|
|
2444
2519
|
return;
|
|
2445
2520
|
}
|
|
@@ -2451,10 +2526,10 @@ function resolveDefineOptions(ctx) {
|
|
|
2451
2526
|
file: filename,
|
|
2452
2527
|
loc: node?.loc
|
|
2453
2528
|
});
|
|
2454
|
-
|
|
2529
|
+
path9.remove();
|
|
2455
2530
|
return;
|
|
2456
2531
|
}
|
|
2457
|
-
if (!
|
|
2532
|
+
if (!t24.isObjectExpression(options)) {
|
|
2458
2533
|
logger.warn("Argument for defineOptions must be an object expression.", {
|
|
2459
2534
|
source: scriptData.source,
|
|
2460
2535
|
file: filename,
|
|
@@ -2462,13 +2537,13 @@ function resolveDefineOptions(ctx) {
|
|
|
2462
2537
|
});
|
|
2463
2538
|
} else {
|
|
2464
2539
|
for (const prop of options.properties) {
|
|
2465
|
-
if (!
|
|
2540
|
+
if (!t24.isObjectProperty(prop) || !t24.isIdentifier(prop.key)) {
|
|
2466
2541
|
continue;
|
|
2467
2542
|
}
|
|
2468
2543
|
extractName(prop, ctx);
|
|
2469
2544
|
}
|
|
2470
2545
|
}
|
|
2471
|
-
|
|
2546
|
+
path9.remove();
|
|
2472
2547
|
}
|
|
2473
2548
|
};
|
|
2474
2549
|
}
|
|
@@ -2476,7 +2551,7 @@ function extractName(prop, ctx) {
|
|
|
2476
2551
|
if (ctx.compName) return;
|
|
2477
2552
|
const { filename, scriptData } = ctx;
|
|
2478
2553
|
if (!prop.computed && prop.key.name === "name") {
|
|
2479
|
-
if (
|
|
2554
|
+
if (t24.isStringLiteral(prop.value)) {
|
|
2480
2555
|
ctx.compName = prop.value.value;
|
|
2481
2556
|
return;
|
|
2482
2557
|
}
|
|
@@ -2489,7 +2564,7 @@ function extractName(prop, ctx) {
|
|
|
2489
2564
|
}
|
|
2490
2565
|
|
|
2491
2566
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-emit-calls.ts
|
|
2492
|
-
import * as
|
|
2567
|
+
import * as t25 from "@babel/types";
|
|
2493
2568
|
function resolveEmitCalls(ctx) {
|
|
2494
2569
|
const formatEmitEventName = (raw) => {
|
|
2495
2570
|
if (raw.startsWith("update:")) {
|
|
@@ -2500,10 +2575,10 @@ function resolveEmitCalls(ctx) {
|
|
|
2500
2575
|
return `on${capitalize(camelCase(normalized))}`;
|
|
2501
2576
|
};
|
|
2502
2577
|
return {
|
|
2503
|
-
CallExpression(
|
|
2504
|
-
const { node } =
|
|
2578
|
+
CallExpression(path9) {
|
|
2579
|
+
const { node } = path9;
|
|
2505
2580
|
const { filename, templateData, scriptData } = ctx;
|
|
2506
|
-
if (!
|
|
2581
|
+
if (!t25.isIdentifier(node.callee)) return;
|
|
2507
2582
|
const { name } = node.callee;
|
|
2508
2583
|
const checkIfFromDefineEmits = () => {
|
|
2509
2584
|
let result = false;
|
|
@@ -2512,10 +2587,10 @@ function resolveEmitCalls(ctx) {
|
|
|
2512
2587
|
result = meta.source === MACRO_API_NAMES.emits;
|
|
2513
2588
|
}
|
|
2514
2589
|
if (!result) {
|
|
2515
|
-
const binding =
|
|
2590
|
+
const binding = path9.scope.getBinding(name);
|
|
2516
2591
|
if (binding) {
|
|
2517
2592
|
const parent = binding.path.node;
|
|
2518
|
-
if (
|
|
2593
|
+
if (t25.isVariableDeclarator(parent) && t25.isCallExpression(parent.init) && t25.isIdentifier(parent.init.callee)) {
|
|
2519
2594
|
result = parent.init.callee.name === MACRO_API_NAMES.emits;
|
|
2520
2595
|
}
|
|
2521
2596
|
}
|
|
@@ -2524,55 +2599,56 @@ function resolveEmitCalls(ctx) {
|
|
|
2524
2599
|
};
|
|
2525
2600
|
if (!checkIfFromDefineEmits()) return;
|
|
2526
2601
|
const [callee, ...args] = node.arguments;
|
|
2527
|
-
const eventName =
|
|
2602
|
+
const eventName = t25.isStringLiteral(callee) ? formatEmitEventName(callee.value) : void 0;
|
|
2528
2603
|
if (!eventName) {
|
|
2529
2604
|
logger.warn(`Expected String type but got ${callee?.type}, expression will be removed`, {
|
|
2530
2605
|
file: filename,
|
|
2531
2606
|
source: scriptData.source,
|
|
2532
2607
|
loc: callee?.loc
|
|
2533
2608
|
});
|
|
2534
|
-
|
|
2609
|
+
path9.remove();
|
|
2535
2610
|
return;
|
|
2536
2611
|
}
|
|
2537
|
-
const propCall =
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2612
|
+
const propCall = t25.optionalCallExpression(
|
|
2613
|
+
t25.optionalMemberExpression(
|
|
2614
|
+
t25.identifier(ctx.propField),
|
|
2615
|
+
t25.identifier(eventName),
|
|
2541
2616
|
false,
|
|
2542
2617
|
true
|
|
2543
2618
|
),
|
|
2544
|
-
args
|
|
2619
|
+
args,
|
|
2620
|
+
true
|
|
2545
2621
|
);
|
|
2546
|
-
|
|
2622
|
+
path9.replaceWith(propCall);
|
|
2547
2623
|
}
|
|
2548
2624
|
};
|
|
2549
2625
|
}
|
|
2550
2626
|
|
|
2551
2627
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/index.ts
|
|
2552
|
-
import * as
|
|
2628
|
+
import * as t30 from "@babel/types";
|
|
2553
2629
|
|
|
2554
2630
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/resolve-emits.ts
|
|
2555
|
-
import * as
|
|
2631
|
+
import * as t27 from "@babel/types";
|
|
2556
2632
|
|
|
2557
2633
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/shared.ts
|
|
2558
|
-
import * as
|
|
2634
|
+
import * as t26 from "@babel/types";
|
|
2559
2635
|
function cloneCallableParams(params) {
|
|
2560
2636
|
const cloneCallableParam = (param, index) => {
|
|
2561
|
-
if (
|
|
2637
|
+
if (t26.isRestElement(param)) {
|
|
2562
2638
|
const arg = param.argument;
|
|
2563
|
-
const name =
|
|
2564
|
-
const rest =
|
|
2565
|
-
rest.typeAnnotation = param.typeAnnotation || (
|
|
2639
|
+
const name = t26.isIdentifier(arg) ? arg.name : `args${index}`;
|
|
2640
|
+
const rest = t26.restElement(t26.identifier(name));
|
|
2641
|
+
rest.typeAnnotation = param.typeAnnotation || (t26.isIdentifier(arg) ? arg.typeAnnotation : null) || t26.tsTypeAnnotation(t26.tsArrayType(t26.tsAnyKeyword()));
|
|
2566
2642
|
return rest;
|
|
2567
2643
|
}
|
|
2568
|
-
if (
|
|
2569
|
-
const id =
|
|
2644
|
+
if (t26.isIdentifier(param)) {
|
|
2645
|
+
const id = t26.identifier(param.name || `arg${index}`);
|
|
2570
2646
|
id.optional = param.optional;
|
|
2571
|
-
id.typeAnnotation = param.typeAnnotation ||
|
|
2647
|
+
id.typeAnnotation = param.typeAnnotation || t26.tsTypeAnnotation(t26.tsAnyKeyword());
|
|
2572
2648
|
return id;
|
|
2573
2649
|
}
|
|
2574
|
-
const fallback =
|
|
2575
|
-
fallback.typeAnnotation =
|
|
2650
|
+
const fallback = t26.identifier(`arg${index}`);
|
|
2651
|
+
fallback.typeAnnotation = t26.tsTypeAnnotation(t26.tsAnyKeyword());
|
|
2576
2652
|
return fallback;
|
|
2577
2653
|
};
|
|
2578
2654
|
return params.map(cloneCallableParam);
|
|
@@ -2581,19 +2657,19 @@ function cloneCallableParams(params) {
|
|
|
2581
2657
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/resolve-emits.ts
|
|
2582
2658
|
function resolveEmitsTopLevelTypes(ctx) {
|
|
2583
2659
|
return {
|
|
2584
|
-
"TSInterfaceDeclaration|TSTypeAliasDeclaration"(
|
|
2585
|
-
if (!
|
|
2586
|
-
const { node } =
|
|
2587
|
-
if (
|
|
2588
|
-
const typeLiteral =
|
|
2660
|
+
"TSInterfaceDeclaration|TSTypeAliasDeclaration"(path9) {
|
|
2661
|
+
if (!t27.isProgram(path9.parent)) return;
|
|
2662
|
+
const { node } = path9;
|
|
2663
|
+
if (t27.isTSInterfaceDeclaration(node)) {
|
|
2664
|
+
const typeLiteral = t27.tsTypeLiteral(node.body.body);
|
|
2589
2665
|
if (!hasEmitsSignatureInType(typeLiteral)) return;
|
|
2590
2666
|
const resolved = resolveTopLevelEmitType(typeLiteral);
|
|
2591
|
-
if (resolved &&
|
|
2667
|
+
if (resolved && t27.isTSTypeLiteral(resolved)) {
|
|
2592
2668
|
node.body.body = resolved.members;
|
|
2593
2669
|
}
|
|
2594
2670
|
return;
|
|
2595
2671
|
}
|
|
2596
|
-
if (
|
|
2672
|
+
if (t27.isTSTypeAliasDeclaration(node)) {
|
|
2597
2673
|
if (!hasEmitsSignatureInType(node.typeAnnotation)) return;
|
|
2598
2674
|
const resolved = resolveTopLevelEmitType(node.typeAnnotation);
|
|
2599
2675
|
if (resolved) {
|
|
@@ -2604,52 +2680,52 @@ function resolveEmitsTopLevelTypes(ctx) {
|
|
|
2604
2680
|
};
|
|
2605
2681
|
}
|
|
2606
2682
|
function resolveTopLevelEmitType(tsType) {
|
|
2607
|
-
if (
|
|
2683
|
+
if (t27.isTSParenthesizedType(tsType)) {
|
|
2608
2684
|
return resolveTopLevelEmitType(tsType.typeAnnotation);
|
|
2609
2685
|
}
|
|
2610
|
-
if (
|
|
2686
|
+
if (t27.isTSTypeReference(tsType)) {
|
|
2611
2687
|
if (!tsType.typeParameters || !tsType.typeParameters.params.length) {
|
|
2612
2688
|
return tsType;
|
|
2613
2689
|
}
|
|
2614
2690
|
const params = tsType.typeParameters.params.map((param) => resolveTopLevelEmitType(param)).filter(Boolean);
|
|
2615
|
-
return
|
|
2691
|
+
return t27.tsTypeReference(
|
|
2616
2692
|
tsType.typeName,
|
|
2617
|
-
|
|
2693
|
+
t27.tsTypeParameterInstantiation(params.length ? params : tsType.typeParameters.params)
|
|
2618
2694
|
);
|
|
2619
2695
|
}
|
|
2620
|
-
if (
|
|
2696
|
+
if (t27.isTSIntersectionType(tsType)) {
|
|
2621
2697
|
const types = tsType.types.map(resolveTopLevelEmitType).filter(Boolean);
|
|
2622
2698
|
if (!types.length) return null;
|
|
2623
2699
|
if (types.length === 1) return types[0];
|
|
2624
|
-
return
|
|
2700
|
+
return t27.tsIntersectionType(types);
|
|
2625
2701
|
}
|
|
2626
|
-
if (
|
|
2702
|
+
if (t27.isTSUnionType(tsType)) {
|
|
2627
2703
|
const types = tsType.types.map(resolveTopLevelEmitType).filter(Boolean);
|
|
2628
2704
|
if (!types.length) return null;
|
|
2629
2705
|
if (types.length === 1) return types[0];
|
|
2630
|
-
return
|
|
2706
|
+
return t27.tsUnionType(types);
|
|
2631
2707
|
}
|
|
2632
|
-
if (
|
|
2708
|
+
if (t27.isTSTypeLiteral(tsType)) {
|
|
2633
2709
|
const members = [];
|
|
2634
2710
|
for (const member of tsType.members) {
|
|
2635
|
-
if (
|
|
2711
|
+
if (t27.isTSCallSignatureDeclaration(member)) {
|
|
2636
2712
|
members.push(...resolveEmitPropsFromCallSignature(member));
|
|
2637
2713
|
continue;
|
|
2638
2714
|
}
|
|
2639
2715
|
members.push(member);
|
|
2640
2716
|
}
|
|
2641
2717
|
if (!members.length) return null;
|
|
2642
|
-
return
|
|
2718
|
+
return t27.tsTypeLiteral(members);
|
|
2643
2719
|
}
|
|
2644
|
-
if (
|
|
2720
|
+
if (t27.isTSFunctionType(tsType)) {
|
|
2645
2721
|
const props = resolveEmitPropsFromCallable(tsType.parameters, tsType.typeAnnotation);
|
|
2646
2722
|
if (!props.length) return null;
|
|
2647
|
-
return
|
|
2723
|
+
return t27.tsTypeLiteral(props);
|
|
2648
2724
|
}
|
|
2649
2725
|
return tsType;
|
|
2650
2726
|
}
|
|
2651
|
-
function resolveDefineEmitsIface(
|
|
2652
|
-
const { node } =
|
|
2727
|
+
function resolveDefineEmitsIface(path9, ctx) {
|
|
2728
|
+
const { node } = path9;
|
|
2653
2729
|
const [runtimeArg] = node.arguments;
|
|
2654
2730
|
const tsParams = node.typeParameters?.params;
|
|
2655
2731
|
if (tsParams?.length) {
|
|
@@ -2665,41 +2741,41 @@ function processInferredTypes(ctx, runtimeArg) {
|
|
|
2665
2741
|
propsTSIface: { emitTypes }
|
|
2666
2742
|
} = ctx.scriptData;
|
|
2667
2743
|
const members = [];
|
|
2668
|
-
if (
|
|
2744
|
+
if (t27.isArrayExpression(runtimeArg)) {
|
|
2669
2745
|
for (const element of runtimeArg.elements) {
|
|
2670
|
-
if (!element || !
|
|
2746
|
+
if (!element || !t27.isStringLiteral(element)) continue;
|
|
2671
2747
|
const handlerName = resolveEmitHandlerName(element.value);
|
|
2672
2748
|
const key = buildKey(handlerName);
|
|
2673
|
-
const fnType =
|
|
2749
|
+
const fnType = t27.tsFunctionType(
|
|
2674
2750
|
null,
|
|
2675
2751
|
[createRestAnyParam("args")],
|
|
2676
|
-
|
|
2752
|
+
t27.tsTypeAnnotation(t27.tsAnyKeyword())
|
|
2677
2753
|
);
|
|
2678
|
-
const prop =
|
|
2754
|
+
const prop = t27.tsPropertySignature(key, t27.tsTypeAnnotation(fnType));
|
|
2679
2755
|
prop.optional = true;
|
|
2680
2756
|
members.push(prop);
|
|
2681
2757
|
}
|
|
2682
2758
|
if (members.length) {
|
|
2683
|
-
emitTypes.push(
|
|
2759
|
+
emitTypes.push(t27.tsTypeLiteral(members));
|
|
2684
2760
|
}
|
|
2685
2761
|
return;
|
|
2686
2762
|
}
|
|
2687
|
-
if (
|
|
2763
|
+
if (t27.isObjectExpression(runtimeArg)) {
|
|
2688
2764
|
for (const prop of runtimeArg.properties) {
|
|
2689
|
-
if (!
|
|
2690
|
-
if (
|
|
2765
|
+
if (!t27.isObjectProperty(prop)) continue;
|
|
2766
|
+
if (t27.isSpreadElement(prop)) continue;
|
|
2691
2767
|
const rawName = resolvePropName(prop.key);
|
|
2692
2768
|
if (!rawName) continue;
|
|
2693
2769
|
const handlerName = resolveEmitHandlerName(rawName);
|
|
2694
2770
|
const key = buildKey(handlerName);
|
|
2695
|
-
const params =
|
|
2696
|
-
const fnType =
|
|
2697
|
-
const propSig =
|
|
2771
|
+
const params = t27.isArrayExpression(prop.value) ? resolveRuntimeTupleParams(prop.value) : [createRestAnyParam("args")];
|
|
2772
|
+
const fnType = t27.tsFunctionType(null, params, t27.tsTypeAnnotation(t27.tsAnyKeyword()));
|
|
2773
|
+
const propSig = t27.tsPropertySignature(key, t27.tsTypeAnnotation(fnType));
|
|
2698
2774
|
propSig.optional = true;
|
|
2699
2775
|
members.push(propSig);
|
|
2700
2776
|
}
|
|
2701
2777
|
if (members.length) {
|
|
2702
|
-
emitTypes.push(
|
|
2778
|
+
emitTypes.push(t27.tsTypeLiteral(members));
|
|
2703
2779
|
}
|
|
2704
2780
|
}
|
|
2705
2781
|
}
|
|
@@ -2720,129 +2796,129 @@ function resolveEmitHandlerName(rawName) {
|
|
|
2720
2796
|
return `on${name}`;
|
|
2721
2797
|
}
|
|
2722
2798
|
function resolvePropName(key) {
|
|
2723
|
-
if (
|
|
2724
|
-
if (
|
|
2725
|
-
if (
|
|
2799
|
+
if (t27.isIdentifier(key)) return key.name;
|
|
2800
|
+
if (t27.isStringLiteral(key)) return key.value;
|
|
2801
|
+
if (t27.isNumericLiteral(key)) return String(key.value);
|
|
2726
2802
|
return null;
|
|
2727
2803
|
}
|
|
2728
2804
|
function buildKey(name) {
|
|
2729
|
-
return
|
|
2805
|
+
return t27.isValidIdentifier(name) ? t27.identifier(name) : t27.stringLiteral(name);
|
|
2730
2806
|
}
|
|
2731
2807
|
function createRestAnyParam(name) {
|
|
2732
|
-
const id =
|
|
2733
|
-
const rest =
|
|
2734
|
-
rest.typeAnnotation =
|
|
2808
|
+
const id = t27.identifier(name);
|
|
2809
|
+
const rest = t27.restElement(id);
|
|
2810
|
+
rest.typeAnnotation = t27.tsTypeAnnotation(t27.tsArrayType(t27.tsAnyKeyword()));
|
|
2735
2811
|
return rest;
|
|
2736
2812
|
}
|
|
2737
2813
|
function resolveRuntimeTupleParams(value) {
|
|
2738
2814
|
const params = [];
|
|
2739
2815
|
value.elements.forEach((element, index) => {
|
|
2740
2816
|
if (!element) return;
|
|
2741
|
-
if (
|
|
2817
|
+
if (t27.isSpreadElement(element)) {
|
|
2742
2818
|
params.push(createRestAnyParam(`args${index}`));
|
|
2743
2819
|
return;
|
|
2744
2820
|
}
|
|
2745
|
-
if (
|
|
2746
|
-
const id =
|
|
2747
|
-
id.typeAnnotation = element.typeAnnotation ||
|
|
2821
|
+
if (t27.isIdentifier(element)) {
|
|
2822
|
+
const id = t27.identifier(element.name);
|
|
2823
|
+
id.typeAnnotation = element.typeAnnotation || t27.tsTypeAnnotation(t27.tsAnyKeyword());
|
|
2748
2824
|
params.push(id);
|
|
2749
2825
|
return;
|
|
2750
2826
|
}
|
|
2751
|
-
if (
|
|
2752
|
-
const id =
|
|
2753
|
-
id.typeAnnotation =
|
|
2827
|
+
if (t27.isTSAsExpression(element)) {
|
|
2828
|
+
const id = t27.identifier(`arg${index}`);
|
|
2829
|
+
id.typeAnnotation = t27.tsTypeAnnotation(element.typeAnnotation);
|
|
2754
2830
|
params.push(id);
|
|
2755
2831
|
return;
|
|
2756
2832
|
}
|
|
2757
|
-
const fallback =
|
|
2758
|
-
fallback.typeAnnotation =
|
|
2833
|
+
const fallback = t27.identifier(`arg${index}`);
|
|
2834
|
+
fallback.typeAnnotation = t27.tsTypeAnnotation(t27.tsAnyKeyword());
|
|
2759
2835
|
params.push(fallback);
|
|
2760
2836
|
});
|
|
2761
2837
|
return params;
|
|
2762
2838
|
}
|
|
2763
2839
|
function resolveExplicitEmitType(tsType) {
|
|
2764
|
-
if (
|
|
2840
|
+
if (t27.isTSParenthesizedType(tsType)) {
|
|
2765
2841
|
return resolveExplicitEmitType(tsType.typeAnnotation);
|
|
2766
2842
|
}
|
|
2767
|
-
if (
|
|
2843
|
+
if (t27.isTSTypeReference(tsType)) {
|
|
2768
2844
|
if (!tsType.typeParameters || !tsType.typeParameters.params.length) {
|
|
2769
2845
|
return tsType;
|
|
2770
2846
|
}
|
|
2771
2847
|
const params = tsType.typeParameters.params.map((param) => resolveExplicitEmitType(param)).filter(Boolean);
|
|
2772
|
-
return
|
|
2848
|
+
return t27.tsTypeReference(
|
|
2773
2849
|
tsType.typeName,
|
|
2774
|
-
|
|
2850
|
+
t27.tsTypeParameterInstantiation(params.length ? params : tsType.typeParameters.params)
|
|
2775
2851
|
);
|
|
2776
2852
|
}
|
|
2777
|
-
if (
|
|
2853
|
+
if (t27.isTSIntersectionType(tsType)) {
|
|
2778
2854
|
const types = tsType.types.map(resolveExplicitEmitType).filter(Boolean);
|
|
2779
2855
|
if (!types.length) return null;
|
|
2780
2856
|
if (types.length === 1) return types[0];
|
|
2781
|
-
return
|
|
2857
|
+
return t27.tsIntersectionType(types);
|
|
2782
2858
|
}
|
|
2783
|
-
if (
|
|
2859
|
+
if (t27.isTSUnionType(tsType)) {
|
|
2784
2860
|
const types = tsType.types.map(resolveExplicitEmitType).filter(Boolean);
|
|
2785
2861
|
if (!types.length) return null;
|
|
2786
2862
|
if (types.length === 1) return types[0];
|
|
2787
|
-
return
|
|
2863
|
+
return t27.tsUnionType(types);
|
|
2788
2864
|
}
|
|
2789
|
-
if (
|
|
2865
|
+
if (t27.isTSTypeLiteral(tsType)) {
|
|
2790
2866
|
const members = [];
|
|
2791
2867
|
for (const member of tsType.members) {
|
|
2792
|
-
if (
|
|
2868
|
+
if (t27.isTSPropertySignature(member)) {
|
|
2793
2869
|
const prop = resolveEmitPropFromPropertySignature(member);
|
|
2794
2870
|
if (prop) members.push(prop);
|
|
2795
2871
|
continue;
|
|
2796
2872
|
}
|
|
2797
|
-
if (
|
|
2873
|
+
if (t27.isTSCallSignatureDeclaration(member)) {
|
|
2798
2874
|
members.push(...resolveEmitPropsFromCallSignature(member));
|
|
2799
2875
|
continue;
|
|
2800
2876
|
}
|
|
2801
2877
|
}
|
|
2802
2878
|
if (!members.length) return null;
|
|
2803
|
-
return
|
|
2879
|
+
return t27.tsTypeLiteral(members);
|
|
2804
2880
|
}
|
|
2805
|
-
if (
|
|
2881
|
+
if (t27.isTSFunctionType(tsType)) {
|
|
2806
2882
|
const props = resolveEmitPropsFromCallable(tsType.parameters, tsType.typeAnnotation);
|
|
2807
2883
|
if (!props.length) return null;
|
|
2808
|
-
return
|
|
2884
|
+
return t27.tsTypeLiteral(props);
|
|
2809
2885
|
}
|
|
2810
2886
|
return tsType;
|
|
2811
2887
|
}
|
|
2812
2888
|
function hasEmitsSignatureInType(tsType) {
|
|
2813
|
-
if (
|
|
2889
|
+
if (t27.isTSParenthesizedType(tsType)) {
|
|
2814
2890
|
return hasEmitsSignatureInType(tsType.typeAnnotation);
|
|
2815
2891
|
}
|
|
2816
|
-
if (
|
|
2892
|
+
if (t27.isTSTypeReference(tsType)) {
|
|
2817
2893
|
if (!tsType.typeParameters || !tsType.typeParameters.params.length) {
|
|
2818
2894
|
return false;
|
|
2819
2895
|
}
|
|
2820
2896
|
return tsType.typeParameters.params.some(hasEmitsSignatureInType);
|
|
2821
2897
|
}
|
|
2822
|
-
if (
|
|
2898
|
+
if (t27.isTSIntersectionType(tsType) || t27.isTSUnionType(tsType)) {
|
|
2823
2899
|
return tsType.types.some(hasEmitsSignatureInType);
|
|
2824
2900
|
}
|
|
2825
|
-
if (
|
|
2901
|
+
if (t27.isTSTypeLiteral(tsType)) {
|
|
2826
2902
|
return tsType.members.some(hasEmitsSignatureInMember);
|
|
2827
2903
|
}
|
|
2828
|
-
if (
|
|
2904
|
+
if (t27.isTSFunctionType(tsType)) {
|
|
2829
2905
|
return isEmitsCallable(tsType.parameters);
|
|
2830
2906
|
}
|
|
2831
2907
|
return false;
|
|
2832
2908
|
}
|
|
2833
2909
|
function hasEmitsSignatureInMember(member) {
|
|
2834
|
-
if (
|
|
2910
|
+
if (t27.isTSCallSignatureDeclaration(member)) {
|
|
2835
2911
|
return isEmitsCallable(member.parameters);
|
|
2836
2912
|
}
|
|
2837
2913
|
return false;
|
|
2838
2914
|
}
|
|
2839
2915
|
function isEmitsCallable(parameters) {
|
|
2840
2916
|
const [eventParam] = parameters;
|
|
2841
|
-
if (!eventParam || !
|
|
2917
|
+
if (!eventParam || !t27.isIdentifier(eventParam) || !eventParam.typeAnnotation) {
|
|
2842
2918
|
return false;
|
|
2843
2919
|
}
|
|
2844
2920
|
const { typeAnnotation } = eventParam;
|
|
2845
|
-
if (
|
|
2921
|
+
if (t27.isNoop(typeAnnotation)) return false;
|
|
2846
2922
|
return resolveEventNames(typeAnnotation.typeAnnotation).length > 0;
|
|
2847
2923
|
}
|
|
2848
2924
|
function resolveEmitPropFromPropertySignature(member) {
|
|
@@ -2852,19 +2928,19 @@ function resolveEmitPropFromPropertySignature(member) {
|
|
|
2852
2928
|
const key = buildKey(handlerName);
|
|
2853
2929
|
const typeAnnotation = member.typeAnnotation?.typeAnnotation;
|
|
2854
2930
|
let params = [];
|
|
2855
|
-
let returnType =
|
|
2856
|
-
if (typeAnnotation &&
|
|
2931
|
+
let returnType = t27.tsAnyKeyword();
|
|
2932
|
+
if (typeAnnotation && t27.isTSFunctionType(typeAnnotation)) {
|
|
2857
2933
|
params = cloneCallableParams(typeAnnotation.parameters);
|
|
2858
2934
|
returnType = typeAnnotation.typeAnnotation?.typeAnnotation ?? returnType;
|
|
2859
|
-
} else if (typeAnnotation &&
|
|
2935
|
+
} else if (typeAnnotation && t27.isTSTupleType(typeAnnotation)) {
|
|
2860
2936
|
params = resolveTupleTypeParams(typeAnnotation);
|
|
2861
2937
|
} else if (typeAnnotation) {
|
|
2862
|
-
const id =
|
|
2863
|
-
id.typeAnnotation =
|
|
2938
|
+
const id = t27.identifier("value");
|
|
2939
|
+
id.typeAnnotation = t27.tsTypeAnnotation(typeAnnotation);
|
|
2864
2940
|
params = [id];
|
|
2865
2941
|
}
|
|
2866
|
-
const fnType =
|
|
2867
|
-
const prop =
|
|
2942
|
+
const fnType = t27.tsFunctionType(null, params, t27.tsTypeAnnotation(returnType));
|
|
2943
|
+
const prop = t27.tsPropertySignature(key, t27.tsTypeAnnotation(fnType));
|
|
2868
2944
|
prop.optional = !!member.optional;
|
|
2869
2945
|
return prop;
|
|
2870
2946
|
}
|
|
@@ -2873,32 +2949,32 @@ function resolveEmitPropsFromCallSignature(member) {
|
|
|
2873
2949
|
}
|
|
2874
2950
|
function resolveEmitPropsFromCallable(parameters, typeAnnotation) {
|
|
2875
2951
|
const [eventParam, ...restParams] = parameters;
|
|
2876
|
-
if (!eventParam || !
|
|
2952
|
+
if (!eventParam || !t27.isIdentifier(eventParam) || !eventParam.typeAnnotation) {
|
|
2877
2953
|
return [];
|
|
2878
2954
|
}
|
|
2879
2955
|
const { typeAnnotation: paramTypeAnnotation } = eventParam;
|
|
2880
|
-
if (
|
|
2956
|
+
if (t27.isNoop(paramTypeAnnotation)) return [];
|
|
2881
2957
|
const eventNames = resolveEventNames(paramTypeAnnotation.typeAnnotation);
|
|
2882
2958
|
if (!eventNames.length) return [];
|
|
2883
|
-
const returnType = typeAnnotation?.typeAnnotation ??
|
|
2959
|
+
const returnType = typeAnnotation?.typeAnnotation ?? t27.tsAnyKeyword();
|
|
2884
2960
|
return eventNames.map((eventName) => {
|
|
2885
2961
|
const handlerName = resolveEmitHandlerName(eventName);
|
|
2886
2962
|
const key = buildKey(handlerName);
|
|
2887
2963
|
const params = cloneCallableParams(restParams);
|
|
2888
|
-
const fnType =
|
|
2889
|
-
const prop =
|
|
2964
|
+
const fnType = t27.tsFunctionType(null, params, t27.tsTypeAnnotation(returnType));
|
|
2965
|
+
const prop = t27.tsPropertySignature(key, t27.tsTypeAnnotation(fnType));
|
|
2890
2966
|
prop.optional = true;
|
|
2891
2967
|
return prop;
|
|
2892
2968
|
});
|
|
2893
2969
|
}
|
|
2894
2970
|
function resolveEventNames(type) {
|
|
2895
|
-
if (
|
|
2971
|
+
if (t27.isTSLiteralType(type) && t27.isStringLiteral(type.literal)) {
|
|
2896
2972
|
return [type.literal.value];
|
|
2897
2973
|
}
|
|
2898
|
-
if (
|
|
2974
|
+
if (t27.isTSUnionType(type)) {
|
|
2899
2975
|
return type.types.flatMap(resolveEventNames);
|
|
2900
2976
|
}
|
|
2901
|
-
if (
|
|
2977
|
+
if (t27.isTSParenthesizedType(type)) {
|
|
2902
2978
|
return resolveEventNames(type.typeAnnotation);
|
|
2903
2979
|
}
|
|
2904
2980
|
return [];
|
|
@@ -2911,46 +2987,46 @@ function resolveTupleTypeParams(tuple) {
|
|
|
2911
2987
|
return params;
|
|
2912
2988
|
}
|
|
2913
2989
|
function resolveTupleElementParam(element, index) {
|
|
2914
|
-
const isNamedTuple = typeof
|
|
2990
|
+
const isNamedTuple = typeof t27.isTSNamedTupleMember === "function" && t27.isTSNamedTupleMember(element);
|
|
2915
2991
|
if (isNamedTuple) {
|
|
2916
2992
|
const tupleMember = element;
|
|
2917
2993
|
const name = tupleMember.label?.name || `arg${index}`;
|
|
2918
2994
|
let innerType = tupleMember.elementType;
|
|
2919
2995
|
let optional = tupleMember.optional;
|
|
2920
|
-
if (
|
|
2996
|
+
if (t27.isTSOptionalType(innerType)) {
|
|
2921
2997
|
optional = true;
|
|
2922
2998
|
innerType = innerType.typeAnnotation;
|
|
2923
2999
|
}
|
|
2924
|
-
if (
|
|
2925
|
-
const rest =
|
|
2926
|
-
rest.typeAnnotation =
|
|
3000
|
+
if (t27.isTSRestType(innerType)) {
|
|
3001
|
+
const rest = t27.restElement(t27.identifier(name));
|
|
3002
|
+
rest.typeAnnotation = t27.tsTypeAnnotation(innerType.typeAnnotation);
|
|
2927
3003
|
return rest;
|
|
2928
3004
|
}
|
|
2929
|
-
const id2 =
|
|
3005
|
+
const id2 = t27.identifier(name);
|
|
2930
3006
|
id2.optional = optional;
|
|
2931
|
-
id2.typeAnnotation =
|
|
3007
|
+
id2.typeAnnotation = t27.tsTypeAnnotation(innerType);
|
|
2932
3008
|
return id2;
|
|
2933
3009
|
}
|
|
2934
|
-
if (
|
|
2935
|
-
const rest =
|
|
2936
|
-
rest.typeAnnotation =
|
|
3010
|
+
if (t27.isTSRestType(element)) {
|
|
3011
|
+
const rest = t27.restElement(t27.identifier(`args${index}`));
|
|
3012
|
+
rest.typeAnnotation = t27.tsTypeAnnotation(element.typeAnnotation);
|
|
2937
3013
|
return rest;
|
|
2938
3014
|
}
|
|
2939
|
-
if (
|
|
2940
|
-
const id2 =
|
|
3015
|
+
if (t27.isTSOptionalType(element)) {
|
|
3016
|
+
const id2 = t27.identifier(`arg${index}`);
|
|
2941
3017
|
id2.optional = true;
|
|
2942
|
-
id2.typeAnnotation =
|
|
3018
|
+
id2.typeAnnotation = t27.tsTypeAnnotation(element.typeAnnotation);
|
|
2943
3019
|
return id2;
|
|
2944
3020
|
}
|
|
2945
|
-
const id =
|
|
2946
|
-
id.typeAnnotation =
|
|
3021
|
+
const id = t27.identifier(`arg${index}`);
|
|
3022
|
+
id.typeAnnotation = t27.tsTypeAnnotation(element);
|
|
2947
3023
|
return id;
|
|
2948
3024
|
}
|
|
2949
3025
|
|
|
2950
3026
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/resolve-props.ts
|
|
2951
|
-
import * as
|
|
2952
|
-
function resolveDefinePropsIface(
|
|
2953
|
-
const { node } =
|
|
3027
|
+
import * as t28 from "@babel/types";
|
|
3028
|
+
function resolveDefinePropsIface(path9, ctx) {
|
|
3029
|
+
const { node } = path9;
|
|
2954
3030
|
const [runtimeArg] = node.arguments;
|
|
2955
3031
|
const tsParams = node.typeParameters?.params;
|
|
2956
3032
|
if (tsParams?.length) {
|
|
@@ -2968,38 +3044,38 @@ function processInferredTypes2(ctx, runtimeArg) {
|
|
|
2968
3044
|
} = scriptData;
|
|
2969
3045
|
if (!runtimeArg) return;
|
|
2970
3046
|
const members = [];
|
|
2971
|
-
if (
|
|
3047
|
+
if (t28.isArrayExpression(runtimeArg)) {
|
|
2972
3048
|
for (const element of runtimeArg.elements) {
|
|
2973
|
-
if (!element || !
|
|
2974
|
-
const key =
|
|
2975
|
-
const prop =
|
|
3049
|
+
if (!element || !t28.isStringLiteral(element)) continue;
|
|
3050
|
+
const key = t28.isValidIdentifier(element.value) ? t28.identifier(element.value) : t28.stringLiteral(element.value);
|
|
3051
|
+
const prop = t28.tsPropertySignature(key, t28.tsTypeAnnotation(t28.tsAnyKeyword()));
|
|
2976
3052
|
prop.optional = true;
|
|
2977
3053
|
members.push(prop);
|
|
2978
3054
|
}
|
|
2979
3055
|
if (members.length) {
|
|
2980
|
-
propsTypes.push(
|
|
3056
|
+
propsTypes.push(t28.tsTypeLiteral(members));
|
|
2981
3057
|
}
|
|
2982
3058
|
return;
|
|
2983
3059
|
}
|
|
2984
|
-
if (
|
|
3060
|
+
if (t28.isObjectExpression(runtimeArg)) {
|
|
2985
3061
|
for (const prop of runtimeArg.properties) {
|
|
2986
|
-
if (!
|
|
2987
|
-
if (
|
|
3062
|
+
if (!t28.isObjectProperty(prop)) continue;
|
|
3063
|
+
if (t28.isSpreadElement(prop)) continue;
|
|
2988
3064
|
const key = prop.key;
|
|
2989
3065
|
let propName = null;
|
|
2990
|
-
if (
|
|
2991
|
-
if (
|
|
2992
|
-
if (
|
|
3066
|
+
if (t28.isIdentifier(key)) propName = key.name;
|
|
3067
|
+
if (t28.isStringLiteral(key)) propName = key.value;
|
|
3068
|
+
if (t28.isNumericLiteral(key)) propName = String(key.value);
|
|
2993
3069
|
if (!propName) continue;
|
|
2994
3070
|
const { type, required } = resolveRuntimePropMeta(prop.value);
|
|
2995
|
-
const tsType = type ??
|
|
2996
|
-
const tsKey =
|
|
2997
|
-
const tsProp =
|
|
3071
|
+
const tsType = type ?? t28.tsAnyKeyword();
|
|
3072
|
+
const tsKey = t28.isValidIdentifier(propName) ? t28.identifier(propName) : t28.stringLiteral(propName);
|
|
3073
|
+
const tsProp = t28.tsPropertySignature(tsKey, t28.tsTypeAnnotation(tsType));
|
|
2998
3074
|
tsProp.optional = !required;
|
|
2999
3075
|
members.push(tsProp);
|
|
3000
3076
|
}
|
|
3001
3077
|
if (members.length) {
|
|
3002
|
-
propsTypes.push(
|
|
3078
|
+
propsTypes.push(t28.tsTypeLiteral(members));
|
|
3003
3079
|
}
|
|
3004
3080
|
return;
|
|
3005
3081
|
}
|
|
@@ -3013,42 +3089,42 @@ function processInferredTypes2(ctx, runtimeArg) {
|
|
|
3013
3089
|
);
|
|
3014
3090
|
}
|
|
3015
3091
|
function resolveRuntimePropMeta(value) {
|
|
3016
|
-
if (
|
|
3092
|
+
if (t28.isIdentifier(value)) {
|
|
3017
3093
|
return {
|
|
3018
3094
|
type: mapRuntimeTypeToTSType(value),
|
|
3019
3095
|
required: false
|
|
3020
3096
|
};
|
|
3021
3097
|
}
|
|
3022
|
-
if (
|
|
3098
|
+
if (t28.isArrayExpression(value)) {
|
|
3023
3099
|
return {
|
|
3024
3100
|
type: resolveRuntimeUnionType(value),
|
|
3025
3101
|
required: false
|
|
3026
3102
|
};
|
|
3027
3103
|
}
|
|
3028
|
-
if (!
|
|
3104
|
+
if (!t28.isObjectExpression(value)) {
|
|
3029
3105
|
return { required: false };
|
|
3030
3106
|
}
|
|
3031
3107
|
let type;
|
|
3032
3108
|
let required = false;
|
|
3033
3109
|
for (const prop of value.properties) {
|
|
3034
|
-
if (!
|
|
3035
|
-
if (
|
|
3110
|
+
if (!t28.isObjectProperty(prop)) continue;
|
|
3111
|
+
if (t28.isSpreadElement(prop)) continue;
|
|
3036
3112
|
const key = prop.key;
|
|
3037
|
-
const propName =
|
|
3113
|
+
const propName = t28.isIdentifier(key) ? key.name : t28.isStringLiteral(key) ? key.value : null;
|
|
3038
3114
|
if (!propName) continue;
|
|
3039
3115
|
if (propName === "type") {
|
|
3040
3116
|
const valueNode = prop.value;
|
|
3041
|
-
if (
|
|
3117
|
+
if (t28.isArrayExpression(valueNode)) {
|
|
3042
3118
|
type = resolveRuntimeUnionType(valueNode);
|
|
3043
3119
|
continue;
|
|
3044
3120
|
}
|
|
3045
|
-
if (
|
|
3121
|
+
if (t28.isIdentifier(valueNode)) {
|
|
3046
3122
|
type = mapRuntimeTypeToTSType(valueNode);
|
|
3047
3123
|
continue;
|
|
3048
3124
|
}
|
|
3049
3125
|
}
|
|
3050
3126
|
if (propName === "required") {
|
|
3051
|
-
if (
|
|
3127
|
+
if (t28.isBooleanLiteral(prop.value)) {
|
|
3052
3128
|
required = prop.value.value;
|
|
3053
3129
|
}
|
|
3054
3130
|
}
|
|
@@ -3058,58 +3134,58 @@ function resolveRuntimePropMeta(value) {
|
|
|
3058
3134
|
function resolveRuntimeUnionType(value) {
|
|
3059
3135
|
const types = [];
|
|
3060
3136
|
for (const element of value.elements) {
|
|
3061
|
-
if (!element || !
|
|
3137
|
+
if (!element || !t28.isIdentifier(element)) continue;
|
|
3062
3138
|
const resolved = mapRuntimeTypeToTSType(element);
|
|
3063
3139
|
if (resolved) types.push(resolved);
|
|
3064
3140
|
}
|
|
3065
|
-
if (!types.length) return
|
|
3141
|
+
if (!types.length) return t28.tsAnyKeyword();
|
|
3066
3142
|
if (types.length === 1) return types[0];
|
|
3067
|
-
return
|
|
3143
|
+
return t28.tsUnionType(types);
|
|
3068
3144
|
}
|
|
3069
3145
|
function mapRuntimeTypeToTSType(value) {
|
|
3070
3146
|
switch (value.name) {
|
|
3071
3147
|
case "String":
|
|
3072
|
-
return
|
|
3148
|
+
return t28.tsStringKeyword();
|
|
3073
3149
|
case "Number":
|
|
3074
|
-
return
|
|
3150
|
+
return t28.tsNumberKeyword();
|
|
3075
3151
|
case "Boolean":
|
|
3076
|
-
return
|
|
3152
|
+
return t28.tsBooleanKeyword();
|
|
3077
3153
|
case "Object":
|
|
3078
|
-
return
|
|
3154
|
+
return t28.tsTypeLiteral([]);
|
|
3079
3155
|
case "Array":
|
|
3080
|
-
return
|
|
3156
|
+
return t28.tsArrayType(t28.tsAnyKeyword());
|
|
3081
3157
|
case "Function":
|
|
3082
|
-
return
|
|
3158
|
+
return t28.tsFunctionType(null, [], t28.tsTypeAnnotation(t28.tsAnyKeyword()));
|
|
3083
3159
|
case "Symbol":
|
|
3084
|
-
return
|
|
3160
|
+
return t28.tsSymbolKeyword();
|
|
3085
3161
|
case "BigInt":
|
|
3086
|
-
return
|
|
3162
|
+
return t28.tsBigIntKeyword();
|
|
3087
3163
|
default:
|
|
3088
|
-
return
|
|
3164
|
+
return t28.tsAnyKeyword();
|
|
3089
3165
|
}
|
|
3090
3166
|
}
|
|
3091
3167
|
|
|
3092
3168
|
// src/core/transform/sfc/script/syntax-processor/preprocess/resolve-props-interface/resolve-slot.ts
|
|
3093
|
-
import * as
|
|
3169
|
+
import * as t29 from "@babel/types";
|
|
3094
3170
|
var SLOT_DEFAULT_NAME = "default";
|
|
3095
3171
|
var SLOT_CHILDREN_NAME = "children";
|
|
3096
3172
|
var SLOT_FN_PARAM_NAME = "props";
|
|
3097
3173
|
function resolveSlotsTopLevelTypes(ctx) {
|
|
3098
3174
|
return {
|
|
3099
|
-
"TSInterfaceDeclaration|TSTypeAliasDeclaration"(
|
|
3100
|
-
if (!
|
|
3101
|
-
const { node } =
|
|
3102
|
-
if (
|
|
3103
|
-
const typeLiteral =
|
|
3175
|
+
"TSInterfaceDeclaration|TSTypeAliasDeclaration"(path9) {
|
|
3176
|
+
if (!t29.isProgram(path9.parent)) return;
|
|
3177
|
+
const { node } = path9;
|
|
3178
|
+
if (t29.isTSInterfaceDeclaration(node)) {
|
|
3179
|
+
const typeLiteral = t29.tsTypeLiteral(node.body.body);
|
|
3104
3180
|
if (!hasSlotsSignatureInType(typeLiteral)) return;
|
|
3105
3181
|
const resolved = resolveSlotType(typeLiteral);
|
|
3106
|
-
if (resolved &&
|
|
3182
|
+
if (resolved && t29.isTSTypeLiteral(resolved)) {
|
|
3107
3183
|
node.body.body = resolved.members;
|
|
3108
3184
|
recordReactNode(ctx);
|
|
3109
3185
|
}
|
|
3110
3186
|
return;
|
|
3111
3187
|
}
|
|
3112
|
-
if (
|
|
3188
|
+
if (t29.isTSTypeAliasDeclaration(node)) {
|
|
3113
3189
|
if (!hasSlotsSignatureInType(node.typeAnnotation)) return;
|
|
3114
3190
|
const resolved = resolveSlotType(node.typeAnnotation);
|
|
3115
3191
|
if (resolved) {
|
|
@@ -3120,8 +3196,8 @@ function resolveSlotsTopLevelTypes(ctx) {
|
|
|
3120
3196
|
}
|
|
3121
3197
|
};
|
|
3122
3198
|
}
|
|
3123
|
-
function resolveDefineSlotsIface(
|
|
3124
|
-
const { node } =
|
|
3199
|
+
function resolveDefineSlotsIface(path9, ctx) {
|
|
3200
|
+
const { node } = path9;
|
|
3125
3201
|
const tsParams = node.typeParameters?.params;
|
|
3126
3202
|
if (!tsParams?.length) return;
|
|
3127
3203
|
const {
|
|
@@ -3154,7 +3230,7 @@ function resolveTemplateSlotIface(ctx) {
|
|
|
3154
3230
|
}
|
|
3155
3231
|
if (tsMembers.length) {
|
|
3156
3232
|
recordReactNode(ctx);
|
|
3157
|
-
slotTypes.push(
|
|
3233
|
+
slotTypes.push(t29.tsTypeLiteral(tsMembers));
|
|
3158
3234
|
}
|
|
3159
3235
|
}
|
|
3160
3236
|
function recordReactNode(ctx) {
|
|
@@ -3164,32 +3240,32 @@ function recordReactNode(ctx) {
|
|
|
3164
3240
|
recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.ReactNode);
|
|
3165
3241
|
}
|
|
3166
3242
|
function resolveSlotType(tsType) {
|
|
3167
|
-
if (
|
|
3243
|
+
if (t29.isTSParenthesizedType(tsType)) {
|
|
3168
3244
|
return resolveSlotType(tsType.typeAnnotation);
|
|
3169
3245
|
}
|
|
3170
|
-
if (
|
|
3246
|
+
if (t29.isTSTypeReference(tsType)) {
|
|
3171
3247
|
if (!tsType.typeParameters || !tsType.typeParameters.params.length) {
|
|
3172
3248
|
return tsType;
|
|
3173
3249
|
}
|
|
3174
3250
|
const params = tsType.typeParameters.params.map((param) => resolveSlotType(param)).filter(Boolean);
|
|
3175
|
-
return
|
|
3251
|
+
return t29.tsTypeReference(
|
|
3176
3252
|
tsType.typeName,
|
|
3177
|
-
|
|
3253
|
+
t29.tsTypeParameterInstantiation(params.length ? params : tsType.typeParameters.params)
|
|
3178
3254
|
);
|
|
3179
3255
|
}
|
|
3180
|
-
if (
|
|
3256
|
+
if (t29.isTSIntersectionType(tsType)) {
|
|
3181
3257
|
const types = tsType.types.map(resolveSlotType).filter(Boolean);
|
|
3182
3258
|
if (!types.length) return null;
|
|
3183
3259
|
if (types.length === 1) return types[0];
|
|
3184
|
-
return
|
|
3260
|
+
return t29.tsIntersectionType(types);
|
|
3185
3261
|
}
|
|
3186
|
-
if (
|
|
3262
|
+
if (t29.isTSUnionType(tsType)) {
|
|
3187
3263
|
const types = tsType.types.map(resolveSlotType).filter(Boolean);
|
|
3188
3264
|
if (!types.length) return null;
|
|
3189
3265
|
if (types.length === 1) return types[0];
|
|
3190
|
-
return
|
|
3266
|
+
return t29.tsUnionType(types);
|
|
3191
3267
|
}
|
|
3192
|
-
if (
|
|
3268
|
+
if (t29.isTSTypeLiteral(tsType)) {
|
|
3193
3269
|
const members = [];
|
|
3194
3270
|
for (const member of tsType.members) {
|
|
3195
3271
|
const resolved = resolveSlotPropFromMember(member);
|
|
@@ -3200,56 +3276,56 @@ function resolveSlotType(tsType) {
|
|
|
3200
3276
|
members.push(member);
|
|
3201
3277
|
}
|
|
3202
3278
|
if (!members.length) return null;
|
|
3203
|
-
return
|
|
3279
|
+
return t29.tsTypeLiteral(members);
|
|
3204
3280
|
}
|
|
3205
|
-
if (
|
|
3281
|
+
if (t29.isTSFunctionType(tsType)) {
|
|
3206
3282
|
const props = buildSlotPropSignature(
|
|
3207
3283
|
SLOT_DEFAULT_NAME,
|
|
3208
3284
|
cloneCallableParams(tsType.parameters),
|
|
3209
3285
|
false
|
|
3210
3286
|
);
|
|
3211
|
-
return
|
|
3287
|
+
return t29.tsTypeLiteral([props]);
|
|
3212
3288
|
}
|
|
3213
3289
|
return tsType;
|
|
3214
3290
|
}
|
|
3215
3291
|
function hasSlotsSignatureInType(tsType) {
|
|
3216
|
-
if (
|
|
3292
|
+
if (t29.isTSParenthesizedType(tsType)) {
|
|
3217
3293
|
return hasSlotsSignatureInType(tsType.typeAnnotation);
|
|
3218
3294
|
}
|
|
3219
|
-
if (
|
|
3295
|
+
if (t29.isTSTypeReference(tsType)) {
|
|
3220
3296
|
if (!tsType.typeParameters || !tsType.typeParameters.params.length) {
|
|
3221
3297
|
return false;
|
|
3222
3298
|
}
|
|
3223
3299
|
return tsType.typeParameters.params.some(hasSlotsSignatureInType);
|
|
3224
3300
|
}
|
|
3225
|
-
if (
|
|
3301
|
+
if (t29.isTSIntersectionType(tsType) || t29.isTSUnionType(tsType)) {
|
|
3226
3302
|
return tsType.types.some(hasSlotsSignatureInType);
|
|
3227
3303
|
}
|
|
3228
|
-
if (
|
|
3304
|
+
if (t29.isTSTypeLiteral(tsType)) {
|
|
3229
3305
|
return tsType.members.some(hasSlotsSignatureInMember);
|
|
3230
3306
|
}
|
|
3231
|
-
if (
|
|
3307
|
+
if (t29.isTSFunctionType(tsType)) {
|
|
3232
3308
|
return true;
|
|
3233
3309
|
}
|
|
3234
3310
|
return false;
|
|
3235
3311
|
}
|
|
3236
3312
|
function hasSlotsSignatureInMember(member) {
|
|
3237
|
-
if (
|
|
3238
|
-
if (
|
|
3239
|
-
if (
|
|
3313
|
+
if (t29.isTSMethodSignature(member)) return true;
|
|
3314
|
+
if (t29.isTSCallSignatureDeclaration(member)) return true;
|
|
3315
|
+
if (t29.isTSPropertySignature(member)) {
|
|
3240
3316
|
const typeAnnotation = member.typeAnnotation?.typeAnnotation;
|
|
3241
3317
|
return !!(typeAnnotation && resolveCallableType(typeAnnotation));
|
|
3242
3318
|
}
|
|
3243
3319
|
return false;
|
|
3244
3320
|
}
|
|
3245
3321
|
function resolveSlotPropFromMember(member) {
|
|
3246
|
-
if (
|
|
3322
|
+
if (t29.isTSMethodSignature(member)) {
|
|
3247
3323
|
const rawName = resolvePropName2(member.key);
|
|
3248
3324
|
if (!rawName) return null;
|
|
3249
3325
|
const params = cloneCallableParams(member.parameters);
|
|
3250
3326
|
return buildSlotPropSignature(rawName, params, !!member.optional);
|
|
3251
3327
|
}
|
|
3252
|
-
if (
|
|
3328
|
+
if (t29.isTSPropertySignature(member)) {
|
|
3253
3329
|
const rawName = resolvePropName2(member.key);
|
|
3254
3330
|
if (!rawName) return null;
|
|
3255
3331
|
const typeAnnotation = member.typeAnnotation?.typeAnnotation;
|
|
@@ -3258,53 +3334,53 @@ function resolveSlotPropFromMember(member) {
|
|
|
3258
3334
|
const params = cloneCallableParams(callable.parameters);
|
|
3259
3335
|
return buildSlotPropSignature(rawName, params, !!member.optional);
|
|
3260
3336
|
}
|
|
3261
|
-
if (
|
|
3337
|
+
if (t29.isTSCallSignatureDeclaration(member)) {
|
|
3262
3338
|
const params = cloneCallableParams(member.parameters);
|
|
3263
3339
|
return buildSlotPropSignature(SLOT_DEFAULT_NAME, params, true);
|
|
3264
3340
|
}
|
|
3265
3341
|
return null;
|
|
3266
3342
|
}
|
|
3267
3343
|
function resolveCallableType(tsType) {
|
|
3268
|
-
if (
|
|
3269
|
-
if (
|
|
3344
|
+
if (t29.isTSFunctionType(tsType)) return tsType;
|
|
3345
|
+
if (t29.isTSParenthesizedType(tsType)) return resolveCallableType(tsType.typeAnnotation);
|
|
3270
3346
|
return null;
|
|
3271
3347
|
}
|
|
3272
3348
|
function buildSlotPropSignature(rawName, params, optional) {
|
|
3273
3349
|
const propName = rawName === SLOT_DEFAULT_NAME ? SLOT_CHILDREN_NAME : rawName;
|
|
3274
|
-
const key =
|
|
3275
|
-
const reactNodeType =
|
|
3276
|
-
|
|
3350
|
+
const key = t29.isValidIdentifier(propName) ? t29.identifier(propName) : t29.stringLiteral(propName);
|
|
3351
|
+
const reactNodeType = t29.tsTypeAnnotation(
|
|
3352
|
+
t29.tsTypeReference(t29.identifier(REACT_API_MAP.ReactNode))
|
|
3277
3353
|
);
|
|
3278
3354
|
let typeAnnotation;
|
|
3279
3355
|
if (rawName === SLOT_DEFAULT_NAME && params.length === 0 || params.length === 0) {
|
|
3280
3356
|
typeAnnotation = reactNodeType;
|
|
3281
3357
|
} else {
|
|
3282
|
-
const fnType =
|
|
3283
|
-
typeAnnotation =
|
|
3358
|
+
const fnType = t29.tsFunctionType(null, params, reactNodeType);
|
|
3359
|
+
typeAnnotation = t29.tsTypeAnnotation(fnType);
|
|
3284
3360
|
}
|
|
3285
|
-
const prop =
|
|
3361
|
+
const prop = t29.tsPropertySignature(key, typeAnnotation);
|
|
3286
3362
|
prop.optional = optional;
|
|
3287
3363
|
return prop;
|
|
3288
3364
|
}
|
|
3289
3365
|
function createSlotScopeParam(props, ctx) {
|
|
3290
|
-
const paramId =
|
|
3366
|
+
const paramId = t29.identifier(SLOT_FN_PARAM_NAME);
|
|
3291
3367
|
const propsSigns = [];
|
|
3292
3368
|
const { reactiveBindings } = ctx.templateData;
|
|
3293
3369
|
props.forEach(({ prop, tsType }) => {
|
|
3294
3370
|
const foundBindingValue = reactiveBindings[prop]?.value;
|
|
3295
3371
|
const foundBindingTypes = foundBindingValue ? expressionToTSType(foundBindingValue) : null;
|
|
3296
|
-
const typeAnnotation = foundBindingTypes ?
|
|
3297
|
-
const key =
|
|
3298
|
-
const propSign =
|
|
3372
|
+
const typeAnnotation = foundBindingTypes ? t29.tsTypeAnnotation(foundBindingTypes) : tsType;
|
|
3373
|
+
const key = t29.isValidIdentifier(prop) ? t29.identifier(prop) : t29.stringLiteral(prop);
|
|
3374
|
+
const propSign = t29.tsPropertySignature(key, typeAnnotation);
|
|
3299
3375
|
propsSigns.push(propSign);
|
|
3300
3376
|
});
|
|
3301
|
-
paramId.typeAnnotation =
|
|
3377
|
+
paramId.typeAnnotation = t29.tsTypeAnnotation(t29.tsTypeLiteral(propsSigns));
|
|
3302
3378
|
return paramId;
|
|
3303
3379
|
}
|
|
3304
3380
|
function resolvePropName2(key) {
|
|
3305
|
-
if (
|
|
3306
|
-
if (
|
|
3307
|
-
if (
|
|
3381
|
+
if (t29.isIdentifier(key)) return key.name;
|
|
3382
|
+
if (t29.isStringLiteral(key)) return key.value;
|
|
3383
|
+
if (t29.isNumericLiteral(key)) return String(key.value);
|
|
3308
3384
|
return null;
|
|
3309
3385
|
}
|
|
3310
3386
|
|
|
@@ -3312,8 +3388,8 @@ function resolvePropName2(key) {
|
|
|
3312
3388
|
function resolvePropsIface(ctx) {
|
|
3313
3389
|
const isTS = ctx.scriptData.lang.startsWith("ts");
|
|
3314
3390
|
return {
|
|
3315
|
-
CallExpression(
|
|
3316
|
-
const { node, parentPath } =
|
|
3391
|
+
CallExpression(path9) {
|
|
3392
|
+
const { node, parentPath } = path9;
|
|
3317
3393
|
const name = node.callee.name;
|
|
3318
3394
|
if (!isCalleeNamed(node, MACRO_API_NAMES.props) && !isCalleeNamed(node, MACRO_API_NAMES.emits) && !isCalleeNamed(node, MACRO_API_NAMES.slots)) {
|
|
3319
3395
|
return;
|
|
@@ -3322,7 +3398,7 @@ function resolvePropsIface(ctx) {
|
|
|
3322
3398
|
if (parentPath.isVariableDeclaration() || parentPath.isVariableDeclarator()) {
|
|
3323
3399
|
parentPath.remove();
|
|
3324
3400
|
} else {
|
|
3325
|
-
|
|
3401
|
+
path9.remove();
|
|
3326
3402
|
}
|
|
3327
3403
|
};
|
|
3328
3404
|
if (ctx.inputType !== "sfc") {
|
|
@@ -3336,11 +3412,11 @@ function resolvePropsIface(ctx) {
|
|
|
3336
3412
|
propsTSIface.hasPropsInJsEnv = true;
|
|
3337
3413
|
} else {
|
|
3338
3414
|
if (name === MACRO_API_NAMES.props) {
|
|
3339
|
-
resolveDefinePropsIface(
|
|
3415
|
+
resolveDefinePropsIface(path9, ctx);
|
|
3340
3416
|
} else if (name === MACRO_API_NAMES.emits) {
|
|
3341
|
-
resolveDefineEmitsIface(
|
|
3417
|
+
resolveDefineEmitsIface(path9, ctx);
|
|
3342
3418
|
} else if (name === MACRO_API_NAMES.slots) {
|
|
3343
|
-
resolveDefineSlotsIface(
|
|
3419
|
+
resolveDefineSlotsIface(path9, ctx);
|
|
3344
3420
|
}
|
|
3345
3421
|
}
|
|
3346
3422
|
removePath();
|
|
@@ -3356,9 +3432,9 @@ function resolveCompIProps(ctx, ast) {
|
|
|
3356
3432
|
}
|
|
3357
3433
|
const n = ctx.compName || "Comp";
|
|
3358
3434
|
const ns = `I${camelCase(capitalize(n))}Props`;
|
|
3359
|
-
const typeNode =
|
|
3360
|
-
const typeAliasDecl =
|
|
3361
|
-
const exportDecl =
|
|
3435
|
+
const typeNode = t30.tsIntersectionType(tsTypes);
|
|
3436
|
+
const typeAliasDecl = t30.tsTypeAliasDeclaration(t30.identifier(ns), null, typeNode);
|
|
3437
|
+
const exportDecl = t30.exportNamedDeclaration(typeAliasDecl);
|
|
3362
3438
|
propsTSIface.name = ns;
|
|
3363
3439
|
const scriptIR = getScriptIR(ctx);
|
|
3364
3440
|
scriptIR.exports.push(exportDecl);
|
|
@@ -3366,17 +3442,17 @@ function resolveCompIProps(ctx, ast) {
|
|
|
3366
3442
|
}
|
|
3367
3443
|
|
|
3368
3444
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-analysis-only-adapter.ts
|
|
3369
|
-
import * as
|
|
3445
|
+
import * as t32 from "@babel/types";
|
|
3370
3446
|
|
|
3371
3447
|
// src/core/transform/sfc/script/shared/dependency-analyzer.ts
|
|
3372
3448
|
import { traverse as traverse2 } from "@babel/core";
|
|
3373
|
-
import * as
|
|
3449
|
+
import * as t31 from "@babel/types";
|
|
3374
3450
|
var TRACE_MAX_DEPTH = 20;
|
|
3375
3451
|
function analyzeDeps(node, ctx, parentPath) {
|
|
3376
3452
|
if (!parentPath) {
|
|
3377
|
-
return
|
|
3453
|
+
return t31.arrayExpression([]);
|
|
3378
3454
|
}
|
|
3379
|
-
const isFnExpr =
|
|
3455
|
+
const isFnExpr = t31.isArrowFunctionExpression(node) || t31.isFunctionExpression(node);
|
|
3380
3456
|
const analyzeTarget = isFnExpr ? node.body : node;
|
|
3381
3457
|
const bindingLocalBoundary = isFnExpr ? node : analyzeTarget;
|
|
3382
3458
|
const reactiveStateApis = getReactiveStateApis();
|
|
@@ -3385,15 +3461,27 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3385
3461
|
function addDependency(exp) {
|
|
3386
3462
|
deps.set(getDependencyKey(exp), exp);
|
|
3387
3463
|
}
|
|
3464
|
+
const analyzeTargetPath = parentPath && parentPath.node === analyzeTarget ? parentPath : null;
|
|
3465
|
+
if (analyzeTargetPath) {
|
|
3466
|
+
if (t31.isMemberExpression(analyzeTarget) || t31.isOptionalMemberExpression(analyzeTarget)) {
|
|
3467
|
+
const rootId = findRootIdentifier(analyzeTarget);
|
|
3468
|
+
if (rootId) {
|
|
3469
|
+
tryAddDependency(analyzeTargetPath, rootId.name, analyzeTargetPath.scope);
|
|
3470
|
+
processedIdentifiers.add(rootId);
|
|
3471
|
+
}
|
|
3472
|
+
} else if (t31.isIdentifier(analyzeTarget)) {
|
|
3473
|
+
tryAddDependency(analyzeTargetPath, analyzeTarget.name, analyzeTargetPath.scope);
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3388
3476
|
traverse2(
|
|
3389
3477
|
analyzeTarget,
|
|
3390
3478
|
{
|
|
3391
3479
|
"MemberExpression|OptionalMemberExpression"(memberPath) {
|
|
3392
|
-
const
|
|
3393
|
-
if (isNestedMemberObject(
|
|
3394
|
-
const rootId = findRootIdentifier(
|
|
3480
|
+
const path9 = memberPath;
|
|
3481
|
+
if (isNestedMemberObject(path9)) return;
|
|
3482
|
+
const rootId = findRootIdentifier(path9.node);
|
|
3395
3483
|
if (!rootId) return;
|
|
3396
|
-
tryAddDependency(
|
|
3484
|
+
tryAddDependency(path9, rootId.name, path9.scope);
|
|
3397
3485
|
processedIdentifiers.add(rootId);
|
|
3398
3486
|
},
|
|
3399
3487
|
Identifier(idPath) {
|
|
@@ -3425,43 +3513,62 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3425
3513
|
}
|
|
3426
3514
|
const sourcedExpression = traceBindingSource(binding, /* @__PURE__ */ new Set(), TRACE_MAX_DEPTH);
|
|
3427
3515
|
if (sourcedExpression) {
|
|
3428
|
-
|
|
3516
|
+
const normalizedSource = normalizeSourcedDependency(sourcedExpression);
|
|
3517
|
+
if (normalizedSource) {
|
|
3518
|
+
addDependency(normalizedSource);
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
function normalizeDependencyExpr(path9, rootName) {
|
|
3523
|
+
if (t31.isIdentifier(path9.node)) {
|
|
3524
|
+
return t31.identifier(path9.node.name);
|
|
3429
3525
|
}
|
|
3526
|
+
if (t31.isMemberExpression(path9.node) || t31.isOptionalMemberExpression(path9.node)) {
|
|
3527
|
+
const normalizedExp = normalizeMemberForCallSite(path9, path9.node);
|
|
3528
|
+
const safeExp = t31.isMemberExpression(normalizedExp) || t31.isOptionalMemberExpression(normalizedExp) ? ensureOptionalForMemberChain(normalizedExp) : normalizedExp;
|
|
3529
|
+
if (isReactValidDependencyExpr(safeExp)) {
|
|
3530
|
+
return t31.cloneNode(safeExp, true);
|
|
3531
|
+
}
|
|
3532
|
+
return t31.identifier(rootName);
|
|
3533
|
+
}
|
|
3534
|
+
return null;
|
|
3430
3535
|
}
|
|
3431
|
-
function
|
|
3432
|
-
if (
|
|
3433
|
-
return
|
|
3536
|
+
function normalizeSourcedDependency(exp) {
|
|
3537
|
+
if (t31.isIdentifier(exp)) {
|
|
3538
|
+
return t31.identifier(exp.name);
|
|
3434
3539
|
}
|
|
3435
|
-
if (
|
|
3436
|
-
const
|
|
3437
|
-
if (
|
|
3438
|
-
|
|
3540
|
+
if (t31.isMemberExpression(exp) || t31.isOptionalMemberExpression(exp)) {
|
|
3541
|
+
const root = findRootIdentifier(exp);
|
|
3542
|
+
if (!root) return null;
|
|
3543
|
+
const safeExp = t31.isMemberExpression(exp) || t31.isOptionalMemberExpression(exp) ? ensureOptionalForMemberChain(exp) : exp;
|
|
3544
|
+
if (isReactValidDependencyExpr(safeExp)) {
|
|
3545
|
+
return t31.cloneNode(safeExp, true);
|
|
3439
3546
|
}
|
|
3440
|
-
return
|
|
3547
|
+
return t31.identifier(root.name);
|
|
3441
3548
|
}
|
|
3442
3549
|
return null;
|
|
3443
3550
|
}
|
|
3444
3551
|
function isReactValidDependencyExpr(node2) {
|
|
3445
|
-
if (
|
|
3552
|
+
if (t31.isIdentifier(node2)) {
|
|
3446
3553
|
return true;
|
|
3447
3554
|
}
|
|
3448
|
-
if (
|
|
3555
|
+
if (t31.isMemberExpression(node2) || t31.isOptionalMemberExpression(node2)) {
|
|
3449
3556
|
return isStaticMemberChain(node2);
|
|
3450
3557
|
}
|
|
3451
3558
|
return false;
|
|
3452
3559
|
}
|
|
3453
3560
|
function isStaticMemberChain(node2) {
|
|
3454
3561
|
let current = node2;
|
|
3455
|
-
while (
|
|
3456
|
-
if (!current.computed && !
|
|
3562
|
+
while (t31.isMemberExpression(current) || t31.isOptionalMemberExpression(current)) {
|
|
3563
|
+
if (!current.computed && !t31.isIdentifier(current.property)) {
|
|
3457
3564
|
return false;
|
|
3458
3565
|
}
|
|
3459
|
-
if (current.computed && !
|
|
3566
|
+
if (current.computed && !t31.isStringLiteral(current.property) && !t31.isNumericLiteral(current.property)) {
|
|
3460
3567
|
return false;
|
|
3461
3568
|
}
|
|
3462
3569
|
current = current.object;
|
|
3463
3570
|
}
|
|
3464
|
-
return
|
|
3571
|
+
return t31.isIdentifier(current);
|
|
3465
3572
|
}
|
|
3466
3573
|
function isBindingDeclaredInsideBoundary(binding, boundary) {
|
|
3467
3574
|
let current = binding.path;
|
|
@@ -3473,39 +3580,50 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3473
3580
|
}
|
|
3474
3581
|
return false;
|
|
3475
3582
|
}
|
|
3476
|
-
function normalizeMemberForCallSite(
|
|
3477
|
-
const parent =
|
|
3583
|
+
function normalizeMemberForCallSite(path9, node2) {
|
|
3584
|
+
const parent = path9.parentPath;
|
|
3478
3585
|
const isDirectCallee = !!parent && (parent.isCallExpression() && parent.node.callee === node2 || parent.isOptionalCallExpression() && parent.node.callee === node2);
|
|
3479
3586
|
if (!isDirectCallee) {
|
|
3480
3587
|
return node2;
|
|
3481
3588
|
}
|
|
3482
|
-
if (!
|
|
3589
|
+
if (!t31.isExpression(node2.object)) {
|
|
3483
3590
|
return node2;
|
|
3484
3591
|
}
|
|
3485
3592
|
return node2.object;
|
|
3486
3593
|
}
|
|
3594
|
+
function ensureOptionalForMemberChain(node2) {
|
|
3595
|
+
if (!hasTrailingMemberAccess(node2)) {
|
|
3596
|
+
return node2;
|
|
3597
|
+
}
|
|
3598
|
+
if (t31.isOptionalMemberExpression(node2) && node2.optional) {
|
|
3599
|
+
return node2;
|
|
3600
|
+
}
|
|
3601
|
+
const object = t31.cloneNode(node2.object, true);
|
|
3602
|
+
const property = t31.cloneNode(node2.property, true);
|
|
3603
|
+
return t31.optionalMemberExpression(object, property, node2.computed, true);
|
|
3604
|
+
}
|
|
3605
|
+
function hasTrailingMemberAccess(node2) {
|
|
3606
|
+
return t31.isMemberExpression(node2.object) || t31.isOptionalMemberExpression(node2.object);
|
|
3607
|
+
}
|
|
3487
3608
|
function isEligibleBindingSource(binding) {
|
|
3488
3609
|
if (binding.kind === "param") {
|
|
3489
3610
|
return false;
|
|
3490
3611
|
}
|
|
3491
3612
|
const bindingPath = binding.path;
|
|
3492
3613
|
const declaratorPath = getVariableDeclaratorPath(bindingPath);
|
|
3493
|
-
const isImportBinding = bindingPath.isImportSpecifier() || bindingPath.isImportDefaultSpecifier() || bindingPath.isImportNamespaceSpecifier();
|
|
3494
3614
|
const isReactiveVarBinding = !!declaratorPath && isReactiveBinding(declaratorPath.node);
|
|
3495
3615
|
const nodeInit = declaratorPath?.node.init;
|
|
3496
|
-
const isReactiveApiCallVarBinding = !!declaratorPath &&
|
|
3497
|
-
const isHookCallVarBinding = !!declaratorPath &&
|
|
3498
|
-
const isFunctionBinding = bindingPath.isFunctionDeclaration() || !!declaratorPath && !!nodeInit && (
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
}
|
|
3502
|
-
return isImportBinding || isReactiveVarBinding || isReactiveApiCallVarBinding || isHookCallVarBinding || isFunctionBinding;
|
|
3616
|
+
const isReactiveApiCallVarBinding = !!declaratorPath && t31.isCallExpression(nodeInit) && t31.isIdentifier(nodeInit.callee) && reactiveStateApis.has(nodeInit.callee.name);
|
|
3617
|
+
const isHookCallVarBinding = !!declaratorPath && t31.isCallExpression(nodeInit) && isHookLikeCallee(nodeInit.callee);
|
|
3618
|
+
const isFunctionBinding = bindingPath.isFunctionDeclaration() || !!declaratorPath && !!nodeInit && (t31.isArrowFunctionExpression(nodeInit) || t31.isFunctionExpression(nodeInit));
|
|
3619
|
+
const isReactiveFunctionBinding = isFunctionBinding && (isReactiveBinding(declaratorPath?.node) || isReactiveBinding(bindingPath.node));
|
|
3620
|
+
return isReactiveVarBinding || isReactiveApiCallVarBinding || isHookCallVarBinding || isReactiveFunctionBinding;
|
|
3503
3621
|
}
|
|
3504
3622
|
function isHookLikeCallee(callee) {
|
|
3505
|
-
if (
|
|
3623
|
+
if (t31.isIdentifier(callee)) {
|
|
3506
3624
|
return callee.name.startsWith("use");
|
|
3507
3625
|
}
|
|
3508
|
-
if (
|
|
3626
|
+
if (t31.isMemberExpression(callee) && !callee.computed && t31.isIdentifier(callee.property)) {
|
|
3509
3627
|
return callee.property.name.startsWith("use");
|
|
3510
3628
|
}
|
|
3511
3629
|
return false;
|
|
@@ -3521,7 +3639,7 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3521
3639
|
}
|
|
3522
3640
|
function isExpressionSourcedFromEligibleBinding(exp, scope, seen, depth) {
|
|
3523
3641
|
if (depth <= 0) return null;
|
|
3524
|
-
if (
|
|
3642
|
+
if (t31.isIdentifier(exp)) {
|
|
3525
3643
|
const sourceBinding = scope.getBinding(exp.name);
|
|
3526
3644
|
if (!sourceBinding) return null;
|
|
3527
3645
|
if (isEligibleBindingSource(sourceBinding)) {
|
|
@@ -3529,13 +3647,13 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3529
3647
|
}
|
|
3530
3648
|
return traceBindingSource(sourceBinding, seen, depth - 1);
|
|
3531
3649
|
}
|
|
3532
|
-
if (
|
|
3650
|
+
if (t31.isMemberExpression(exp) || t31.isOptionalMemberExpression(exp)) {
|
|
3533
3651
|
const root = findRootIdentifier(exp);
|
|
3534
3652
|
if (!root) return null;
|
|
3535
3653
|
const sourceBinding = scope.getBinding(root.name);
|
|
3536
3654
|
if (!sourceBinding) return null;
|
|
3537
3655
|
if (isEligibleBindingSource(sourceBinding)) {
|
|
3538
|
-
return
|
|
3656
|
+
return t31.cloneNode(exp);
|
|
3539
3657
|
}
|
|
3540
3658
|
const sourcedRoot = traceBindingSource(sourceBinding, seen, depth - 1);
|
|
3541
3659
|
if (sourcedRoot) {
|
|
@@ -3543,17 +3661,17 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3543
3661
|
if (rebuilt) {
|
|
3544
3662
|
return rebuilt;
|
|
3545
3663
|
}
|
|
3546
|
-
return
|
|
3664
|
+
return t31.cloneNode(sourcedRoot, true);
|
|
3547
3665
|
}
|
|
3548
3666
|
}
|
|
3549
3667
|
return null;
|
|
3550
3668
|
}
|
|
3551
3669
|
function rebuildMemberWithNewRoot(node2, nextRoot) {
|
|
3552
3670
|
const replacedObject = (() => {
|
|
3553
|
-
if (
|
|
3554
|
-
return
|
|
3671
|
+
if (t31.isIdentifier(node2.object)) {
|
|
3672
|
+
return t31.cloneNode(nextRoot, true);
|
|
3555
3673
|
}
|
|
3556
|
-
if (
|
|
3674
|
+
if (t31.isMemberExpression(node2.object) || t31.isOptionalMemberExpression(node2.object)) {
|
|
3557
3675
|
return rebuildMemberWithNewRoot(node2.object, nextRoot);
|
|
3558
3676
|
}
|
|
3559
3677
|
return null;
|
|
@@ -3561,45 +3679,45 @@ function analyzeDeps(node, ctx, parentPath) {
|
|
|
3561
3679
|
if (!replacedObject) {
|
|
3562
3680
|
return null;
|
|
3563
3681
|
}
|
|
3564
|
-
const property =
|
|
3565
|
-
if (
|
|
3566
|
-
return
|
|
3682
|
+
const property = t31.cloneNode(node2.property, true);
|
|
3683
|
+
if (t31.isMemberExpression(node2)) {
|
|
3684
|
+
return t31.memberExpression(
|
|
3567
3685
|
replacedObject,
|
|
3568
3686
|
property,
|
|
3569
3687
|
node2.computed
|
|
3570
3688
|
);
|
|
3571
3689
|
}
|
|
3572
|
-
return
|
|
3690
|
+
return t31.optionalMemberExpression(
|
|
3573
3691
|
replacedObject,
|
|
3574
3692
|
property,
|
|
3575
3693
|
node2.computed,
|
|
3576
3694
|
node2.optional
|
|
3577
3695
|
);
|
|
3578
3696
|
}
|
|
3579
|
-
return
|
|
3697
|
+
return t31.arrayExpression(Array.from(deps.values()));
|
|
3580
3698
|
}
|
|
3581
3699
|
function getDependencyKey(exp) {
|
|
3582
|
-
if (
|
|
3700
|
+
if (t31.isIdentifier(exp)) {
|
|
3583
3701
|
return exp.name;
|
|
3584
3702
|
}
|
|
3585
|
-
if (
|
|
3703
|
+
if (t31.isMemberExpression(exp) || t31.isOptionalMemberExpression(exp)) {
|
|
3586
3704
|
const objectKey = getDependencyKey(exp.object);
|
|
3587
3705
|
const opt = exp.optional ? "?" : "";
|
|
3588
|
-
if (!exp.computed &&
|
|
3706
|
+
if (!exp.computed && t31.isIdentifier(exp.property)) {
|
|
3589
3707
|
return `${objectKey}${opt}.${exp.property.name}`;
|
|
3590
3708
|
}
|
|
3591
|
-
if (
|
|
3709
|
+
if (t31.isStringLiteral(exp.property) || t31.isNumericLiteral(exp.property)) {
|
|
3592
3710
|
return `${objectKey}${opt}[${JSON.stringify(exp.property.value)}]`;
|
|
3593
3711
|
}
|
|
3594
3712
|
return `${objectKey}${opt}[*]`;
|
|
3595
3713
|
}
|
|
3596
3714
|
return exp.type;
|
|
3597
3715
|
}
|
|
3598
|
-
function isNestedMemberObject(
|
|
3599
|
-
const parent =
|
|
3716
|
+
function isNestedMemberObject(path9) {
|
|
3717
|
+
const parent = path9.parentPath;
|
|
3600
3718
|
if (!parent) return false;
|
|
3601
3719
|
if (parent.isMemberExpression() || parent.isOptionalMemberExpression()) {
|
|
3602
|
-
return parent.node.object ===
|
|
3720
|
+
return parent.node.object === path9.node;
|
|
3603
3721
|
}
|
|
3604
3722
|
return false;
|
|
3605
3723
|
}
|
|
@@ -3607,27 +3725,19 @@ function isReactiveBinding(node) {
|
|
|
3607
3725
|
if (!node) return false;
|
|
3608
3726
|
return !!getScriptNodeMeta(node)?.is_reactive;
|
|
3609
3727
|
}
|
|
3610
|
-
function markAsAnalyzed(node, flag = true) {
|
|
3611
|
-
const analyzed = getIsAnalyzed(node);
|
|
3612
|
-
if (analyzed) return;
|
|
3613
|
-
setScriptNodeMeta(node, { is_deps_analyzed: flag });
|
|
3614
|
-
}
|
|
3615
|
-
function getIsAnalyzed(node) {
|
|
3616
|
-
return getScriptNodeMeta(node)?.is_deps_analyzed;
|
|
3617
|
-
}
|
|
3618
3728
|
|
|
3619
3729
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-analysis-only-adapter.ts
|
|
3620
3730
|
function resolveAnalysisOnlyAdapter(ctx) {
|
|
3621
3731
|
return {
|
|
3622
|
-
"CallExpression|Identifier"(
|
|
3623
|
-
const node =
|
|
3732
|
+
"CallExpression|Identifier"(path9) {
|
|
3733
|
+
const node = path9.node;
|
|
3624
3734
|
const apiName = getApiName(node);
|
|
3625
3735
|
const adapter = ADAPTER_RULES.runtime[apiName];
|
|
3626
3736
|
if (!adapter || adapter.type !== "analyzed-deps") {
|
|
3627
3737
|
return;
|
|
3628
3738
|
}
|
|
3629
|
-
if (
|
|
3630
|
-
resolveCallNode(
|
|
3739
|
+
if (t32.isCallExpression(node)) {
|
|
3740
|
+
resolveCallNode(path9, adapter, ctx);
|
|
3631
3741
|
} else {
|
|
3632
3742
|
replaceIdName(node, adapter.target);
|
|
3633
3743
|
}
|
|
@@ -3636,24 +3746,24 @@ function resolveAnalysisOnlyAdapter(ctx) {
|
|
|
3636
3746
|
};
|
|
3637
3747
|
}
|
|
3638
3748
|
function getApiName(node) {
|
|
3639
|
-
const isCallNode =
|
|
3749
|
+
const isCallNode = t32.isCallExpression(node);
|
|
3640
3750
|
let apiName = "";
|
|
3641
|
-
if (
|
|
3751
|
+
if (t32.isIdentifier(node)) {
|
|
3642
3752
|
apiName = node.name;
|
|
3643
|
-
} else if (isCallNode &&
|
|
3753
|
+
} else if (isCallNode && t32.isIdentifier(node.callee)) {
|
|
3644
3754
|
apiName = node.callee.name;
|
|
3645
3755
|
}
|
|
3646
3756
|
return apiName;
|
|
3647
3757
|
}
|
|
3648
|
-
function resolveCallNode(
|
|
3649
|
-
const { node } =
|
|
3758
|
+
function resolveCallNode(path9, adapter, ctx) {
|
|
3759
|
+
const { node } = path9;
|
|
3650
3760
|
const { arguments: args } = node;
|
|
3651
3761
|
if (!args.length) return;
|
|
3652
3762
|
const fn = args[0];
|
|
3653
|
-
if (!
|
|
3763
|
+
if (!t32.isArrowFunctionExpression(fn) && !t32.isFunctionExpression(fn)) {
|
|
3654
3764
|
return;
|
|
3655
3765
|
}
|
|
3656
|
-
const fnPath =
|
|
3766
|
+
const fnPath = path9.get("arguments")[0];
|
|
3657
3767
|
const deps = analyzeDeps(fn, ctx, fnPath);
|
|
3658
3768
|
args.push(deps);
|
|
3659
3769
|
replaceCallName(node, adapter.target);
|
|
@@ -3663,41 +3773,24 @@ function resolveCallNode(path7, adapter, ctx) {
|
|
|
3663
3773
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-arrow-deps.ts
|
|
3664
3774
|
function resolveArrowFnDeps(ctx, ast) {
|
|
3665
3775
|
return {
|
|
3666
|
-
ArrowFunctionExpression(
|
|
3667
|
-
const { node, parentPath } =
|
|
3668
|
-
if (isSkip(
|
|
3776
|
+
ArrowFunctionExpression(path9) {
|
|
3777
|
+
const { node, parentPath } = path9;
|
|
3778
|
+
if (isSkip(path9) || !atComponentOrHookRoot(parentPath, ast.program)) {
|
|
3669
3779
|
return;
|
|
3670
3780
|
}
|
|
3671
|
-
const deps = analyzeDeps(node, ctx,
|
|
3781
|
+
const deps = analyzeDeps(node, ctx, path9);
|
|
3672
3782
|
if (!deps.elements.length) return;
|
|
3673
3783
|
const newNode = createUseCallback(node, deps);
|
|
3674
|
-
const declaratorPath = getVariableDeclaratorPath(
|
|
3675
|
-
markAsAnalyzed(newNode.arguments[0]);
|
|
3784
|
+
const declaratorPath = getVariableDeclaratorPath(path9);
|
|
3676
3785
|
recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.useCallback);
|
|
3677
3786
|
setScriptNodeMeta(declaratorPath?.node, { is_reactive: true, reactive_type: "indirect" });
|
|
3678
|
-
|
|
3679
|
-
}
|
|
3680
|
-
};
|
|
3681
|
-
}
|
|
3682
|
-
function resolveUnanalyzedArrow(ctx) {
|
|
3683
|
-
return {
|
|
3684
|
-
ArrowFunctionExpression(path7) {
|
|
3685
|
-
const { node } = path7;
|
|
3686
|
-
const analyzed = getIsAnalyzed(node);
|
|
3687
|
-
if (typeof analyzed === "undefined" || analyzed) return;
|
|
3688
|
-
const newNode = createUseCallback(node);
|
|
3689
|
-
const declaratorPath = getVariableDeclaratorPath(path7);
|
|
3690
|
-
if (declaratorPath?.node) {
|
|
3691
|
-
setScriptNodeMeta(declaratorPath.node, { is_reactive: true, reactive_type: "indirect" });
|
|
3692
|
-
}
|
|
3693
|
-
markAsAnalyzed(newNode.arguments[0]);
|
|
3694
|
-
path7.replaceWith(newNode);
|
|
3787
|
+
path9.replaceWith(newNode);
|
|
3695
3788
|
}
|
|
3696
3789
|
};
|
|
3697
3790
|
}
|
|
3698
|
-
function isSkip(
|
|
3699
|
-
const { parentPath } =
|
|
3700
|
-
const isVariableDecl = () => getVariableDeclaratorPath(
|
|
3791
|
+
function isSkip(path9) {
|
|
3792
|
+
const { parentPath } = path9;
|
|
3793
|
+
const isVariableDecl = () => getVariableDeclaratorPath(path9) !== null;
|
|
3701
3794
|
const isReturnFunc = () => !isVariableDecl() && parentPath.isReturnStatement();
|
|
3702
3795
|
const isCallback = () => {
|
|
3703
3796
|
if (!parentPath) {
|
|
@@ -3706,12 +3799,12 @@ function isSkip(path7) {
|
|
|
3706
3799
|
if (parentPath.isCallExpression()) {
|
|
3707
3800
|
const callExpressionPath = parentPath;
|
|
3708
3801
|
const args = callExpressionPath.node.arguments;
|
|
3709
|
-
return args.some((arg) => arg ===
|
|
3802
|
+
return args.some((arg) => arg === path9.node);
|
|
3710
3803
|
}
|
|
3711
3804
|
if (parentPath.isArrayExpression()) {
|
|
3712
3805
|
const arrayExpressionPath = parentPath;
|
|
3713
3806
|
const elements = arrayExpressionPath.node.elements;
|
|
3714
|
-
return elements.some((element) => element ===
|
|
3807
|
+
return elements.some((element) => element === path9.node);
|
|
3715
3808
|
}
|
|
3716
3809
|
return false;
|
|
3717
3810
|
};
|
|
@@ -3732,16 +3825,16 @@ function isSkip(path7) {
|
|
|
3732
3825
|
}
|
|
3733
3826
|
|
|
3734
3827
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-element-ref.ts
|
|
3735
|
-
import * as
|
|
3828
|
+
import * as t33 from "@babel/types";
|
|
3736
3829
|
function resolveElementRef(ctx) {
|
|
3737
3830
|
return {
|
|
3738
|
-
CallExpression(
|
|
3831
|
+
CallExpression(path9) {
|
|
3739
3832
|
const {
|
|
3740
3833
|
inputType,
|
|
3741
3834
|
templateData: { refBindings }
|
|
3742
3835
|
} = ctx;
|
|
3743
3836
|
if (inputType !== "sfc") return;
|
|
3744
|
-
const { node } =
|
|
3837
|
+
const { node } = path9;
|
|
3745
3838
|
const isUseTemplateRef = isCalleeNamed(node, VUE_API_MAP.useTemplateRef);
|
|
3746
3839
|
const isCompRefBindings = Object.keys(refBindings.componentRefs).length > 0 && isCalleeNamed(node, VUE_API_MAP.ref);
|
|
3747
3840
|
const shouldProcess = isUseTemplateRef || isCompRefBindings;
|
|
@@ -3749,31 +3842,31 @@ function resolveElementRef(ctx) {
|
|
|
3749
3842
|
return;
|
|
3750
3843
|
}
|
|
3751
3844
|
if (isCompRefBindings) {
|
|
3752
|
-
const varDeclaratorPath = getVariableDeclaratorPath(
|
|
3753
|
-
if (!
|
|
3845
|
+
const varDeclaratorPath = getVariableDeclaratorPath(path9)?.node;
|
|
3846
|
+
if (!t33.isIdentifier(varDeclaratorPath?.id)) {
|
|
3754
3847
|
return;
|
|
3755
3848
|
}
|
|
3756
3849
|
const varName = varDeclaratorPath.id.name;
|
|
3757
3850
|
const compRef = refBindings.componentRefs[varName];
|
|
3758
3851
|
if (!compRef) return;
|
|
3759
3852
|
}
|
|
3760
|
-
node.arguments[0] =
|
|
3761
|
-
resolveTypeParameters(ctx,
|
|
3853
|
+
node.arguments[0] = t33.identifier("null");
|
|
3854
|
+
resolveTypeParameters(ctx, path9);
|
|
3762
3855
|
replaceCallName(node, REACT_API_MAP.useRef);
|
|
3763
3856
|
recordImport(ctx, PACKAGE_NAME.react, REACT_API_MAP.useRef);
|
|
3764
3857
|
},
|
|
3765
|
-
MemberExpression(
|
|
3766
|
-
resolveRefValueToCurrent(
|
|
3858
|
+
MemberExpression(path9) {
|
|
3859
|
+
resolveRefValueToCurrent(path9);
|
|
3767
3860
|
}
|
|
3768
3861
|
};
|
|
3769
3862
|
}
|
|
3770
|
-
function resolveTypeParameters(ctx,
|
|
3863
|
+
function resolveTypeParameters(ctx, path9) {
|
|
3771
3864
|
const {
|
|
3772
3865
|
templateData: { refBindings },
|
|
3773
3866
|
scriptData
|
|
3774
3867
|
} = ctx;
|
|
3775
|
-
const { node } =
|
|
3776
|
-
const varDeclaratorNode = getVariableDeclaratorPath(
|
|
3868
|
+
const { node } = path9;
|
|
3869
|
+
const varDeclaratorNode = getVariableDeclaratorPath(path9)?.node;
|
|
3777
3870
|
if (!scriptData.lang.startsWith("ts") || !varDeclaratorNode) {
|
|
3778
3871
|
return;
|
|
3779
3872
|
}
|
|
@@ -3782,45 +3875,49 @@ function resolveTypeParameters(ctx, path7) {
|
|
|
3782
3875
|
const compBindingMeta = refBindings.componentRefs[idName];
|
|
3783
3876
|
if (!node.typeParameters && (domBindingMeta || compBindingMeta)) {
|
|
3784
3877
|
const type = compBindingMeta ? "any" : domBindingMeta.htmlType;
|
|
3785
|
-
node.typeParameters =
|
|
3878
|
+
node.typeParameters = t33.tsTypeParameterInstantiation([t33.tsTypeReference(t33.identifier(type))]);
|
|
3786
3879
|
}
|
|
3787
3880
|
}
|
|
3788
|
-
function resolveRefValueToCurrent(
|
|
3789
|
-
const { node } =
|
|
3790
|
-
if (node.computed || !
|
|
3881
|
+
function resolveRefValueToCurrent(path9) {
|
|
3882
|
+
const { node } = path9;
|
|
3883
|
+
if (node.computed || !t33.isIdentifier(node.property) || node.property.name !== "value") {
|
|
3791
3884
|
return;
|
|
3792
3885
|
}
|
|
3793
|
-
const rootPath = findRootVariablePath(
|
|
3794
|
-
if (!rootPath?.node || !
|
|
3886
|
+
const rootPath = findRootVariablePath(path9);
|
|
3887
|
+
if (!rootPath?.node || !t33.isCallExpression(rootPath.node.init) || !isCalleeNamed(rootPath.node.init, REACT_API_MAP.useRef)) {
|
|
3795
3888
|
return;
|
|
3796
3889
|
}
|
|
3797
3890
|
const rootId = findRootIdentifier(node);
|
|
3798
|
-
if (!
|
|
3891
|
+
if (!t33.isIdentifier(node.object) || node.object.name !== rootId?.name) {
|
|
3799
3892
|
return;
|
|
3800
3893
|
}
|
|
3801
3894
|
node.property.name = "current";
|
|
3802
3895
|
}
|
|
3803
3896
|
|
|
3804
3897
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-expression-memo.ts
|
|
3805
|
-
import * as
|
|
3898
|
+
import * as t34 from "@babel/types";
|
|
3806
3899
|
function resolveExprMemo(ctx, ast) {
|
|
3807
3900
|
const isScriptFile = ctx.inputType !== "sfc";
|
|
3808
3901
|
return {
|
|
3809
|
-
VariableDeclarator(
|
|
3810
|
-
const { node } =
|
|
3902
|
+
VariableDeclarator(path9) {
|
|
3903
|
+
const { node } = path9;
|
|
3811
3904
|
const { init } = node;
|
|
3812
|
-
if (!init) return;
|
|
3813
3905
|
const shouldMemo = () => {
|
|
3814
|
-
if (!
|
|
3906
|
+
if (!init) return false;
|
|
3907
|
+
if (!atComponentOrHookRoot(path9, ast.program, isScriptFile)) {
|
|
3908
|
+
return false;
|
|
3909
|
+
}
|
|
3910
|
+
if (!t34.isVariableDeclaration(path9.parent) || path9.parent.kind !== "const") {
|
|
3815
3911
|
return false;
|
|
3816
3912
|
}
|
|
3817
|
-
if (
|
|
3913
|
+
if (t34.isFunction(init)) return false;
|
|
3914
|
+
if (t34.isCallExpression(init) && t34.isIdentifier(init.callee) && init.callee.name.startsWith("use")) {
|
|
3818
3915
|
return false;
|
|
3819
3916
|
}
|
|
3820
3917
|
return true;
|
|
3821
3918
|
};
|
|
3822
3919
|
if (!shouldMemo()) return;
|
|
3823
|
-
const initPath =
|
|
3920
|
+
const initPath = path9.get("init");
|
|
3824
3921
|
if (!initPath.isExpression()) return;
|
|
3825
3922
|
const deps = analyzeDeps(initPath.node, ctx, initPath);
|
|
3826
3923
|
if (!deps.elements.length) return;
|
|
@@ -3832,13 +3929,13 @@ function resolveExprMemo(ctx, ast) {
|
|
|
3832
3929
|
}
|
|
3833
3930
|
|
|
3834
3931
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-lint-rules.ts
|
|
3835
|
-
import * as
|
|
3932
|
+
import * as t35 from "@babel/types";
|
|
3836
3933
|
function resolveLintRules(ctx, ast) {
|
|
3837
3934
|
const inScriptFile = ctx.inputType !== "sfc";
|
|
3838
3935
|
return {
|
|
3839
|
-
CallExpression(
|
|
3840
|
-
const { node, parentPath } =
|
|
3841
|
-
if (!
|
|
3936
|
+
CallExpression(path9) {
|
|
3937
|
+
const { node, parentPath } = path9;
|
|
3938
|
+
if (!t35.isIdentifier(node.callee)) return;
|
|
3842
3939
|
const { name: callName } = node.callee;
|
|
3843
3940
|
const addLog = (t41) => {
|
|
3844
3941
|
logger.error(t41, {
|
|
@@ -3856,7 +3953,7 @@ function resolveLintRules(ctx, ast) {
|
|
|
3856
3953
|
);
|
|
3857
3954
|
return;
|
|
3858
3955
|
}
|
|
3859
|
-
if (!atComponentOrHookRoot(
|
|
3956
|
+
if (!atComponentOrHookRoot(path9, ast.program)) {
|
|
3860
3957
|
addLog(
|
|
3861
3958
|
`The ${macro} must be defined at the top level of the component, not inside blocks or functions.`
|
|
3862
3959
|
);
|
|
@@ -3872,7 +3969,7 @@ function resolveLintRules(ctx, ast) {
|
|
|
3872
3969
|
};
|
|
3873
3970
|
const lintHooks = () => {
|
|
3874
3971
|
if (!callName.startsWith("use")) return;
|
|
3875
|
-
if (!atComponentOrHookRoot(
|
|
3972
|
+
if (!atComponentOrHookRoot(path9, ast.program, inScriptFile)) {
|
|
3876
3973
|
addLog(
|
|
3877
3974
|
`The ${callName} hook must be called at the top level, not inside loops, conditions, or nested functions.`
|
|
3878
3975
|
);
|
|
@@ -3886,12 +3983,12 @@ function resolveLintRules(ctx, ast) {
|
|
|
3886
3983
|
|
|
3887
3984
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-provide.ts
|
|
3888
3985
|
import { generate as generate3 } from "@babel/generator";
|
|
3889
|
-
import * as
|
|
3986
|
+
import * as t36 from "@babel/types";
|
|
3890
3987
|
function resolveProvide(ctx) {
|
|
3891
3988
|
if (ctx.inputType === "style") return {};
|
|
3892
3989
|
return {
|
|
3893
|
-
CallExpression(
|
|
3894
|
-
const { node } =
|
|
3990
|
+
CallExpression(path9) {
|
|
3991
|
+
const { node } = path9;
|
|
3895
3992
|
const providerTarget = ADAPTER_RULES.runtime[VUE_API_MAP.provide]?.target;
|
|
3896
3993
|
const isProvideCall = isCalleeNamed(node, VUE_API_MAP.provide) || providerTarget && isCalleeNamed(node, providerTarget);
|
|
3897
3994
|
if (!isProvideCall) return;
|
|
@@ -3901,7 +3998,7 @@ function resolveProvide(ctx) {
|
|
|
3901
3998
|
const adapter = ADAPTER_RULES.runtime[VUE_API_MAP.provide];
|
|
3902
3999
|
assignProviderValue(target, key, value);
|
|
3903
4000
|
recordImport(ctx, adapter.package, adapter.target);
|
|
3904
|
-
|
|
4001
|
+
path9.parentPath.remove();
|
|
3905
4002
|
}
|
|
3906
4003
|
};
|
|
3907
4004
|
}
|
|
@@ -3918,13 +4015,13 @@ function findOrCreateCtxProvider(root) {
|
|
|
3918
4015
|
function assignProviderValue(target, key, value) {
|
|
3919
4016
|
const getRawExp = (exp) => {
|
|
3920
4017
|
if (!exp) return "''";
|
|
3921
|
-
if (
|
|
4018
|
+
if (t36.isStringLiteral(exp)) {
|
|
3922
4019
|
return JSON.stringify(exp.value);
|
|
3923
4020
|
}
|
|
3924
|
-
if (
|
|
4021
|
+
if (t36.isNumericLiteral(exp)) {
|
|
3925
4022
|
return exp.value.toString();
|
|
3926
4023
|
}
|
|
3927
|
-
if (
|
|
4024
|
+
if (t36.isIdentifier(exp)) {
|
|
3928
4025
|
return exp.name;
|
|
3929
4026
|
}
|
|
3930
4027
|
try {
|
|
@@ -3940,16 +4037,16 @@ function assignProviderValue(target, key, value) {
|
|
|
3940
4037
|
}
|
|
3941
4038
|
|
|
3942
4039
|
// src/core/transform/sfc/script/syntax-processor/process/resolve-rename-adapter.ts
|
|
3943
|
-
import * as
|
|
4040
|
+
import * as t37 from "@babel/types";
|
|
3944
4041
|
function resolveRenameAdapter(ctx) {
|
|
3945
4042
|
return {
|
|
3946
|
-
"CallExpression|Identifier"(
|
|
3947
|
-
const node =
|
|
3948
|
-
const isCallNode =
|
|
4043
|
+
"CallExpression|Identifier"(path9) {
|
|
4044
|
+
const node = path9.node;
|
|
4045
|
+
const isCallNode = t37.isCallExpression(node);
|
|
3949
4046
|
let apiName = "";
|
|
3950
|
-
if (
|
|
4047
|
+
if (t37.isIdentifier(node)) {
|
|
3951
4048
|
apiName = node.name;
|
|
3952
|
-
} else if (isCallNode &&
|
|
4049
|
+
} else if (isCallNode && t37.isIdentifier(node.callee)) {
|
|
3953
4050
|
apiName = node.callee.name;
|
|
3954
4051
|
}
|
|
3955
4052
|
const runtimeAdapter = ADAPTER_RULES.runtime[apiName];
|
|
@@ -3960,7 +4057,7 @@ function resolveRenameAdapter(ctx) {
|
|
|
3960
4057
|
}
|
|
3961
4058
|
if (adapter.isTrackable) {
|
|
3962
4059
|
const reactiveType = getReactiveType(apiName);
|
|
3963
|
-
const declaratorPath = getVariableDeclaratorPath(
|
|
4060
|
+
const declaratorPath = getVariableDeclaratorPath(path9);
|
|
3964
4061
|
setScriptNodeMeta(declaratorPath?.node, {
|
|
3965
4062
|
is_reactive: true,
|
|
3966
4063
|
reactive_type: reactiveType
|
|
@@ -3999,10 +4096,11 @@ function processVueSyntax2(ast, ctx) {
|
|
|
3999
4096
|
// provide 需要在 rename 之前收集并移除原始调用,避免被重命名后失配
|
|
4000
4097
|
resolveProvide,
|
|
4001
4098
|
resolveRenameAdapter,
|
|
4099
|
+
// fix:在分析函数前分析可优化为 useMemo 的顶层变量声明,
|
|
4100
|
+
// 使得后续能够被函数依赖分析
|
|
4101
|
+
resolveExprMemo,
|
|
4002
4102
|
resolveArrowFnDeps,
|
|
4003
|
-
resolveUnanalyzedArrow,
|
|
4004
4103
|
resolveAnalysisOnlyAdapter,
|
|
4005
|
-
resolveExprMemo,
|
|
4006
4104
|
resolveLintRules
|
|
4007
4105
|
],
|
|
4008
4106
|
excludeBabel: [resolveTemplateSlotIface, resolveCompIProps]
|
|
@@ -4105,7 +4203,7 @@ import * as t39 from "@babel/types";
|
|
|
4105
4203
|
|
|
4106
4204
|
// src/shared/string-code-types.ts
|
|
4107
4205
|
import { parseExpression as parseExpression3 } from "@babel/parser";
|
|
4108
|
-
import * as
|
|
4206
|
+
import * as t38 from "@babel/types";
|
|
4109
4207
|
var strCodeTypes = {
|
|
4110
4208
|
isIdentifier: isIdentifier20,
|
|
4111
4209
|
isSimpleExpression,
|
|
@@ -4118,22 +4216,22 @@ function isSimpleExpression(code, excludeVar = false) {
|
|
|
4118
4216
|
} catch {
|
|
4119
4217
|
return false;
|
|
4120
4218
|
}
|
|
4121
|
-
if (
|
|
4219
|
+
if (t38.isLiteral(node)) {
|
|
4122
4220
|
return true;
|
|
4123
4221
|
}
|
|
4124
|
-
if (!excludeVar &&
|
|
4222
|
+
if (!excludeVar && t38.isIdentifier(node)) {
|
|
4125
4223
|
return true;
|
|
4126
4224
|
}
|
|
4127
|
-
if (
|
|
4128
|
-
return isSimpleExpression(node.object) &&
|
|
4225
|
+
if (t38.isMemberExpression(node)) {
|
|
4226
|
+
return isSimpleExpression(node.object) && t38.isIdentifier(node.property);
|
|
4129
4227
|
}
|
|
4130
|
-
if (
|
|
4228
|
+
if (t38.isObjectExpression(node) || t38.isArrayExpression(node)) {
|
|
4131
4229
|
return false;
|
|
4132
4230
|
}
|
|
4133
|
-
if (
|
|
4231
|
+
if (t38.isCallExpression(node) || t38.isAssignmentExpression(node)) {
|
|
4134
4232
|
return false;
|
|
4135
4233
|
}
|
|
4136
|
-
if (
|
|
4234
|
+
if (t38.isBinaryExpression(node) || t38.isUnaryExpression(node)) {
|
|
4137
4235
|
return true;
|
|
4138
4236
|
}
|
|
4139
4237
|
return false;
|
|
@@ -4141,7 +4239,7 @@ function isSimpleExpression(code, excludeVar = false) {
|
|
|
4141
4239
|
function isIdentifier20(code) {
|
|
4142
4240
|
try {
|
|
4143
4241
|
const node = parseExpression3(code);
|
|
4144
|
-
return
|
|
4242
|
+
return t38.isIdentifier(node);
|
|
4145
4243
|
} catch {
|
|
4146
4244
|
return false;
|
|
4147
4245
|
}
|
|
@@ -4149,69 +4247,12 @@ function isIdentifier20(code) {
|
|
|
4149
4247
|
function isStringLiteral12(code) {
|
|
4150
4248
|
try {
|
|
4151
4249
|
const node = parseExpression3(code);
|
|
4152
|
-
return
|
|
4250
|
+
return t38.isStringLiteral(node) || t38.isTemplateLiteral(node);
|
|
4153
4251
|
} catch {
|
|
4154
4252
|
return false;
|
|
4155
4253
|
}
|
|
4156
4254
|
}
|
|
4157
4255
|
|
|
4158
|
-
// src/core/transform/sfc/template/shared/resolve-string-expression/index.ts
|
|
4159
|
-
import * as t38 from "@babel/types";
|
|
4160
|
-
|
|
4161
|
-
// src/core/transform/sfc/template/shared/resolve-string-expression/special-expressions.ts
|
|
4162
|
-
function resolveSpecialExpressions(input, ctx) {
|
|
4163
|
-
input = resolveEmitsCalls(input, ctx);
|
|
4164
|
-
input = resolveRefVariable(input, ctx);
|
|
4165
|
-
return input;
|
|
4166
|
-
}
|
|
4167
|
-
function resolveEmitsCalls(input, ctx) {
|
|
4168
|
-
const result = matchEmitCalls(input, ctx);
|
|
4169
|
-
if (!result) return input;
|
|
4170
|
-
const [, , eventName, args] = result;
|
|
4171
|
-
const callee = eventName.split(/[:\-]/).map((part) => capitalize(camelCase(part))).join("");
|
|
4172
|
-
const event = args ? `on${callee}?.(${args})` : `on${callee}?.()`;
|
|
4173
|
-
return `${ctx.propField}?.${event}`;
|
|
4174
|
-
}
|
|
4175
|
-
function matchEmitCalls(input, ctx) {
|
|
4176
|
-
const { reactiveBindings } = ctx.templateData;
|
|
4177
|
-
const macroBinding = Object.values(reactiveBindings).find((b) => b.source === "defineEmits");
|
|
4178
|
-
if (!macroBinding) return null;
|
|
4179
|
-
const escapedName = macroBinding.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4180
|
-
const regex = new RegExp(
|
|
4181
|
-
`${escapedName}\\s*\\(\\s*(['"\`])([^\\1]*?)\\1\\s*(?:,\\s*(.*?))?\\s*\\)$`,
|
|
4182
|
-
// 可选的第二个参数
|
|
4183
|
-
"s"
|
|
4184
|
-
// s 标志让 . 匹配换行符
|
|
4185
|
-
);
|
|
4186
|
-
return input.trim().match(regex);
|
|
4187
|
-
}
|
|
4188
|
-
function resolveRefVariable(input, ctx) {
|
|
4189
|
-
const { reactiveBindings } = ctx.templateData;
|
|
4190
|
-
const addValueProperty = (input2, varName) => {
|
|
4191
|
-
const escapedVarName = varName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4192
|
-
const regex = new RegExp(`(?<![a-zA-Z0-9_])${escapedVarName}(?![a-zA-Z0-9_])(?!\\.value)`, "g");
|
|
4193
|
-
return input2.replace(regex, `${varName}.value`);
|
|
4194
|
-
};
|
|
4195
|
-
for (const name in reactiveBindings) {
|
|
4196
|
-
const binding = reactiveBindings[name];
|
|
4197
|
-
if (binding?.reactiveType !== "ref") continue;
|
|
4198
|
-
input = addValueProperty(input, name);
|
|
4199
|
-
}
|
|
4200
|
-
return input;
|
|
4201
|
-
}
|
|
4202
|
-
|
|
4203
|
-
// src/core/transform/sfc/template/shared/resolve-string-expression/index.ts
|
|
4204
|
-
function resolveStringExpr(input, ctx, toStrLiteral = false) {
|
|
4205
|
-
if (toStrLiteral) return t38.stringLiteral(input);
|
|
4206
|
-
const { filename, scriptData } = ctx;
|
|
4207
|
-
const newContent = resolveSpecialExpressions(input, ctx);
|
|
4208
|
-
try {
|
|
4209
|
-
return stringToExpr(newContent, scriptData.lang, filename);
|
|
4210
|
-
} catch {
|
|
4211
|
-
return t38.identifier(newContent);
|
|
4212
|
-
}
|
|
4213
|
-
}
|
|
4214
|
-
|
|
4215
4256
|
// src/core/transform/sfc/template/shared/style-utils.ts
|
|
4216
4257
|
function parseStyleString(styleStr) {
|
|
4217
4258
|
if (isSimpleStyle(styleStr) || strCodeTypes.isIdentifier(styleStr)) {
|
|
@@ -5425,12 +5466,12 @@ function transform(ast, ctx, options) {
|
|
|
5425
5466
|
}
|
|
5426
5467
|
|
|
5427
5468
|
// package.json
|
|
5428
|
-
var version = "1.
|
|
5469
|
+
var version = "1.4.0";
|
|
5429
5470
|
var bin = {
|
|
5430
5471
|
vureact: "./bin/vureact.js"
|
|
5431
5472
|
};
|
|
5432
5473
|
|
|
5433
|
-
// src/compiler/shared/types.ts
|
|
5474
|
+
// src/compiler/shared/types/cache-types.ts
|
|
5434
5475
|
var CacheKey = /* @__PURE__ */ ((CacheKey2) => {
|
|
5435
5476
|
CacheKey2["SFC"] = "sfc";
|
|
5436
5477
|
CacheKey2["SCRIPT"] = "script";
|
|
@@ -5472,10 +5513,146 @@ function simpleFormat(code) {
|
|
|
5472
5513
|
}
|
|
5473
5514
|
|
|
5474
5515
|
// src/compiler/shared/helper.ts
|
|
5475
|
-
import
|
|
5476
|
-
import
|
|
5477
|
-
import
|
|
5516
|
+
import fs2 from "fs";
|
|
5517
|
+
import kleur4 from "kleur";
|
|
5518
|
+
import path3 from "path";
|
|
5519
|
+
|
|
5520
|
+
// src/compiler/shared/file-lock-manager.ts
|
|
5521
|
+
import fs from "fs";
|
|
5522
|
+
import kleur3 from "kleur";
|
|
5478
5523
|
import path2 from "path";
|
|
5524
|
+
import lockfile from "proper-lockfile";
|
|
5525
|
+
var FileLockManager = class _FileLockManager {
|
|
5526
|
+
static instance;
|
|
5527
|
+
/**
|
|
5528
|
+
* 获取单例实例
|
|
5529
|
+
*/
|
|
5530
|
+
static getInstance() {
|
|
5531
|
+
if (!_FileLockManager.instance) {
|
|
5532
|
+
_FileLockManager.instance = new _FileLockManager();
|
|
5533
|
+
}
|
|
5534
|
+
return _FileLockManager.instance;
|
|
5535
|
+
}
|
|
5536
|
+
/**
|
|
5537
|
+
* 获取文件锁并更新文件内容
|
|
5538
|
+
* @param filePath 文件路径
|
|
5539
|
+
* @param updater 更新函数,接收当前内容,返回更新后的内容
|
|
5540
|
+
* @param options 锁选项
|
|
5541
|
+
*/
|
|
5542
|
+
async updateFile(filePath, updater, options = {}) {
|
|
5543
|
+
return this.withLock(
|
|
5544
|
+
filePath,
|
|
5545
|
+
async () => {
|
|
5546
|
+
let current = null;
|
|
5547
|
+
try {
|
|
5548
|
+
const content = await fs.promises.readFile(filePath, "utf-8");
|
|
5549
|
+
if (content.trim()) {
|
|
5550
|
+
try {
|
|
5551
|
+
current = JSON.parse(content);
|
|
5552
|
+
} catch {
|
|
5553
|
+
current = content;
|
|
5554
|
+
}
|
|
5555
|
+
}
|
|
5556
|
+
} catch (error) {
|
|
5557
|
+
console.error(kleur3.red("\u2716"), `Failed to read file ${filePath}`);
|
|
5558
|
+
console.error(error);
|
|
5559
|
+
}
|
|
5560
|
+
const updated = await updater(current);
|
|
5561
|
+
const contentToWrite = typeof updated === "string" ? updated : JSON.stringify(updated, null, 2);
|
|
5562
|
+
await this.writeFile(filePath, contentToWrite);
|
|
5563
|
+
return updated;
|
|
5564
|
+
},
|
|
5565
|
+
options
|
|
5566
|
+
);
|
|
5567
|
+
}
|
|
5568
|
+
/**
|
|
5569
|
+
* 获取文件锁并执行操作
|
|
5570
|
+
* @param filePath 文件路径
|
|
5571
|
+
* @param operation 要执行的操作函数
|
|
5572
|
+
* @param options 锁选项
|
|
5573
|
+
*/
|
|
5574
|
+
async withLock(filePath, operation, options = {}) {
|
|
5575
|
+
const {
|
|
5576
|
+
stale = 1e4,
|
|
5577
|
+
update = stale / 2,
|
|
5578
|
+
retries = 5,
|
|
5579
|
+
realpath = true,
|
|
5580
|
+
lockfilePath
|
|
5581
|
+
} = options;
|
|
5582
|
+
await fs.promises.mkdir(path2.dirname(filePath), { recursive: true });
|
|
5583
|
+
try {
|
|
5584
|
+
await fs.promises.access(filePath);
|
|
5585
|
+
} catch {
|
|
5586
|
+
await this.writeFile(filePath, "");
|
|
5587
|
+
}
|
|
5588
|
+
const release = await lockfile.lock(filePath, {
|
|
5589
|
+
stale,
|
|
5590
|
+
update,
|
|
5591
|
+
retries,
|
|
5592
|
+
realpath,
|
|
5593
|
+
lockfilePath
|
|
5594
|
+
});
|
|
5595
|
+
try {
|
|
5596
|
+
return await operation();
|
|
5597
|
+
} finally {
|
|
5598
|
+
await release();
|
|
5599
|
+
}
|
|
5600
|
+
}
|
|
5601
|
+
/**
|
|
5602
|
+
* 检查文件是否被锁定
|
|
5603
|
+
* @param filePath 文件路径
|
|
5604
|
+
* @param options 锁选项
|
|
5605
|
+
*/
|
|
5606
|
+
async isLocked(filePath, options = {}) {
|
|
5607
|
+
const { stale = 1e4, realpath = true, lockfilePath } = options;
|
|
5608
|
+
try {
|
|
5609
|
+
return await lockfile.check(filePath, { stale, realpath, lockfilePath });
|
|
5610
|
+
} catch {
|
|
5611
|
+
return false;
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
/**
|
|
5615
|
+
* 尝试获取锁(非阻塞)
|
|
5616
|
+
* @param filePath 文件路径
|
|
5617
|
+
* @param options 锁选项
|
|
5618
|
+
* @returns 如果成功获取锁,返回释放函数;否则返回 null
|
|
5619
|
+
*/
|
|
5620
|
+
async tryLock(filePath, options = {}) {
|
|
5621
|
+
const { stale = 1e4, update = stale / 2, realpath = true, lockfilePath } = options;
|
|
5622
|
+
try {
|
|
5623
|
+
const release = await lockfile.lock(filePath, {
|
|
5624
|
+
stale,
|
|
5625
|
+
update,
|
|
5626
|
+
retries: 0,
|
|
5627
|
+
// 不重试
|
|
5628
|
+
realpath,
|
|
5629
|
+
lockfilePath
|
|
5630
|
+
});
|
|
5631
|
+
return release;
|
|
5632
|
+
} catch {
|
|
5633
|
+
return null;
|
|
5634
|
+
}
|
|
5635
|
+
}
|
|
5636
|
+
/**
|
|
5637
|
+
* 释放文件锁
|
|
5638
|
+
* @param filePath 文件路径
|
|
5639
|
+
* @param options 锁选项
|
|
5640
|
+
*/
|
|
5641
|
+
async unlock(filePath, options = {}) {
|
|
5642
|
+
const { realpath = true, lockfilePath } = options;
|
|
5643
|
+
try {
|
|
5644
|
+
await lockfile.unlock(filePath, { realpath, lockfilePath });
|
|
5645
|
+
} catch {
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5648
|
+
async writeFile(filePath, content) {
|
|
5649
|
+
await fs.promises.mkdir(path2.dirname(filePath), { recursive: true });
|
|
5650
|
+
await fs.promises.writeFile(filePath, content, "utf-8");
|
|
5651
|
+
}
|
|
5652
|
+
};
|
|
5653
|
+
var fileLock = FileLockManager.getInstance();
|
|
5654
|
+
|
|
5655
|
+
// src/compiler/shared/helper.ts
|
|
5479
5656
|
var Helper = class {
|
|
5480
5657
|
compilerOpts;
|
|
5481
5658
|
pathFilter;
|
|
@@ -5500,35 +5677,37 @@ var Helper = class {
|
|
|
5500
5677
|
* 获取输入文件的路径
|
|
5501
5678
|
*/
|
|
5502
5679
|
getInputPath() {
|
|
5503
|
-
const { input } = this.compilerOpts;
|
|
5504
|
-
return
|
|
5680
|
+
const { input = "src" } = this.compilerOpts;
|
|
5681
|
+
return path3.resolve(this.getProjectRoot(), input);
|
|
5505
5682
|
}
|
|
5506
5683
|
/**
|
|
5507
5684
|
* 检查 input 路径是否是单个文件
|
|
5508
5685
|
*/
|
|
5509
5686
|
isSingleFile() {
|
|
5510
5687
|
const inputPath = this.getInputPath();
|
|
5511
|
-
return
|
|
5688
|
+
return fs2.existsSync(inputPath) && fs2.statSync(inputPath).isFile();
|
|
5512
5689
|
}
|
|
5513
5690
|
/**
|
|
5514
5691
|
* 获取输出文件的路径。如:'[root]/.vureact/dist/'
|
|
5692
|
+
* @param addInput 会输出如:'[root]/.vureact/dist/[input]/'
|
|
5515
5693
|
*/
|
|
5516
|
-
getOuputPath() {
|
|
5517
|
-
|
|
5694
|
+
getOuputPath(addInput = false) {
|
|
5695
|
+
const { input = "src" } = this.compilerOpts;
|
|
5696
|
+
return path3.resolve(this.getWorkspaceDir(), this.getOutDirName(), addInput ? input : "");
|
|
5518
5697
|
}
|
|
5519
5698
|
getOutDirName() {
|
|
5520
5699
|
const { output } = this.compilerOpts;
|
|
5521
5700
|
return output?.outDir || this.outDir;
|
|
5522
5701
|
}
|
|
5523
5702
|
getWorkspaceDir() {
|
|
5524
|
-
return
|
|
5703
|
+
return path3.resolve(this.getProjectRoot(), this.workspaceDir);
|
|
5525
5704
|
}
|
|
5526
5705
|
/**
|
|
5527
5706
|
* 根据相对输出路径反推源文件路径
|
|
5528
5707
|
*/
|
|
5529
5708
|
getSourcePath(outputPath) {
|
|
5530
|
-
const relativePath2 =
|
|
5531
|
-
return
|
|
5709
|
+
const relativePath2 = path3.relative(this.getOuputPath(), outputPath);
|
|
5710
|
+
return path3.resolve(this.getProjectRoot(), relativePath2);
|
|
5532
5711
|
}
|
|
5533
5712
|
getIgnoreAssets() {
|
|
5534
5713
|
const { output } = this.compilerOpts;
|
|
@@ -5546,7 +5725,9 @@ var Helper = class {
|
|
|
5546
5725
|
"eslint.config.",
|
|
5547
5726
|
"readme.",
|
|
5548
5727
|
"vue.",
|
|
5549
|
-
"
|
|
5728
|
+
".vue",
|
|
5729
|
+
"vureact.config.js",
|
|
5730
|
+
"vureact.config.ts"
|
|
5550
5731
|
]);
|
|
5551
5732
|
}
|
|
5552
5733
|
getIsCache() {
|
|
@@ -5556,19 +5737,19 @@ var Helper = class {
|
|
|
5556
5737
|
* 返回原始目录下的 package.json 路径
|
|
5557
5738
|
*/
|
|
5558
5739
|
getRootPkgPath() {
|
|
5559
|
-
return
|
|
5740
|
+
return path3.join(this.getProjectRoot(), "package.json");
|
|
5560
5741
|
}
|
|
5561
5742
|
/**
|
|
5562
5743
|
* 返回 output 的 package.json 路径
|
|
5563
5744
|
*/
|
|
5564
5745
|
getOutputPkgPath() {
|
|
5565
|
-
return
|
|
5746
|
+
return path3.join(this.getOuputPath(), "package.json");
|
|
5566
5747
|
}
|
|
5567
5748
|
/**
|
|
5568
5749
|
* 返回文件相对工作区的路径
|
|
5569
5750
|
*/
|
|
5570
5751
|
relativePath(filePath) {
|
|
5571
|
-
return
|
|
5752
|
+
return path3.relative(this.getProjectRoot(), filePath);
|
|
5572
5753
|
}
|
|
5573
5754
|
/**
|
|
5574
5755
|
* 替换 .vue 文件名后缀为 .jsx/.tsx
|
|
@@ -5580,8 +5761,8 @@ var Helper = class {
|
|
|
5580
5761
|
const relativePath2 = this.relativePath(filePath);
|
|
5581
5762
|
let newRelativePath = relativePath2.replace(/\.vue$/i, ext);
|
|
5582
5763
|
if (newRelativePath === relativePath2) {
|
|
5583
|
-
const { name, dir } =
|
|
5584
|
-
newRelativePath =
|
|
5764
|
+
const { name, dir } = path3.parse(relativePath2);
|
|
5765
|
+
newRelativePath = path3.join(dir, `${name}${ext}`);
|
|
5585
5766
|
}
|
|
5586
5767
|
return newRelativePath;
|
|
5587
5768
|
}
|
|
@@ -5589,7 +5770,7 @@ var Helper = class {
|
|
|
5589
5770
|
* 判断是否应该跳过不需要进行文件搜索的路径
|
|
5590
5771
|
*/
|
|
5591
5772
|
shouldSkipPath(filePath) {
|
|
5592
|
-
const baseName =
|
|
5773
|
+
const baseName = path3.basename(filePath);
|
|
5593
5774
|
const defaultExcludes = ["node_modules", "dist", "build", ".git", ".DS_Store"];
|
|
5594
5775
|
if (defaultExcludes.includes(baseName)) {
|
|
5595
5776
|
return true;
|
|
@@ -5605,7 +5786,7 @@ var Helper = class {
|
|
|
5605
5786
|
*/
|
|
5606
5787
|
resolveOutputPath(filePath, extname) {
|
|
5607
5788
|
const newRelativePath = extname ? this.replaceVueFileExt(filePath, `.${extname}`) : this.relativePath(filePath);
|
|
5608
|
-
const outputPath =
|
|
5789
|
+
const outputPath = path3.resolve(this.getOuputPath(), newRelativePath);
|
|
5609
5790
|
return outputPath;
|
|
5610
5791
|
}
|
|
5611
5792
|
/**
|
|
@@ -5645,20 +5826,34 @@ var Helper = class {
|
|
|
5645
5826
|
return a.fileSize === b.fileSize && a.mtime === b.mtime;
|
|
5646
5827
|
}
|
|
5647
5828
|
/**
|
|
5648
|
-
*
|
|
5829
|
+
* 统一的写文件方法,包含自动创建目录(带文件互斥锁可选)
|
|
5830
|
+
* @param filePath - 要写入的文件路径
|
|
5831
|
+
* @param content - 要写入的内容
|
|
5832
|
+
* @param options - 可选配置项
|
|
5833
|
+
* @param options.lock - 是否启用文件锁(默认false)
|
|
5649
5834
|
*/
|
|
5650
|
-
async writeFileWithDir(filePath, content) {
|
|
5651
|
-
|
|
5652
|
-
|
|
5835
|
+
async writeFileWithDir(filePath, content, options) {
|
|
5836
|
+
if (options?.lock) {
|
|
5837
|
+
await fileLock.updateFile(filePath, async () => content, options);
|
|
5838
|
+
} else {
|
|
5839
|
+
await fs2.promises.mkdir(path3.dirname(filePath), { recursive: true });
|
|
5840
|
+
await fs2.promises.writeFile(filePath, content, "utf-8");
|
|
5841
|
+
}
|
|
5842
|
+
}
|
|
5843
|
+
async rmFile(filePath) {
|
|
5844
|
+
try {
|
|
5845
|
+
await fs2.promises.rm(filePath, { recursive: true, force: true });
|
|
5846
|
+
} catch {
|
|
5847
|
+
}
|
|
5653
5848
|
}
|
|
5654
5849
|
async loadCache(key) {
|
|
5655
5850
|
const cacheFile = this.getCachePath();
|
|
5656
5851
|
const defaultData = this.createCacheData(key);
|
|
5657
|
-
if (!
|
|
5852
|
+
if (!fs2.existsSync(cacheFile)) {
|
|
5658
5853
|
return defaultData;
|
|
5659
5854
|
}
|
|
5660
5855
|
try {
|
|
5661
|
-
const content = await
|
|
5856
|
+
const content = await fs2.promises.readFile(cacheFile, "utf-8");
|
|
5662
5857
|
const data = JSON.parse(content);
|
|
5663
5858
|
return {
|
|
5664
5859
|
key,
|
|
@@ -5686,15 +5881,25 @@ var Helper = class {
|
|
|
5686
5881
|
*/
|
|
5687
5882
|
getCachePath() {
|
|
5688
5883
|
const filename = "_metadata";
|
|
5689
|
-
return
|
|
5884
|
+
return path3.resolve(this.getProjectRoot(), this.workspaceDir, "cache", `${filename}.json`);
|
|
5690
5885
|
}
|
|
5691
5886
|
async saveCache(data) {
|
|
5692
5887
|
if (!this.getIsCache() || !data) {
|
|
5693
5888
|
return;
|
|
5694
5889
|
}
|
|
5695
|
-
const
|
|
5696
|
-
|
|
5697
|
-
|
|
5890
|
+
const getDefaultValue = () => ({
|
|
5891
|
+
["sfc" /* SFC */]: [],
|
|
5892
|
+
["script" /* SCRIPT */]: [],
|
|
5893
|
+
["style" /* STYLE */]: [],
|
|
5894
|
+
["copied" /* ASSET */]: []
|
|
5895
|
+
});
|
|
5896
|
+
const cachePath = this.getCachePath();
|
|
5897
|
+
await fileLock.updateFile(cachePath, (currentData) => {
|
|
5898
|
+
const { key, target } = data;
|
|
5899
|
+
const mergedData = currentData || getDefaultValue();
|
|
5900
|
+
mergedData[key] = target;
|
|
5901
|
+
return mergedData;
|
|
5902
|
+
});
|
|
5698
5903
|
}
|
|
5699
5904
|
genHash(content) {
|
|
5700
5905
|
return genHashByXXH(content);
|
|
@@ -5706,18 +5911,18 @@ var Helper = class {
|
|
|
5706
5911
|
*/
|
|
5707
5912
|
scanFiles(dir, filter) {
|
|
5708
5913
|
const results = [];
|
|
5709
|
-
if (!
|
|
5914
|
+
if (!fs2.existsSync(dir)) {
|
|
5710
5915
|
return results;
|
|
5711
5916
|
}
|
|
5712
|
-
const stats =
|
|
5917
|
+
const stats = fs2.statSync(dir);
|
|
5713
5918
|
if (stats.isFile()) {
|
|
5714
5919
|
return filter(dir) ? [dir] : [];
|
|
5715
5920
|
}
|
|
5716
|
-
const list =
|
|
5921
|
+
const list = fs2.readdirSync(dir);
|
|
5717
5922
|
for (const file of list) {
|
|
5718
|
-
const fullPath =
|
|
5923
|
+
const fullPath = path3.resolve(dir, file);
|
|
5719
5924
|
if (this.shouldSkipPath(fullPath)) continue;
|
|
5720
|
-
const stat =
|
|
5925
|
+
const stat = fs2.statSync(fullPath);
|
|
5721
5926
|
if (stat.isDirectory() && this.compilerOpts.recursive !== false) {
|
|
5722
5927
|
results.push(...this.scanFiles(fullPath, filter));
|
|
5723
5928
|
} else if (filter(fullPath)) {
|
|
@@ -5727,19 +5932,19 @@ var Helper = class {
|
|
|
5727
5932
|
return results;
|
|
5728
5933
|
}
|
|
5729
5934
|
getAbsPath(filePath) {
|
|
5730
|
-
return
|
|
5935
|
+
return path3.isAbsolute(filePath) ? filePath : path3.resolve(this.getProjectRoot(), filePath);
|
|
5731
5936
|
}
|
|
5732
5937
|
async getFileMeta(filePath) {
|
|
5733
|
-
const stats = await
|
|
5938
|
+
const stats = await fs2.promises.stat(filePath);
|
|
5734
5939
|
return {
|
|
5735
5940
|
fileSize: stats.size,
|
|
5736
5941
|
mtime: stats.mtimeMs
|
|
5737
5942
|
};
|
|
5738
5943
|
}
|
|
5739
5944
|
async removeOutputFile(filePath, resolveOutputPath) {
|
|
5740
|
-
const
|
|
5741
|
-
if (!
|
|
5742
|
-
await
|
|
5945
|
+
const path9 = resolveOutputPath ? this.resolveOutputPath(filePath) : filePath;
|
|
5946
|
+
if (!fs2.existsSync(path9)) return;
|
|
5947
|
+
await fs2.promises.unlink(path9);
|
|
5743
5948
|
}
|
|
5744
5949
|
updateCache(targetFile, newData, cache) {
|
|
5745
5950
|
const index = cache.target.findIndex((c) => c.file === targetFile);
|
|
@@ -5749,18 +5954,6 @@ var Helper = class {
|
|
|
5749
5954
|
cache.target.push(newData);
|
|
5750
5955
|
}
|
|
5751
5956
|
}
|
|
5752
|
-
resolveViteCreateApp() {
|
|
5753
|
-
const { output } = this.compilerOpts;
|
|
5754
|
-
const config = output?.bootstrapVite;
|
|
5755
|
-
const template = typeof config === "object" ? config.template : "react-ts";
|
|
5756
|
-
const outDirName = this.getOutDirName();
|
|
5757
|
-
const cmd = `npm create vite@latest ${outDirName} -- --template ${template}`;
|
|
5758
|
-
execSync(cmd, {
|
|
5759
|
-
cwd: this.getWorkspaceDir(),
|
|
5760
|
-
stdio: "ignore"
|
|
5761
|
-
// 隐藏 create-vite 内部的输出日志,保持终端整洁
|
|
5762
|
-
});
|
|
5763
|
-
}
|
|
5764
5957
|
/**
|
|
5765
5958
|
* 获取需要排除编译的文件
|
|
5766
5959
|
*/
|
|
@@ -5788,15 +5981,15 @@ var Helper = class {
|
|
|
5788
5981
|
}
|
|
5789
5982
|
printCompileInfo(file, duration) {
|
|
5790
5983
|
this.print(
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5984
|
+
kleur4.green("Compiled"),
|
|
5985
|
+
kleur4.dim(normalizePath(this.relativePath(file))),
|
|
5986
|
+
kleur4.gray(`(${duration})`)
|
|
5794
5987
|
);
|
|
5795
5988
|
}
|
|
5796
5989
|
print(...message) {
|
|
5797
5990
|
if (this.compilerOpts.watch) {
|
|
5798
5991
|
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
5799
|
-
console.info(
|
|
5992
|
+
console.info(kleur4.dim(time), kleur4.cyan(kleur4.bold("[vureact]")), ...message);
|
|
5800
5993
|
return;
|
|
5801
5994
|
}
|
|
5802
5995
|
console.info(...message);
|
|
@@ -5804,17 +5997,34 @@ var Helper = class {
|
|
|
5804
5997
|
/**
|
|
5805
5998
|
* 读取 package.json 文件内容,并处理成对象返回
|
|
5806
5999
|
*/
|
|
5807
|
-
async resolvePackageFile(
|
|
6000
|
+
async resolvePackageFile(path9) {
|
|
6001
|
+
if (!fs2.existsSync(path9)) {
|
|
6002
|
+
return {};
|
|
6003
|
+
}
|
|
5808
6004
|
try {
|
|
5809
|
-
|
|
6005
|
+
const content = await fs2.promises.readFile(path9, "utf-8");
|
|
6006
|
+
if (!content.trim()) {
|
|
5810
6007
|
return {};
|
|
5811
6008
|
}
|
|
5812
|
-
return JSON.parse(
|
|
6009
|
+
return JSON.parse(content);
|
|
5813
6010
|
} catch (error) {
|
|
5814
|
-
console.error(
|
|
6011
|
+
console.error(kleur4.red("\u274C"), `Failed to parse JSON file ${path9}:
|
|
6012
|
+
`, error);
|
|
5815
6013
|
return {};
|
|
5816
6014
|
}
|
|
5817
6015
|
}
|
|
6016
|
+
/**
|
|
6017
|
+
* 获取目录到文件的相对路径
|
|
6018
|
+
* @returns 结果路径不包含文件拓展名,并以诸如 ./ 开头
|
|
6019
|
+
*/
|
|
6020
|
+
resolveRelativePath(from, to) {
|
|
6021
|
+
let relativePath2 = path3.relative(from, to);
|
|
6022
|
+
relativePath2 = relativePath2.substring(0, relativePath2.indexOf("."));
|
|
6023
|
+
if (!relativePath2.startsWith(".")) {
|
|
6024
|
+
relativePath2 = `./${relativePath2}`;
|
|
6025
|
+
}
|
|
6026
|
+
return normalizePath(relativePath2);
|
|
6027
|
+
}
|
|
5818
6028
|
};
|
|
5819
6029
|
|
|
5820
6030
|
// src/core/parse/style-only.ts
|
|
@@ -5851,7 +6061,7 @@ function parseOnlyStyle(source, ctx, options) {
|
|
|
5851
6061
|
}
|
|
5852
6062
|
|
|
5853
6063
|
// src/compiler/context/adapter.ts
|
|
5854
|
-
import
|
|
6064
|
+
import path4 from "path";
|
|
5855
6065
|
|
|
5856
6066
|
// src/compiler/context/creator.ts
|
|
5857
6067
|
function createCompilationCtx() {
|
|
@@ -5938,7 +6148,7 @@ var CompilationAdapter = class _CompilationAdapter {
|
|
|
5938
6148
|
return ctx;
|
|
5939
6149
|
}
|
|
5940
6150
|
static detectInputType(filename) {
|
|
5941
|
-
const ext =
|
|
6151
|
+
const ext = path4.extname(filename).toLowerCase();
|
|
5942
6152
|
switch (ext) {
|
|
5943
6153
|
case ".vue":
|
|
5944
6154
|
return "sfc";
|
|
@@ -5962,65 +6172,11 @@ var BaseCompiler = class extends Helper {
|
|
|
5962
6172
|
version = version;
|
|
5963
6173
|
options;
|
|
5964
6174
|
createContext = CompilationAdapter.createContext;
|
|
5965
|
-
/**
|
|
5966
|
-
* 创建基础编译器实例
|
|
5967
|
-
*
|
|
5968
|
-
* @param options - 编译器配置选项,包括缓存设置、插件配置、样式预处理等,
|
|
5969
|
-
* 所有选项都会传递给父类 {@link Helper} 进行初始化
|
|
5970
|
-
*
|
|
5971
|
-
* @see {@link CompilerOptions} 查看完整的配置选项说明
|
|
5972
|
-
*/
|
|
5973
6175
|
constructor(options = {}) {
|
|
5974
6176
|
super(options);
|
|
5975
6177
|
this.options = options;
|
|
5976
6178
|
}
|
|
5977
|
-
/**
|
|
5978
|
-
* 编译 Vue 源代码为 React 代码
|
|
5979
|
-
*
|
|
5980
|
-
* 该方法执行完整的编译流程,包括:
|
|
5981
|
-
* 1. 上下文初始化:创建独立的编译上下文
|
|
5982
|
-
* 2. 解析阶段:将 Vue 源代码解析为抽象语法树(AST)
|
|
5983
|
-
* 3. 转换阶段:将 Vue AST 转换为 React 中间表示(IR)
|
|
5984
|
-
* 4. 生成阶段:将 React IR 生成为目标代码
|
|
5985
|
-
* 5. 插件执行:在各阶段执行注册的插件
|
|
5986
|
-
* 6. 结果处理:整理编译结果并返回
|
|
5987
|
-
*
|
|
5988
|
-
* 编译过程使用 try-finally 确保上下文资源被正确清理,
|
|
5989
|
-
* 即使编译过程中发生错误也不会导致资源泄漏。
|
|
5990
|
-
*
|
|
5991
|
-
* @param source - Vue 源代码字符串
|
|
5992
|
-
* @param filename - 源文件名,用于生成文件ID和输出路径
|
|
5993
|
-
* @returns {CompilationResult} 编译结果,包含生成的代码和文件信息
|
|
5994
|
-
*
|
|
5995
|
-
* @example
|
|
5996
|
-
* ```typescript
|
|
5997
|
-
* const vueCode = `
|
|
5998
|
-
* <template>
|
|
5999
|
-
* <div class="container">{{ message }}</div>
|
|
6000
|
-
* </template>
|
|
6001
|
-
*
|
|
6002
|
-
* <script setup lang="ts">
|
|
6003
|
-
* import { ref } from 'vue;
|
|
6004
|
-
* const message = ref('Hello Vue')
|
|
6005
|
-
* </script>
|
|
6006
|
-
*
|
|
6007
|
-
* <style scoped>
|
|
6008
|
-
* .container {
|
|
6009
|
-
* padding: 20px;
|
|
6010
|
-
* }
|
|
6011
|
-
* </style>
|
|
6012
|
-
* `;
|
|
6013
|
-
*
|
|
6014
|
-
* const result = compiler.compile(vueCode, 'MyComponent.vue');
|
|
6015
|
-
* console.log(result);
|
|
6016
|
-
* ```
|
|
6017
|
-
*
|
|
6018
|
-
* @throws 不会直接抛出异常,错误通过日志系统记录
|
|
6019
|
-
* @see {@link parse} 解析函数
|
|
6020
|
-
* @see {@link transform} 转换函数
|
|
6021
|
-
* @see {@link generate} 生成函数
|
|
6022
|
-
* @see {@link executePlugins} 插件执行函数
|
|
6023
|
-
*/
|
|
6179
|
+
/** 编译 Vue 源代码为 React 代码 */
|
|
6024
6180
|
compile(source, filename) {
|
|
6025
6181
|
const { plugins, preprocessStyles = true } = this.options;
|
|
6026
6182
|
const fileId = this.genHash(filename);
|
|
@@ -6056,61 +6212,12 @@ var BaseCompiler = class extends Helper {
|
|
|
6056
6212
|
ctx.clear();
|
|
6057
6213
|
}
|
|
6058
6214
|
}
|
|
6059
|
-
/**
|
|
6060
|
-
* 初始化 Babel 代码生成选项
|
|
6061
|
-
*
|
|
6062
|
-
* 合并用户自定义的生成选项与默认选项,确保代码生成的一致性和正确性。
|
|
6063
|
-
* 默认配置优化了代码的可读性和性能:
|
|
6064
|
-
* 1. 最小化 Unicode 转义:只转义必要的字符,保持代码可读性
|
|
6065
|
-
* 2. 统一引号风格:使用单引号,符合 JavaScript 社区常见约定
|
|
6066
|
-
* 3. 代码压缩:启用最小化,移除不必要的空白字符
|
|
6067
|
-
*
|
|
6068
|
-
* 如果用户提供了自定义选项,会与默认选项进行深度合并,
|
|
6069
|
-
* 用户选项的优先级高于默认选项。
|
|
6070
|
-
*
|
|
6071
|
-
* @private
|
|
6072
|
-
* @param filename - 可选的文件名,用于源码映射配置
|
|
6073
|
-
* @returns {GeneratorOptions} 合并后的 Babel 生成选项
|
|
6074
|
-
*
|
|
6075
|
-
* @remarks
|
|
6076
|
-
* - 源码映射支持:如果启用了 sourceMaps 且提供了文件名,会自动设置 sourceFileName
|
|
6077
|
-
* - 选项合并策略:用户选项会覆盖默认选项,实现灵活的配置
|
|
6078
|
-
* - 性能优化:默认启用 minified 以减少生成代码的体积
|
|
6079
|
-
* - 编码安全:使用 jsesc 确保特殊字符的正确转义
|
|
6080
|
-
*
|
|
6081
|
-
* @example
|
|
6082
|
-
* ```typescript
|
|
6083
|
-
* // 默认选项
|
|
6084
|
-
* const defaultOptions = {
|
|
6085
|
-
* jsescOption: { minimal: true, quotes: 'single' },
|
|
6086
|
-
* minified: true
|
|
6087
|
-
* };
|
|
6088
|
-
*
|
|
6089
|
-
* // 用户自定义选项
|
|
6090
|
-
* const userOptions = {
|
|
6091
|
-
* minified: false, // 覆盖默认值
|
|
6092
|
-
* sourceMaps: true // 新增选项
|
|
6093
|
-
* };
|
|
6094
|
-
*
|
|
6095
|
-
* // 合并结果
|
|
6096
|
-
* const merged = {
|
|
6097
|
-
* jsescOption: { minimal: true, quotes: 'single' },
|
|
6098
|
-
* minified: false, // 用户值
|
|
6099
|
-
* sourceMaps: true // 用户值
|
|
6100
|
-
* };
|
|
6101
|
-
* ```
|
|
6102
|
-
*
|
|
6103
|
-
* @see {@link GeneratorOptions} Babel 生成选项类型定义
|
|
6104
|
-
*/
|
|
6105
6215
|
prepareGenerateOptions(filename) {
|
|
6106
6216
|
const userOptions = this.options.generate || {};
|
|
6107
6217
|
const mergedOptions = {
|
|
6108
|
-
// 配置 jsesc 避免 Unicode 转义
|
|
6109
6218
|
jsescOption: {
|
|
6110
6219
|
minimal: true,
|
|
6111
|
-
// 只转义必要的字符
|
|
6112
6220
|
quotes: "single"
|
|
6113
|
-
// 使用单引号
|
|
6114
6221
|
},
|
|
6115
6222
|
minified: true,
|
|
6116
6223
|
...userOptions
|
|
@@ -6120,36 +6227,6 @@ var BaseCompiler = class extends Helper {
|
|
|
6120
6227
|
}
|
|
6121
6228
|
return mergedOptions;
|
|
6122
6229
|
}
|
|
6123
|
-
/**
|
|
6124
|
-
* 处理 SFC 和 Script 文件的编译结果
|
|
6125
|
-
*
|
|
6126
|
-
* 根据编译上下文中的输入类型(SFC 或 Script),整理并返回相应的编译结果。
|
|
6127
|
-
* 对于 SFC 文件,返回包含 JSX 和 CSS 信息的完整结果;
|
|
6128
|
-
* 对于 Script 文件,返回仅包含脚本信息的结果。
|
|
6129
|
-
*
|
|
6130
|
-
* 关键处理逻辑:
|
|
6131
|
-
* 1. 构建基础结果:包含文件ID、路由信息和生成的代码
|
|
6132
|
-
* 2. 确定输出路径:根据源文件路径和语言类型生成输出文件路径
|
|
6133
|
-
* 3. 区分文件类型:
|
|
6134
|
-
* - SFC 文件:生成 .tsx 扩展名,包含样式信息
|
|
6135
|
-
* - Script 文件:保持原扩展名,不包含样式信息
|
|
6136
|
-
* 4. 样式处理:提取样式文件路径、作用域ID和样式代码
|
|
6137
|
-
*
|
|
6138
|
-
* @private
|
|
6139
|
-
* @param ir - React 中间表示(IR)描述符,包含转换后的组件信息
|
|
6140
|
-
* @param gen - 代码生成结果,包含生成的代码和源码映射
|
|
6141
|
-
* @param ctxData - 编译上下文数据,包含文件信息和编译状态
|
|
6142
|
-
* @returns {CompilationResult} 整理后的编译结果
|
|
6143
|
-
*
|
|
6144
|
-
* @remarks
|
|
6145
|
-
* - 文件扩展名处理:Vue SFC 文件会转换为 .tsx 或 .jsx 文件
|
|
6146
|
-
* - 样式分离:SFC 中的样式会被提取到独立的 CSS 文件中
|
|
6147
|
-
* - 路由检测:自动检测组件是否使用路由,用于依赖注入
|
|
6148
|
-
* - 作用域样式:为 Scoped CSS 生成唯一的作用域ID
|
|
6149
|
-
*
|
|
6150
|
-
* @see {@link SFCCompilationResult} SFC 编译结果类型
|
|
6151
|
-
* @see {@link ScriptCompilationResult} Script 编译结果类型
|
|
6152
|
-
*/
|
|
6153
6230
|
resolveMainResult(ir, gen, ctxData) {
|
|
6154
6231
|
const { fileId, filename, scriptData, styleData, inputType } = ctxData;
|
|
6155
6232
|
const base = {
|
|
@@ -6164,7 +6241,6 @@ var BaseCompiler = class extends Helper {
|
|
|
6164
6241
|
fileInfo: {
|
|
6165
6242
|
jsx: {
|
|
6166
6243
|
file: `${file}x`,
|
|
6167
|
-
// 'xxx.ts' + 'x' => 'xxx.tsx'
|
|
6168
6244
|
lang
|
|
6169
6245
|
},
|
|
6170
6246
|
css: {
|
|
@@ -6181,11 +6257,6 @@ var BaseCompiler = class extends Helper {
|
|
|
6181
6257
|
...base
|
|
6182
6258
|
};
|
|
6183
6259
|
}
|
|
6184
|
-
/**
|
|
6185
|
-
* 处理 Style 文件的编译结果
|
|
6186
|
-
* @param data style 文件解析结果
|
|
6187
|
-
* @param ctxData 上下文数据
|
|
6188
|
-
*/
|
|
6189
6260
|
resolveStyleResult(data, ctxData) {
|
|
6190
6261
|
const { fileId, filename } = ctxData;
|
|
6191
6262
|
const { lang, content = "" } = data.style.source;
|
|
@@ -6218,13 +6289,12 @@ function formattDuration(n) {
|
|
|
6218
6289
|
}
|
|
6219
6290
|
|
|
6220
6291
|
// src/compiler/shared/file-compiler/index.ts
|
|
6221
|
-
import
|
|
6222
|
-
import kleur6 from "kleur";
|
|
6292
|
+
import kleur8 from "kleur";
|
|
6223
6293
|
import ora2 from "ora";
|
|
6224
6294
|
|
|
6225
6295
|
// src/compiler/shared/file-compiler/asset-manager.ts
|
|
6226
|
-
import
|
|
6227
|
-
import
|
|
6296
|
+
import fs3 from "fs";
|
|
6297
|
+
import path5 from "path";
|
|
6228
6298
|
var AssetManager = class {
|
|
6229
6299
|
constructor(fileCompiler, cleanupManager) {
|
|
6230
6300
|
this.fileCompiler = fileCompiler;
|
|
@@ -6232,19 +6302,21 @@ var AssetManager = class {
|
|
|
6232
6302
|
}
|
|
6233
6303
|
// 需要经过管线编译处理的文件类型
|
|
6234
6304
|
pipelineFiles = [".js", ".ts", ".less", ".scss", ".sass"];
|
|
6305
|
+
skippedCount = 0;
|
|
6235
6306
|
/**
|
|
6236
6307
|
* 运行资源文件处理管线
|
|
6237
6308
|
*/
|
|
6238
6309
|
async runAssetPipeline() {
|
|
6310
|
+
const { options } = this.fileCompiler;
|
|
6239
6311
|
const rootPath = this.fileCompiler.getProjectRoot();
|
|
6240
6312
|
const inputPath = this.fileCompiler.getInputPath();
|
|
6241
6313
|
const exclusions = this.fileCompiler.getIgnoreAssets();
|
|
6242
6314
|
const assetFiles = this.fileCompiler.scanFiles(rootPath, (p) => {
|
|
6243
6315
|
if (this.fileCompiler.shouldSkipPath(p)) return false;
|
|
6244
6316
|
const relativeToRoot = normalizePath(this.fileCompiler.relativePath(p));
|
|
6245
|
-
const filename =
|
|
6246
|
-
const ext =
|
|
6247
|
-
if (!
|
|
6317
|
+
const filename = path5.basename(p).toLowerCase();
|
|
6318
|
+
const ext = path5.extname(p).toLowerCase();
|
|
6319
|
+
if (!options.output?.ignoreAssets) {
|
|
6248
6320
|
const shouldExclude = Array.from(exclusions).some((pattern) => {
|
|
6249
6321
|
if (pattern.endsWith(".")) {
|
|
6250
6322
|
return filename.startsWith(pattern);
|
|
@@ -6254,34 +6326,28 @@ var AssetManager = class {
|
|
|
6254
6326
|
}
|
|
6255
6327
|
return relativeToRoot === pattern || filename === pattern;
|
|
6256
6328
|
});
|
|
6257
|
-
if (shouldExclude)
|
|
6258
|
-
return false;
|
|
6259
|
-
}
|
|
6329
|
+
if (shouldExclude) return false;
|
|
6260
6330
|
} else if (exclusions.has(relativeToRoot) || exclusions.has(filename)) {
|
|
6261
6331
|
return false;
|
|
6262
6332
|
}
|
|
6263
6333
|
if (ext === ".vue") return false;
|
|
6264
|
-
const isInsideSrc = p.startsWith(inputPath +
|
|
6334
|
+
const isInsideSrc = p.startsWith(inputPath + path5.sep);
|
|
6265
6335
|
if (isInsideSrc && this.pipelineFiles.includes(ext)) {
|
|
6266
6336
|
return false;
|
|
6267
6337
|
}
|
|
6268
6338
|
return true;
|
|
6269
6339
|
});
|
|
6270
6340
|
const absFiles = new Set(assetFiles.map((f) => this.fileCompiler.getAbsPath(f)));
|
|
6271
|
-
const cache = await this.fileCompiler.loadCache("copied" /* ASSET */);
|
|
6272
6341
|
await this.cleanupManager.cleanupOldOutput("copied" /* ASSET */, (u) => !absFiles.has(u.file));
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
for (const file of files) {
|
|
6281
|
-
const meta = await this.processAsset(file, cache);
|
|
6282
|
-
this.updateCache(file, meta, cache);
|
|
6283
|
-
}
|
|
6342
|
+
if (!assetFiles.length) return 0;
|
|
6343
|
+
const cache = await this.fileCompiler.loadCache("copied" /* ASSET */);
|
|
6344
|
+
const copied = await Promise.all(
|
|
6345
|
+
assetFiles.map((file) => {
|
|
6346
|
+
return this.processAsset(file, cache);
|
|
6347
|
+
})
|
|
6348
|
+
);
|
|
6284
6349
|
await this.fileCompiler.saveCache(cache);
|
|
6350
|
+
return copied.filter(Boolean).length;
|
|
6285
6351
|
}
|
|
6286
6352
|
/**
|
|
6287
6353
|
* Process single asset file, compare with cache and decide whether to copy.
|
|
@@ -6295,11 +6361,16 @@ var AssetManager = class {
|
|
|
6295
6361
|
const cache = (this.fileCompiler.getIsCache() ? existingCache : void 0) || await this.fileCompiler.loadCache("copied" /* ASSET */);
|
|
6296
6362
|
const record = cache.target.find((f) => f.file === absPath);
|
|
6297
6363
|
if (record && this.fileCompiler.compareFileMeta(record, fileMeta)) {
|
|
6298
|
-
|
|
6364
|
+
this.skippedCount++;
|
|
6365
|
+
return;
|
|
6299
6366
|
}
|
|
6300
6367
|
const outputPath = this.fileCompiler.resolveOutputPath(absPath);
|
|
6301
|
-
await
|
|
6302
|
-
await
|
|
6368
|
+
await fs3.promises.mkdir(path5.dirname(outputPath), { recursive: true });
|
|
6369
|
+
await fs3.promises.copyFile(absPath, outputPath);
|
|
6370
|
+
this.updateCache(absPath, fileMeta, cache);
|
|
6371
|
+
if (this.fileCompiler.getIsCache() && !existingCache) {
|
|
6372
|
+
await this.fileCompiler.saveCache(cache);
|
|
6373
|
+
}
|
|
6303
6374
|
return fileMeta;
|
|
6304
6375
|
}
|
|
6305
6376
|
/**
|
|
@@ -6314,6 +6385,18 @@ var AssetManager = class {
|
|
|
6314
6385
|
cache.target.push(newData);
|
|
6315
6386
|
}
|
|
6316
6387
|
}
|
|
6388
|
+
/**
|
|
6389
|
+
* 获取跳过的文件数量
|
|
6390
|
+
*/
|
|
6391
|
+
getSkippedCount() {
|
|
6392
|
+
return this.skippedCount;
|
|
6393
|
+
}
|
|
6394
|
+
/**
|
|
6395
|
+
* 重置跳过的文件数量
|
|
6396
|
+
*/
|
|
6397
|
+
resetSkippedCount() {
|
|
6398
|
+
this.skippedCount = 0;
|
|
6399
|
+
}
|
|
6317
6400
|
};
|
|
6318
6401
|
|
|
6319
6402
|
// src/compiler/shared/file-compiler/cache-manager.ts
|
|
@@ -6321,22 +6404,42 @@ var CacheManager = class {
|
|
|
6321
6404
|
constructor(fileCompiler) {
|
|
6322
6405
|
this.fileCompiler = fileCompiler;
|
|
6323
6406
|
}
|
|
6407
|
+
pendingUpdates = /* @__PURE__ */ new Map();
|
|
6324
6408
|
/**
|
|
6325
|
-
*
|
|
6409
|
+
* 批量更新缓存记录
|
|
6326
6410
|
*/
|
|
6327
6411
|
async updateCacheIncrementally(unit, key) {
|
|
6328
6412
|
if (!this.fileCompiler.getIsCache()) return;
|
|
6329
|
-
const cache = await this.fileCompiler.loadCache(key);
|
|
6330
6413
|
const meta = { ...unit };
|
|
6331
6414
|
delete meta.source;
|
|
6332
6415
|
if (key === "sfc" /* SFC */) {
|
|
6333
|
-
delete meta.output
|
|
6334
|
-
delete meta.output
|
|
6416
|
+
delete meta.output?.jsx.code;
|
|
6417
|
+
delete meta.output?.css.code;
|
|
6335
6418
|
} else if (key === "script" /* SCRIPT */) {
|
|
6336
|
-
delete meta.output
|
|
6419
|
+
delete meta.output?.script.code;
|
|
6420
|
+
} else if (key === "style" /* STYLE */) {
|
|
6421
|
+
delete meta.output?.style.code;
|
|
6422
|
+
}
|
|
6423
|
+
if (!this.pendingUpdates.has(key)) {
|
|
6424
|
+
this.pendingUpdates.set(key, []);
|
|
6425
|
+
}
|
|
6426
|
+
this.pendingUpdates.get(key).push({ unit, meta });
|
|
6427
|
+
}
|
|
6428
|
+
/**
|
|
6429
|
+
* 批量保存缓存
|
|
6430
|
+
*/
|
|
6431
|
+
async flushCache(key) {
|
|
6432
|
+
if (!this.fileCompiler.getIsCache() || !this.pendingUpdates.has(key)) {
|
|
6433
|
+
return;
|
|
6434
|
+
}
|
|
6435
|
+
const updates = this.pendingUpdates.get(key);
|
|
6436
|
+
if (updates.length === 0) return;
|
|
6437
|
+
const cache = await this.fileCompiler.loadCache(key);
|
|
6438
|
+
for (const { unit, meta } of updates) {
|
|
6439
|
+
this.updateCache(unit.file, meta, cache);
|
|
6337
6440
|
}
|
|
6338
|
-
this.updateCache(unit.file, meta, cache);
|
|
6339
6441
|
await this.fileCompiler.saveCache(cache);
|
|
6442
|
+
this.pendingUpdates.set(key, []);
|
|
6340
6443
|
}
|
|
6341
6444
|
/**
|
|
6342
6445
|
* 更新缓存
|
|
@@ -6352,7 +6455,7 @@ var CacheManager = class {
|
|
|
6352
6455
|
};
|
|
6353
6456
|
|
|
6354
6457
|
// src/compiler/shared/file-compiler/cleanup-manager.ts
|
|
6355
|
-
import
|
|
6458
|
+
import path6 from "path";
|
|
6356
6459
|
var CleanupManager = class {
|
|
6357
6460
|
constructor(fileCompiler) {
|
|
6358
6461
|
this.fileCompiler = fileCompiler;
|
|
@@ -6367,7 +6470,7 @@ var CleanupManager = class {
|
|
|
6367
6470
|
(u) => u.file === absPath || // 加 path.sep 是因为假如删除了 src/components 文件夹,
|
|
6368
6471
|
// 为了防止误删名为 src/components-old 的文件夹,
|
|
6369
6472
|
// 所以必须确保路径后跟着一个分隔符,确保精准匹配子目录内容。
|
|
6370
|
-
u.file.startsWith(absPath +
|
|
6473
|
+
u.file.startsWith(absPath + path6.sep)
|
|
6371
6474
|
);
|
|
6372
6475
|
}
|
|
6373
6476
|
/**
|
|
@@ -6379,25 +6482,43 @@ var CleanupManager = class {
|
|
|
6379
6482
|
const toRemove = cache.target.filter(filter);
|
|
6380
6483
|
if (!toRemove.length) return;
|
|
6381
6484
|
const removeFn = async (m) => {
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6485
|
+
let meta;
|
|
6486
|
+
switch (key) {
|
|
6487
|
+
case "sfc" /* SFC */: {
|
|
6488
|
+
meta = m;
|
|
6489
|
+
const { jsx, css } = meta.output;
|
|
6490
|
+
await this.fileCompiler.removeOutputFile(jsx.file);
|
|
6491
|
+
if (css?.file) {
|
|
6492
|
+
await this.fileCompiler.removeOutputFile(css.file);
|
|
6493
|
+
}
|
|
6494
|
+
break;
|
|
6495
|
+
}
|
|
6496
|
+
case "script" /* SCRIPT */: {
|
|
6497
|
+
meta = m;
|
|
6498
|
+
await this.fileCompiler.removeOutputFile(meta.output.script.file);
|
|
6499
|
+
break;
|
|
6500
|
+
}
|
|
6501
|
+
case "style" /* STYLE */: {
|
|
6502
|
+
meta = m;
|
|
6503
|
+
await this.fileCompiler.removeOutputFile(meta.output.style.file);
|
|
6504
|
+
break;
|
|
6505
|
+
}
|
|
6506
|
+
// 静态资产缓存直接删除对应文件
|
|
6507
|
+
default: {
|
|
6508
|
+
await this.fileCompiler.removeOutputFile(m.file, true);
|
|
6509
|
+
break;
|
|
6389
6510
|
}
|
|
6390
|
-
} else if (key === "script" /* SCRIPT */ || key === "copied" /* ASSET */) {
|
|
6391
|
-
await this.fileCompiler.removeOutputFile(m.file, true);
|
|
6392
6511
|
}
|
|
6393
6512
|
};
|
|
6394
6513
|
await Promise.all(toRemove.map(removeFn));
|
|
6514
|
+
const removedFiles = new Set(toRemove.map((m) => m.file));
|
|
6515
|
+
cache.target = cache.target.filter((m) => !removedFiles.has(m.file));
|
|
6395
6516
|
await this.fileCompiler.saveCache(cache);
|
|
6396
6517
|
}
|
|
6397
6518
|
};
|
|
6398
6519
|
|
|
6399
6520
|
// src/compiler/shared/file-compiler/compilation-unit.ts
|
|
6400
|
-
import
|
|
6521
|
+
import kleur5 from "kleur";
|
|
6401
6522
|
var CompilationUnitProcessor = class {
|
|
6402
6523
|
constructor(fileCompiler) {
|
|
6403
6524
|
this.fileCompiler = fileCompiler;
|
|
@@ -6412,7 +6533,7 @@ var CompilationUnitProcessor = class {
|
|
|
6412
6533
|
this.resolveResult(result, unit, key);
|
|
6413
6534
|
} catch (err) {
|
|
6414
6535
|
console.info(
|
|
6415
|
-
|
|
6536
|
+
kleur5.red(`\u2716`),
|
|
6416
6537
|
`Failed to compile ${this.fileCompiler.relativePath(unit.file)}
|
|
6417
6538
|
`,
|
|
6418
6539
|
err
|
|
@@ -6493,19 +6614,16 @@ var CompilationUnitProcessor = class {
|
|
|
6493
6614
|
};
|
|
6494
6615
|
|
|
6495
6616
|
// src/compiler/shared/file-compiler/file-processor.ts
|
|
6496
|
-
import
|
|
6617
|
+
import fs4 from "fs";
|
|
6618
|
+
import kleur6 from "kleur";
|
|
6619
|
+
import path7 from "path";
|
|
6497
6620
|
var FileProcessor = class {
|
|
6498
6621
|
constructor(fileCompiler, compilationUnitProcessor, cacheManager) {
|
|
6499
6622
|
this.fileCompiler = fileCompiler;
|
|
6500
6623
|
this.compilationUnitProcessor = compilationUnitProcessor;
|
|
6501
6624
|
this.cacheManager = cacheManager;
|
|
6502
6625
|
}
|
|
6503
|
-
|
|
6504
|
-
router: {
|
|
6505
|
-
name: PACKAGE_NAME.router,
|
|
6506
|
-
version: "^1.0.0"
|
|
6507
|
-
}
|
|
6508
|
-
};
|
|
6626
|
+
skippedCount = 0;
|
|
6509
6627
|
/**
|
|
6510
6628
|
* Process a single Vue file (this method is called directly in CLI Watch mode)
|
|
6511
6629
|
*/
|
|
@@ -6532,10 +6650,13 @@ var FileProcessor = class {
|
|
|
6532
6650
|
const { shouldCompile, hash } = await this.fileCompiler.checkCacheStatus(
|
|
6533
6651
|
fileMeta,
|
|
6534
6652
|
record,
|
|
6535
|
-
() =>
|
|
6653
|
+
() => fs4.promises.readFile(absPath, "utf-8")
|
|
6536
6654
|
);
|
|
6537
|
-
if (!shouldCompile)
|
|
6538
|
-
|
|
6655
|
+
if (!shouldCompile) {
|
|
6656
|
+
this.skippedCount++;
|
|
6657
|
+
return;
|
|
6658
|
+
}
|
|
6659
|
+
const source = await fs4.promises.readFile(absPath, "utf-8");
|
|
6539
6660
|
if (!source.trim()) return;
|
|
6540
6661
|
const initUnit = {
|
|
6541
6662
|
...fileMeta,
|
|
@@ -6551,24 +6672,108 @@ var FileProcessor = class {
|
|
|
6551
6672
|
await this.compilationUnitProcessor.saveCompiledFiles(processed, key);
|
|
6552
6673
|
if (key === "sfc" /* SFC */ || key === "script" /* SCRIPT */) {
|
|
6553
6674
|
if (processed?.hasRoute) {
|
|
6554
|
-
await this.
|
|
6675
|
+
await this.addRouterToPackageJson();
|
|
6676
|
+
await this.updateEntryWithRouterProvider();
|
|
6555
6677
|
}
|
|
6556
6678
|
}
|
|
6557
6679
|
await this.cacheManager.updateCacheIncrementally(processed, key);
|
|
6558
6680
|
}
|
|
6559
6681
|
return processed;
|
|
6560
6682
|
}
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6683
|
+
/**
|
|
6684
|
+
* 对 package.json 注入路由依赖项
|
|
6685
|
+
*/
|
|
6686
|
+
async addRouterToPackageJson() {
|
|
6687
|
+
const { output } = this.fileCompiler.options;
|
|
6688
|
+
if (output?.bootstrapVite === false) {
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
const { router } = RUNTIME_PACKAGES;
|
|
6692
|
+
const filePath = this.fileCompiler.getOutputPkgPath();
|
|
6693
|
+
const packageJson = await this.fileCompiler.resolvePackageFile(filePath);
|
|
6694
|
+
if (packageJson?.dependencies?.[router.name]) {
|
|
6695
|
+
return;
|
|
6696
|
+
}
|
|
6697
|
+
if (!packageJson.dependencies) {
|
|
6698
|
+
packageJson.dependencies = {};
|
|
6699
|
+
}
|
|
6700
|
+
packageJson.dependencies[router.name] = router.version;
|
|
6701
|
+
const newData = JSON.stringify(packageJson, null, 2);
|
|
6702
|
+
await this.fileCompiler.writeFileWithDir(filePath, newData, {
|
|
6703
|
+
lock: true
|
|
6704
|
+
});
|
|
6705
|
+
}
|
|
6706
|
+
/**
|
|
6707
|
+
* 注入路由提供器到 React 应用的入口文件(如 main.tsx)
|
|
6708
|
+
*/
|
|
6709
|
+
async updateEntryWithRouterProvider() {
|
|
6710
|
+
const { exclude, output, router } = this.fileCompiler.options;
|
|
6711
|
+
const inputPath = this.fileCompiler.getInputPath();
|
|
6712
|
+
const outputPath = this.fileCompiler.getOuputPath(true);
|
|
6713
|
+
if (output?.bootstrapVite === false || router?.autoUpdateEntry === false || !router?.configFile) {
|
|
6714
|
+
return;
|
|
6715
|
+
}
|
|
6716
|
+
const getMainFile = async (filename) => {
|
|
6717
|
+
const filePath = path7.resolve(outputPath, filename);
|
|
6718
|
+
try {
|
|
6719
|
+
return { filePath, content: await fs4.promises.readFile(filePath, "utf-8") };
|
|
6720
|
+
} catch {
|
|
6721
|
+
return;
|
|
6722
|
+
}
|
|
6723
|
+
};
|
|
6724
|
+
const fileData = await getMainFile("main.tsx") || await getMainFile("main.jsx");
|
|
6725
|
+
if (!fileData) {
|
|
6726
|
+
console.warn(
|
|
6727
|
+
`${kleur6.yellow("\u26A0\uFE0F")} React application entry file not found, please confirm the filename is main.tsx or main.jsx?`
|
|
6728
|
+
);
|
|
6729
|
+
return;
|
|
6730
|
+
}
|
|
6731
|
+
const prepareRouterEntry = () => {
|
|
6732
|
+
const importPath = this.fileCompiler.resolveRelativePath(inputPath, router.configFile);
|
|
6733
|
+
let content = fileData.content;
|
|
6734
|
+
if (exclude?.includes(router.configFile) || exclude?.includes(importPath)) {
|
|
6735
|
+
return content;
|
|
6736
|
+
}
|
|
6737
|
+
const routerModule = "RouterInstance";
|
|
6738
|
+
if (content.includes(routerModule) || content.includes(importPath)) {
|
|
6739
|
+
return content;
|
|
6740
|
+
}
|
|
6741
|
+
const routerImport = `import ${routerModule} from '${importPath}'`;
|
|
6742
|
+
if (content.includes("./App")) {
|
|
6743
|
+
const appImportRegex = /import\s+(?:App|.*)\s+from\s+['"]\.\/App\.(?:tsx|jsx)['"]/;
|
|
6744
|
+
content = content.replace(appImportRegex, routerImport);
|
|
6745
|
+
} else {
|
|
6746
|
+
const lastImportMatch = content.match(/import.*from.*\n/g);
|
|
6747
|
+
if (lastImportMatch) {
|
|
6748
|
+
const lastImport = lastImportMatch.pop();
|
|
6749
|
+
content = content.replace(lastImport, `${lastImport}
|
|
6750
|
+
${routerImport}`);
|
|
6751
|
+
} else {
|
|
6752
|
+
content = `${routerImport}${content}`;
|
|
6753
|
+
}
|
|
6754
|
+
}
|
|
6755
|
+
const providerTag = `<${routerModule}.RouterProvider />`;
|
|
6756
|
+
fileData.content = content.replace(/<App\s*\/?>/g, providerTag);
|
|
6757
|
+
};
|
|
6758
|
+
prepareRouterEntry();
|
|
6759
|
+
await this.fileCompiler.writeFileWithDir(fileData.filePath, fileData.content);
|
|
6760
|
+
}
|
|
6761
|
+
/**
|
|
6762
|
+
* 获取跳过的文件数量
|
|
6763
|
+
*/
|
|
6764
|
+
getSkippedCount() {
|
|
6765
|
+
return this.skippedCount;
|
|
6766
|
+
}
|
|
6767
|
+
/**
|
|
6768
|
+
* 重置跳过的文件数量
|
|
6769
|
+
*/
|
|
6770
|
+
resetSkippedCount() {
|
|
6771
|
+
this.skippedCount = 0;
|
|
6567
6772
|
}
|
|
6568
6773
|
};
|
|
6569
6774
|
|
|
6570
6775
|
// src/compiler/shared/file-compiler/pipeline-manager.ts
|
|
6571
|
-
import
|
|
6776
|
+
import path8 from "path";
|
|
6572
6777
|
var PipelineManager = class {
|
|
6573
6778
|
constructor(fileCompiler, fileProcessor) {
|
|
6574
6779
|
this.fileCompiler = fileCompiler;
|
|
@@ -6603,7 +6808,7 @@ var PipelineManager = class {
|
|
|
6603
6808
|
const scriptExtRegex = /\.(js|ts)$/i;
|
|
6604
6809
|
const styleExtRegex = /\.(css|less|sass|scss)$/i;
|
|
6605
6810
|
const files = this.fileCompiler.scanFiles(inputPath, (p) => {
|
|
6606
|
-
const ext =
|
|
6811
|
+
const ext = path8.extname(p);
|
|
6607
6812
|
if (key === "sfc" /* SFC */) {
|
|
6608
6813
|
return ext === ".vue";
|
|
6609
6814
|
}
|
|
@@ -6615,28 +6820,21 @@ var PipelineManager = class {
|
|
|
6615
6820
|
}
|
|
6616
6821
|
return false;
|
|
6617
6822
|
});
|
|
6618
|
-
if (!files.length) return 0;
|
|
6619
|
-
const cache = await this.fileCompiler.loadCache(key);
|
|
6620
6823
|
const absFiles = new Set(files.map((f) => this.fileCompiler.getAbsPath(f)));
|
|
6621
6824
|
await this.cleanupManager.cleanupOldOutput(key, (c) => !absFiles.has(c.file));
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
} else {
|
|
6627
|
-
return this.fileProcessor.processFile(key, f, cache);
|
|
6628
|
-
}
|
|
6629
|
-
})
|
|
6825
|
+
if (!files.length) return 0;
|
|
6826
|
+
const cache = await this.fileCompiler.loadCache(key);
|
|
6827
|
+
const compiled = await Promise.all(
|
|
6828
|
+
files.map(async (f) => this.fileProcessor.processFile(key, f, cache))
|
|
6630
6829
|
);
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
return compiledCount;
|
|
6830
|
+
await this.fileCompiler.flushCache(key);
|
|
6831
|
+
return compiled.filter(Boolean).length;
|
|
6634
6832
|
}
|
|
6635
6833
|
/**
|
|
6636
6834
|
* 获取跳过的文件数量
|
|
6637
6835
|
*/
|
|
6638
6836
|
getSkippedCount() {
|
|
6639
|
-
return this.skippedCount;
|
|
6837
|
+
return this.skippedCount += this.fileProcessor.getSkippedCount();
|
|
6640
6838
|
}
|
|
6641
6839
|
/**
|
|
6642
6840
|
* 重置跳过的文件数量
|
|
@@ -6647,9 +6845,9 @@ var PipelineManager = class {
|
|
|
6647
6845
|
};
|
|
6648
6846
|
|
|
6649
6847
|
// src/compiler/shared/file-compiler/vite-bootstrapper.ts
|
|
6650
|
-
import { execSync
|
|
6651
|
-
import
|
|
6652
|
-
import
|
|
6848
|
+
import { execSync } from "child_process";
|
|
6849
|
+
import fs5 from "fs";
|
|
6850
|
+
import kleur7 from "kleur";
|
|
6653
6851
|
import ora from "ora";
|
|
6654
6852
|
var ViteBootstrapper = class {
|
|
6655
6853
|
constructor(fileCompiler, options) {
|
|
@@ -6657,21 +6855,19 @@ var ViteBootstrapper = class {
|
|
|
6657
6855
|
this.options = options;
|
|
6658
6856
|
}
|
|
6659
6857
|
spinner = ora();
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
version: "^1.0.0"
|
|
6664
|
-
}
|
|
6858
|
+
defaultConfig = {
|
|
6859
|
+
template: "react-ts",
|
|
6860
|
+
viteVersion: "@latest"
|
|
6665
6861
|
};
|
|
6666
6862
|
/**
|
|
6667
6863
|
* 检查是否需要初始化 Vite 环境
|
|
6668
6864
|
*/
|
|
6669
6865
|
isSingleFile() {
|
|
6670
6866
|
const inputPath = this.fileCompiler.getInputPath();
|
|
6671
|
-
if (!
|
|
6867
|
+
if (!fs5.existsSync(inputPath)) {
|
|
6672
6868
|
return false;
|
|
6673
6869
|
}
|
|
6674
|
-
const stat =
|
|
6870
|
+
const stat = fs5.statSync(inputPath);
|
|
6675
6871
|
return stat.isFile();
|
|
6676
6872
|
}
|
|
6677
6873
|
/**
|
|
@@ -6679,27 +6875,27 @@ var ViteBootstrapper = class {
|
|
|
6679
6875
|
*/
|
|
6680
6876
|
async bootstrapIfNeeded() {
|
|
6681
6877
|
const { bootstrapVite } = this.options.output || {};
|
|
6878
|
+
const workspaceDir = this.fileCompiler.getWorkspaceDir();
|
|
6879
|
+
await fs5.promises.mkdir(workspaceDir, { recursive: true });
|
|
6682
6880
|
if (bootstrapVite === false) {
|
|
6683
6881
|
return false;
|
|
6684
6882
|
}
|
|
6685
6883
|
if (this.isSingleFile()) {
|
|
6686
|
-
console.info(
|
|
6884
|
+
console.info("Skipping Vite initialization for single file compilation");
|
|
6687
6885
|
return false;
|
|
6688
6886
|
}
|
|
6689
|
-
const workspaceDir = this.fileCompiler.getWorkspaceDir();
|
|
6690
6887
|
const outputPkgPath = this.fileCompiler.getOutputPkgPath();
|
|
6691
|
-
if (
|
|
6888
|
+
if (fs5.existsSync(outputPkgPath)) {
|
|
6692
6889
|
return false;
|
|
6693
6890
|
}
|
|
6694
6891
|
this.spinner.start("Bootstrapping Vite React environment...");
|
|
6695
|
-
await fs4.promises.mkdir(workspaceDir, { recursive: true });
|
|
6696
6892
|
try {
|
|
6697
|
-
this.resolveViteCreateApp();
|
|
6893
|
+
await this.resolveViteCreateApp();
|
|
6698
6894
|
} catch (err) {
|
|
6699
6895
|
this.spinner.stop();
|
|
6700
6896
|
console.error(
|
|
6701
|
-
|
|
6702
|
-
"Failed to bootstrap Vite environment. Please check npm/network
|
|
6897
|
+
kleur7.red("\u2716"),
|
|
6898
|
+
"Failed to bootstrap Vite environment. Please check npm/network.",
|
|
6703
6899
|
err
|
|
6704
6900
|
);
|
|
6705
6901
|
return false;
|
|
@@ -6719,7 +6915,7 @@ var ViteBootstrapper = class {
|
|
|
6719
6915
|
...vite
|
|
6720
6916
|
};
|
|
6721
6917
|
if (!isDev) {
|
|
6722
|
-
const { runtime } =
|
|
6918
|
+
const { runtime } = RUNTIME_PACKAGES;
|
|
6723
6919
|
deps[runtime.name] = runtime.version;
|
|
6724
6920
|
}
|
|
6725
6921
|
return deps;
|
|
@@ -6731,274 +6927,239 @@ var ViteBootstrapper = class {
|
|
|
6731
6927
|
const newDevDeps = resolveDeps(rootPkg.devDependencies, vitePkg.devDependencies, true);
|
|
6732
6928
|
vitePkg.dependencies = newDeps;
|
|
6733
6929
|
vitePkg.devDependencies = newDevDeps;
|
|
6734
|
-
|
|
6930
|
+
const newVitePkg = JSON.stringify(vitePkg, null, 2);
|
|
6931
|
+
await this.fileCompiler.writeFileWithDir(outputPkgPath, newVitePkg);
|
|
6735
6932
|
this.spinner.succeed("Standard Vite React environment initialized");
|
|
6736
6933
|
return true;
|
|
6737
6934
|
}
|
|
6738
6935
|
/**
|
|
6739
6936
|
* 执行 vite 创建命令
|
|
6740
6937
|
*/
|
|
6741
|
-
resolveViteCreateApp() {
|
|
6938
|
+
async resolveViteCreateApp() {
|
|
6742
6939
|
const { output } = this.options;
|
|
6743
|
-
const
|
|
6744
|
-
const
|
|
6940
|
+
const { viteVersion, template: tmpl } = this.defaultConfig;
|
|
6941
|
+
const bootstrapVite = output?.bootstrapVite;
|
|
6745
6942
|
const outDirName = this.fileCompiler.getOutDirName();
|
|
6746
|
-
const
|
|
6747
|
-
|
|
6943
|
+
const configObject = typeof bootstrapVite === "object" ? bootstrapVite : null;
|
|
6944
|
+
const viteVer = configObject?.vite || viteVersion;
|
|
6945
|
+
const reactVer = configObject?.react;
|
|
6946
|
+
const template = configObject?.template || tmpl;
|
|
6947
|
+
const cmd = `npm create vite${viteVer} ${outDirName} -- --template ${template}`;
|
|
6948
|
+
execSync(cmd, {
|
|
6748
6949
|
cwd: this.fileCompiler.getWorkspaceDir(),
|
|
6749
6950
|
stdio: "ignore"
|
|
6750
6951
|
// 隐藏 create-vite 内部的输出日志,保持终端整洁
|
|
6751
6952
|
});
|
|
6953
|
+
if (reactVer) {
|
|
6954
|
+
await this.resolveReactVersion(reactVer);
|
|
6955
|
+
}
|
|
6752
6956
|
}
|
|
6753
|
-
};
|
|
6754
|
-
|
|
6755
|
-
// src/compiler/shared/file-compiler/index.ts
|
|
6756
|
-
var FileCompiler = class extends BaseCompiler {
|
|
6757
|
-
skippedCount = 0;
|
|
6758
|
-
spinner = ora2();
|
|
6759
|
-
// 管理器实例
|
|
6760
|
-
viteBootstrapper;
|
|
6761
|
-
pipelineManager;
|
|
6762
|
-
fileProcessor;
|
|
6763
|
-
compilationUnitProcessor;
|
|
6764
|
-
cacheManager;
|
|
6765
|
-
assetManager;
|
|
6766
|
-
cleanupManager;
|
|
6767
6957
|
/**
|
|
6768
|
-
*
|
|
6769
|
-
*
|
|
6770
|
-
* @param options - 编译器配置选项,继承自 BaseCompiler 的选项
|
|
6771
|
-
* 包括输入路径、输出配置、缓存设置、排除模式等
|
|
6772
|
-
* @see {@link CompilerOptions} 查看完整的选项说明
|
|
6958
|
+
* 处理 React 包版本
|
|
6959
|
+
* @param ver 版本号
|
|
6773
6960
|
*/
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
this.
|
|
6961
|
+
async resolveReactVersion(ver) {
|
|
6962
|
+
const outputPkgPath = this.fileCompiler.getOutputPkgPath();
|
|
6963
|
+
const vitePkg = await this.fileCompiler.resolvePackageFile(outputPkgPath);
|
|
6964
|
+
const typesVer = `^${ver.split(".")[0].replace(/@|\^/, "")}.0.0`;
|
|
6965
|
+
vitePkg.dependencies.react = ver;
|
|
6966
|
+
vitePkg.dependencies["react-dom"] = ver;
|
|
6967
|
+
vitePkg.devDependencies["@types/react"] = typesVer;
|
|
6968
|
+
vitePkg.devDependencies["@types/react-dom"] = typesVer;
|
|
6969
|
+
await this.fileCompiler.writeFileWithDir(outputPkgPath, JSON.stringify(vitePkg, null, 2), {
|
|
6970
|
+
lock: true
|
|
6971
|
+
});
|
|
6972
|
+
}
|
|
6973
|
+
};
|
|
6974
|
+
|
|
6975
|
+
// src/compiler/shared/file-compiler/setup-manager.ts
|
|
6976
|
+
var SetupManager = class {
|
|
6977
|
+
constructor(getCompiler) {
|
|
6978
|
+
this.getCompiler = getCompiler;
|
|
6979
|
+
this.setup();
|
|
6777
6980
|
}
|
|
6778
6981
|
/**
|
|
6779
6982
|
* 初始化所有管理器实例
|
|
6780
6983
|
*
|
|
6781
|
-
*
|
|
6984
|
+
* !必须按照依赖关系顺序创建各个管理器:
|
|
6782
6985
|
* 1. 基础管理器(无依赖)
|
|
6783
6986
|
* 2. 依赖基础管理器的管理器
|
|
6784
6987
|
* 3. 依赖其他管理器的管理器
|
|
6785
|
-
*
|
|
6786
|
-
* @private
|
|
6787
6988
|
*/
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
this.
|
|
6791
|
-
this.
|
|
6792
|
-
this.
|
|
6793
|
-
this.viteBootstrapper = new ViteBootstrapper(this, this.options);
|
|
6794
|
-
this.pipelineManager = new PipelineManager(this, this.fileProcessor);
|
|
6795
|
-
this.assetManager = new AssetManager(this, this.cleanupManager);
|
|
6989
|
+
setup() {
|
|
6990
|
+
const fileCompiler = this.getCompiler();
|
|
6991
|
+
this.setupBaseManager(fileCompiler);
|
|
6992
|
+
this.setupManagedByBase(fileCompiler);
|
|
6993
|
+
this.setupCompositeManager(fileCompiler);
|
|
6796
6994
|
}
|
|
6797
6995
|
/**
|
|
6798
|
-
*
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
*
|
|
6808
|
-
|
|
6809
|
-
|
|
6996
|
+
* 创建基础的管理器(无外部依赖)
|
|
6997
|
+
*/
|
|
6998
|
+
setupBaseManager(fileCompiler) {
|
|
6999
|
+
fileCompiler.manager = {};
|
|
7000
|
+
const manager = fileCompiler.manager;
|
|
7001
|
+
manager.cacheManager = new CacheManager(fileCompiler);
|
|
7002
|
+
manager.cleanupManager = new CleanupManager(fileCompiler);
|
|
7003
|
+
}
|
|
7004
|
+
/**
|
|
7005
|
+
* 创建依赖基础管理器的管理器
|
|
7006
|
+
*/
|
|
7007
|
+
setupManagedByBase(fileCompiler) {
|
|
7008
|
+
const manager = fileCompiler.manager;
|
|
7009
|
+
manager.fileProcessor = new FileProcessor(
|
|
7010
|
+
fileCompiler,
|
|
7011
|
+
new CompilationUnitProcessor(fileCompiler),
|
|
7012
|
+
manager.cacheManager
|
|
7013
|
+
);
|
|
7014
|
+
}
|
|
7015
|
+
/**
|
|
7016
|
+
* 创建依赖其他管理器的管理器
|
|
6810
7017
|
*/
|
|
7018
|
+
setupCompositeManager(fileCompiler) {
|
|
7019
|
+
const manager = fileCompiler.manager;
|
|
7020
|
+
manager.viteBootstrapper = new ViteBootstrapper(fileCompiler, fileCompiler.options);
|
|
7021
|
+
manager.pipelineManager = new PipelineManager(fileCompiler, manager.fileProcessor);
|
|
7022
|
+
manager.assetManager = new AssetManager(fileCompiler, manager.cleanupManager);
|
|
7023
|
+
}
|
|
7024
|
+
};
|
|
7025
|
+
|
|
7026
|
+
// src/compiler/shared/file-compiler/index.ts
|
|
7027
|
+
var FileCompiler = class extends BaseCompiler {
|
|
7028
|
+
manager;
|
|
7029
|
+
spinner = ora2();
|
|
7030
|
+
constructor(options = {}) {
|
|
7031
|
+
super(options);
|
|
7032
|
+
new SetupManager(() => this);
|
|
7033
|
+
}
|
|
7034
|
+
/** 执行完整的编译流程 */
|
|
6811
7035
|
async execute() {
|
|
6812
|
-
console.info("\n\n",
|
|
7036
|
+
console.info("\n\n", kleur8.magenta(`${kleur8.bold("VUREACT")} v${this.version}`), "\n");
|
|
6813
7037
|
const startTime = performance.now();
|
|
6814
|
-
|
|
6815
|
-
await
|
|
6816
|
-
}
|
|
6817
|
-
await this.viteBootstrapper.bootstrapIfNeeded();
|
|
7038
|
+
const rmWorkspace = async () => {
|
|
7039
|
+
await this.rmFile(this.getWorkspaceDir());
|
|
7040
|
+
};
|
|
6818
7041
|
try {
|
|
6819
|
-
this.
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
this.
|
|
6823
|
-
const
|
|
6824
|
-
this.
|
|
6825
|
-
this.
|
|
6826
|
-
const
|
|
6827
|
-
this.spinner.stop();
|
|
6828
|
-
this.spinner.start("Copying assets...");
|
|
6829
|
-
const assetCount = await this.assetManager.runAssetPipeline();
|
|
6830
|
-
this.spinner.stop();
|
|
7042
|
+
if (!this.getIsCache()) {
|
|
7043
|
+
await rmWorkspace();
|
|
7044
|
+
}
|
|
7045
|
+
await this.manager.viteBootstrapper.bootstrapIfNeeded();
|
|
7046
|
+
const sfcCount = await this.runPipelineWithSpinner("sfc" /* SFC */);
|
|
7047
|
+
const scriptCount = await this.runPipelineWithSpinner("script" /* SCRIPT */);
|
|
7048
|
+
const styleCount = await this.runPipelineWithSpinner("style" /* STYLE */);
|
|
7049
|
+
const assetCount = await this.runPipelineWithSpinner("copied" /* ASSET */);
|
|
6831
7050
|
await this.options.onSuccess?.();
|
|
6832
7051
|
const endTime = calcElapsedTime(startTime);
|
|
6833
7052
|
this.printCoreLogs();
|
|
6834
7053
|
this.showCompileStats(endTime, sfcCount, scriptCount, styleCount, assetCount);
|
|
6835
7054
|
} catch (error) {
|
|
6836
|
-
this.spinner.stop();
|
|
6837
7055
|
const endTime = calcElapsedTime(startTime);
|
|
6838
|
-
|
|
6839
|
-
`);
|
|
7056
|
+
await rmWorkspace();
|
|
7057
|
+
console.error(kleur8.red("\u2716"), `Build failed in ${endTime}`);
|
|
7058
|
+
console.error(error);
|
|
7059
|
+
} finally {
|
|
7060
|
+
this.resetSkippedCount();
|
|
6840
7061
|
}
|
|
6841
7062
|
}
|
|
6842
|
-
/**
|
|
6843
|
-
* 处理单个 Vue 单文件组件(SFC)
|
|
6844
|
-
*
|
|
6845
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
6846
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
6847
|
-
*
|
|
6848
|
-
* @async
|
|
6849
|
-
* @param filePath - Vue 文件的绝对路径
|
|
6850
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
6851
|
-
* @returns {Promise<SFCUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
6852
|
-
* @see {@link FileProcessor.processSFC}
|
|
6853
|
-
*/
|
|
7063
|
+
/** 处理单个 Vue 单文件组件(SFC) */
|
|
6854
7064
|
async processSFC(filePath, existingCache) {
|
|
6855
|
-
return this.fileProcessor.processSFC(filePath, existingCache);
|
|
7065
|
+
return this.manager.fileProcessor.processSFC(filePath, existingCache);
|
|
6856
7066
|
}
|
|
6857
|
-
/**
|
|
6858
|
-
* 处理单个 JavaScript/TypeScript 脚本文件
|
|
6859
|
-
*
|
|
6860
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
6861
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
6862
|
-
*
|
|
6863
|
-
* @async
|
|
6864
|
-
* @param filePath - 脚本文件的绝对路径
|
|
6865
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
6866
|
-
* @returns {Promise<ScriptUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
6867
|
-
* @see {@link FileProcessor.processScript}
|
|
6868
|
-
*/
|
|
7067
|
+
/** 处理单个 JavaScript/TypeScript 脚本文件 */
|
|
6869
7068
|
async processScript(filePath, existingCache) {
|
|
6870
|
-
return this.fileProcessor.processScript(filePath, existingCache);
|
|
7069
|
+
return this.manager.fileProcessor.processScript(filePath, existingCache);
|
|
6871
7070
|
}
|
|
6872
|
-
/**
|
|
6873
|
-
* 处理单个 CSS/LESS/SCSS 样式文件
|
|
6874
|
-
*
|
|
6875
|
-
* 此方法主要用于 CLI 的 watch 模式,当检测到文件变更时调用。
|
|
6876
|
-
* 支持增量编译,如果文件未变更则跳过编译。
|
|
6877
|
-
*
|
|
6878
|
-
* @async
|
|
6879
|
-
* @param filePath - style 文件的绝对路径
|
|
6880
|
-
* @param existingCache - 可选的预加载缓存对象,用于增量编译
|
|
6881
|
-
* @returns {Promise<ScriptUnit | undefined>} 编译单元对象,如果跳过编译则返回 undefined
|
|
6882
|
-
* @see {@link FileProcessor.processStyle}
|
|
6883
|
-
*/
|
|
7071
|
+
/** 处理单个 CSS/LESS/SCSS 样式文件 */
|
|
6884
7072
|
async processStyle(filePath, existingCache) {
|
|
6885
|
-
return this.fileProcessor.processStyle(filePath, existingCache);
|
|
7073
|
+
return this.manager.fileProcessor.processStyle(filePath, existingCache);
|
|
6886
7074
|
}
|
|
6887
|
-
/**
|
|
6888
|
-
* 处理单个文件(Vue 或 Script)
|
|
6889
|
-
*
|
|
6890
|
-
* 通用的文件处理方法,根据 CacheKey 类型自动选择处理逻辑。
|
|
6891
|
-
* 主要用于内部调用和统一的文件处理接口。
|
|
6892
|
-
*
|
|
6893
|
-
* @async
|
|
6894
|
-
* @param key - 文件类型标识(SFC 或 SCRIPT)
|
|
6895
|
-
* @param filePath - 文件的绝对路径
|
|
6896
|
-
* @param existingCache - 可选的预加载缓存对象
|
|
6897
|
-
* @returns {Promise<SFCUnit | ScriptUnit | undefined>} 编译单元对象
|
|
6898
|
-
* @see {@link FileProcessor.processFile}
|
|
6899
|
-
*/
|
|
7075
|
+
/** 处理单个文件(Vue 或 Script) */
|
|
6900
7076
|
async processFile(key, filePath, existingCache) {
|
|
6901
7077
|
if (key === "sfc" /* SFC */) {
|
|
6902
|
-
return this.fileProcessor.processFile(key, filePath, existingCache);
|
|
7078
|
+
return this.manager.fileProcessor.processFile(key, filePath, existingCache);
|
|
6903
7079
|
} else if (key === "script" /* SCRIPT */) {
|
|
6904
|
-
return this.fileProcessor.processFile(
|
|
7080
|
+
return this.manager.fileProcessor.processFile(
|
|
7081
|
+
key,
|
|
7082
|
+
filePath,
|
|
7083
|
+
existingCache
|
|
7084
|
+
);
|
|
6905
7085
|
}
|
|
6906
|
-
return this.fileProcessor.processFile(
|
|
7086
|
+
return this.manager.fileProcessor.processFile(
|
|
6907
7087
|
key,
|
|
6908
7088
|
filePath,
|
|
6909
7089
|
existingCache
|
|
6910
7090
|
);
|
|
6911
7091
|
}
|
|
6912
|
-
/**
|
|
6913
|
-
* 处理单个资源文件
|
|
6914
|
-
*
|
|
6915
|
-
* 比较文件与缓存,决定是否需要拷贝。
|
|
6916
|
-
* 资源文件包括图片、字体、样式文件等非编译文件。
|
|
6917
|
-
*
|
|
6918
|
-
* @async
|
|
6919
|
-
* @param filePath - 资源文件的绝对路径
|
|
6920
|
-
* @param existingCache - 可选的预加载缓存对象
|
|
6921
|
-
* @returns {Promise<FileCacheMeta>} 资源文件的缓存元数据
|
|
6922
|
-
* @see {@link AssetManager.processAsset}
|
|
6923
|
-
*/
|
|
7092
|
+
/** 处理单个资源文件 */
|
|
6924
7093
|
async processAsset(filePath, existingCache) {
|
|
6925
|
-
return this.assetManager.processAsset(filePath, existingCache);
|
|
7094
|
+
return this.manager.assetManager.processAsset(filePath, existingCache);
|
|
6926
7095
|
}
|
|
6927
|
-
/**
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
* 当源文件被删除或重命名时,需要清理对应的输出文件。
|
|
6931
|
-
* 主要用于 watch 模式下的文件删除处理。
|
|
6932
|
-
*
|
|
6933
|
-
* @async
|
|
6934
|
-
* @param targetPath - 源代码的路径(文件或文件夹)
|
|
6935
|
-
* @param type - 清理类型,指定是 SFC、SCRIPT 还是 ASSET
|
|
6936
|
-
* @returns {Promise<void>}
|
|
6937
|
-
* @see {@link CleanupManager.removeOutputPath}
|
|
6938
|
-
*/
|
|
6939
|
-
async removeOutputPath(targetPath, type) {
|
|
6940
|
-
return this.cleanupManager.removeOutputPath(targetPath, type);
|
|
7096
|
+
/** 批量保存缓存 */
|
|
7097
|
+
async flushCache(key) {
|
|
7098
|
+
await this.manager.cacheManager.flushCache(key);
|
|
6941
7099
|
}
|
|
6942
|
-
/**
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
* 在增量编译中,未变更的文件会被跳过。
|
|
6946
|
-
* 此方法返回当前编译会话中跳过的文件数量。
|
|
6947
|
-
*
|
|
6948
|
-
* @returns {number} 跳过的文件数量
|
|
6949
|
-
*/
|
|
6950
|
-
getSkippedCount() {
|
|
6951
|
-
return this.skippedCount;
|
|
7100
|
+
/** 删除指定路径对应的输出文件和缓存 */
|
|
7101
|
+
async removeOutputPath(targetPath, type) {
|
|
7102
|
+
return await this.manager.cleanupManager.removeOutputPath(targetPath, type);
|
|
6952
7103
|
}
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
7104
|
+
async runPipelineWithSpinner(name) {
|
|
7105
|
+
const options = {
|
|
7106
|
+
["sfc" /* SFC */]: {
|
|
7107
|
+
text: "Compiling Vue files...",
|
|
7108
|
+
pipeline: () => this.manager.pipelineManager.runSfcPipeline()
|
|
7109
|
+
},
|
|
7110
|
+
["script" /* SCRIPT */]: {
|
|
7111
|
+
text: "Compiling script files...",
|
|
7112
|
+
pipeline: () => this.manager.pipelineManager.runScriptPipeline()
|
|
7113
|
+
},
|
|
7114
|
+
["style" /* STYLE */]: {
|
|
7115
|
+
text: "Compiling style files...",
|
|
7116
|
+
pipeline: () => this.manager.pipelineManager.runStylePipeline()
|
|
7117
|
+
},
|
|
7118
|
+
["copied" /* ASSET */]: {
|
|
7119
|
+
text: "Copying assets...",
|
|
7120
|
+
pipeline: () => this.manager.assetManager.runAssetPipeline()
|
|
7121
|
+
}
|
|
7122
|
+
};
|
|
7123
|
+
const { text, pipeline } = options[name];
|
|
7124
|
+
try {
|
|
7125
|
+
this.spinner.start(text);
|
|
7126
|
+
return await pipeline();
|
|
7127
|
+
} catch (err) {
|
|
7128
|
+
throw err;
|
|
7129
|
+
} finally {
|
|
7130
|
+
this.spinner.stop();
|
|
7131
|
+
}
|
|
6960
7132
|
}
|
|
6961
|
-
/**
|
|
6962
|
-
* 显示编译统计信息
|
|
6963
|
-
*
|
|
6964
|
-
* 在编译完成后调用,显示以下信息:
|
|
6965
|
-
* 1. 编译耗时
|
|
6966
|
-
* 2. 输出目录
|
|
6967
|
-
* 3. 跳过的文件数量
|
|
6968
|
-
* 4. 处理的文件分类统计
|
|
6969
|
-
*
|
|
6970
|
-
* @private
|
|
6971
|
-
* @param endTime - 格式化后的编译耗时字符串
|
|
6972
|
-
* @param sfcCount - 处理的 Vue 文件数量
|
|
6973
|
-
* @param scriptCount - 处理的脚本文件数量
|
|
6974
|
-
* @param assetCount - 处理的资源文件数量
|
|
6975
|
-
*/
|
|
6976
7133
|
showCompileStats(endTime, sfcCount, scriptCount, styleCount, assetCount) {
|
|
6977
|
-
const dir = normalizePath(this.relativePath(this.getOuputPath()));
|
|
6978
7134
|
this.spinner.succeed(`Build completed in ${endTime}`);
|
|
6979
|
-
console.info(` Output directory: ${kleur6.dim(dir)}`);
|
|
6980
7135
|
console.info();
|
|
6981
|
-
this.skippedCount += this.pipelineManager.getSkippedCount();
|
|
6982
|
-
this.pipelineManager.resetSkippedCount();
|
|
6983
|
-
if (this.skippedCount) {
|
|
6984
|
-
console.info(kleur6.dim(`Skipped ${this.skippedCount} unchanged file(s)`));
|
|
6985
|
-
this.resetSkippedCount();
|
|
6986
|
-
}
|
|
6987
7136
|
if (sfcCount || scriptCount || styleCount || assetCount) {
|
|
6988
7137
|
const stats = [];
|
|
6989
7138
|
if (sfcCount) stats.push(`${sfcCount} SFC(s)`);
|
|
6990
7139
|
if (scriptCount) stats.push(`${scriptCount} script(s)`);
|
|
6991
7140
|
if (styleCount) stats.push(`${styleCount} style(s)`);
|
|
6992
7141
|
if (assetCount) stats.push(`${assetCount} asset(s)`);
|
|
6993
|
-
|
|
7142
|
+
this.spinner.succeed(`Processed: ${stats.join(", ")}`);
|
|
7143
|
+
}
|
|
7144
|
+
const skippedCount = this.manager.pipelineManager.getSkippedCount() + this.manager.assetManager.getSkippedCount();
|
|
7145
|
+
if (skippedCount) {
|
|
7146
|
+
console.info(kleur8.gray(`\u21B7 Cached: ${kleur8.white(skippedCount)} unchanged file(s)`));
|
|
7147
|
+
this.resetSkippedCount();
|
|
6994
7148
|
}
|
|
7149
|
+
const dir = normalizePath(this.relativePath(this.getOuputPath()));
|
|
7150
|
+
console.info();
|
|
7151
|
+
console.info(`\u{1F4E6} Output: ${dir}`);
|
|
6995
7152
|
console.info();
|
|
6996
7153
|
}
|
|
7154
|
+
resetSkippedCount() {
|
|
7155
|
+
this.manager.pipelineManager.resetSkippedCount();
|
|
7156
|
+
this.manager.assetManager.resetSkippedCount();
|
|
7157
|
+
}
|
|
6997
7158
|
};
|
|
6998
7159
|
|
|
6999
7160
|
// src/compiler/shared/define-config.ts
|
|
7000
|
-
function defineConfig(
|
|
7001
|
-
return
|
|
7161
|
+
function defineConfig(config) {
|
|
7162
|
+
return typeof config === "function" ? config() : config;
|
|
7002
7163
|
}
|
|
7003
7164
|
|
|
7004
7165
|
// src/compiler/index.ts
|
|
@@ -7006,6 +7167,7 @@ var VuReact = class extends FileCompiler {
|
|
|
7006
7167
|
};
|
|
7007
7168
|
|
|
7008
7169
|
export {
|
|
7170
|
+
getDirname,
|
|
7009
7171
|
normalizePath,
|
|
7010
7172
|
calcElapsedTime,
|
|
7011
7173
|
generateComponent,
|