@weapp-vite/ast 6.15.0 → 6.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/engine.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AstEngineName, AstParserLike } from "./types.mjs";
1
+ import { n as AstParserLike, t as AstEngineName } from "./types-Cn0gcZR9.mjs";
2
2
 
3
3
  //#region src/engine.d.ts
4
4
  /**
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { BABEL_TS_MODULE_PARSER_OPTIONS, BABEL_TS_MODULE_PLUGINS, generate, getVisitorKeys, parse, parseJsLike, traverse } from "./babel.mjs";
2
2
  import { getObjectPropertyByKey, getRenderPropertyFromComponentOptions, resolveRenderExpressionFromComponentOptions, resolveRenderableExpression, toStaticObjectKey, unwrapTypeScriptExpression } from "./babelNodes.mjs";
3
- import { AstEngineName, AstParserLike, WeappAstConfig } from "./types.mjs";
3
+ import { n as AstParserLike, r as WeappAstConfig, t as AstEngineName } from "./types-Cn0gcZR9.mjs";
4
4
  import { parseJsLikeWithEngine } from "./engine.mjs";
5
5
  import { ComponentPropMap, collectComponentPropsFromCode, collectComponentPropsWithBabel, collectComponentPropsWithOxc, extractComponentProperties, extractPropertiesObject, getStaticPropertyName, mapConstructorName, mayContainComponentPropsShape, mergeComponentPropTypes, resolveOptionsObjectExpression, resolveOptionsObjectExpressionWithBabel, resolveTypeFromNode } from "./operations/componentProps.mjs";
6
6
  import { FeatureFlagOptions, collectFeatureFlagsFromCode, collectFeatureFlagsWithBabel, collectFeatureFlagsWithOxc, consumeNamedFeatureFlag, consumeNamespaceFeatureFlag, mayContainFeatureFlagHints, registerNamedFeatureFlagLocal, registerNamespaceFeatureFlagLocal } from "./operations/featureFlags.mjs";
7
7
  import { JsxAutoComponentAnalysisOptions, JsxAutoComponentContext, JsxBabelModuleAnalysisOptions, JsxImportedComponent, collectJsxAutoComponentsFromCode, collectJsxAutoComponentsWithBabel, collectJsxAutoComponentsWithOxc, collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, collectJsxTemplateTagsFromOxc, createJsxImportedComponent, defaultIsDefineComponentSource, defaultResolveBabelComponentExpression, defaultResolveBabelRenderExpression, getJsxImportLocalName, getJsxImportedName, getJsxOxcStaticPropertyName, isJsxDefineComponentImportSpecifier, mayContainJsxAutoComponentEntry, resolveOxcComponentExpression, resolveOxcRenderExpression, unwrapOxcExpression } from "./operations/jsxAutoComponents.mjs";
8
- import { collectOnPageScrollPerformanceWarnings, collectOnPageScrollWarningsWithBabel, collectOnPageScrollWarningsWithOxc, collectPageScrollInspection, collectPageScrollInspectionWithOxc, createLineStartOffsets, createWarningPrefix, getCallExpressionCalleeName, getLocationFromOffset, getMemberExpressionPropertyName, getOnPageScrollCallbackArgument, getOxcCallExpressionCalleeName, getOxcMemberExpressionPropertyName, getOxcStaticPropertyName, isOnPageScrollCallee, isOxcFunctionLike, isOxcOnPageScrollCallee, isStaticPropertyName } from "./operations/onPageScroll.mjs";
8
+ import { _ as collectOnPageScrollWarningsWithBabel, a as getLocationFromOffset, c as getOxcCallExpressionCalleeName, d as isOnPageScrollCallee, f as isOxcFunctionLike, g as collectPageScrollInspectionWithOxc, h as collectOnPageScrollWarningsWithOxc, i as getCallExpressionCalleeName, l as getOxcMemberExpressionPropertyName, m as isStaticPropertyName, n as createLineStartOffsets, o as getMemberExpressionPropertyName, p as isOxcOnPageScrollCallee, r as createWarningPrefix, s as getOnPageScrollCallbackArgument, t as collectOnPageScrollPerformanceWarnings, u as getOxcStaticPropertyName, v as collectPageScrollInspection } from "./onPageScroll-C9pqH5L1.mjs";
9
9
  import { hasPlatformApiMemberExpression, isPlatformApiIdentifier, isPlatformApiMemberExpression, mayContainPlatformApiAccess, mayContainPlatformApiIdentifierByText, platformApiIdentifierList, platformApiIdentifiers } from "./operations/platformApi.mjs";
10
10
  import { RequireToken, collectRequireTokens, getRequireAsyncLiteralToken, getStaticRequireLiteralValue, hasStaticRequireCall, isStaticRequireCall, mayContainRequireCallByText, mayContainStaticRequireLiteral } from "./operations/require.mjs";
11
11
  import { ScriptSetupImport, collectScriptSetupImportsFromCode, collectScriptSetupImportsWithBabel, collectScriptSetupImportsWithOxc, createScriptSetupImport, getScriptSetupImportedName, mayContainRelevantScriptSetupImports } from "./operations/scriptSetupImports.mjs";
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { n as oxcAstEngine, r as babelAstEngine, t as parseJsLikeWithEngine } fr
4
4
  import { collectComponentPropsFromCode, collectComponentPropsWithBabel, collectComponentPropsWithOxc, extractComponentProperties, extractPropertiesObject, getStaticPropertyName, mapConstructorName, mayContainComponentPropsShape, mergeComponentPropTypes, resolveOptionsObjectExpression, resolveOptionsObjectExpressionWithBabel, resolveTypeFromNode } from "./operations/componentProps.mjs";
5
5
  import { collectFeatureFlagsFromCode, collectFeatureFlagsWithBabel, collectFeatureFlagsWithOxc, consumeNamedFeatureFlag, consumeNamespaceFeatureFlag, mayContainFeatureFlagHints, registerNamedFeatureFlagLocal, registerNamespaceFeatureFlagLocal } from "./operations/featureFlags.mjs";
6
6
  import { collectJsxAutoComponentsFromCode, collectJsxAutoComponentsWithBabel, collectJsxAutoComponentsWithOxc, collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, collectJsxTemplateTagsFromOxc, createJsxImportedComponent, defaultIsDefineComponentSource, defaultResolveBabelComponentExpression, defaultResolveBabelRenderExpression, getJsxImportLocalName, getJsxImportedName, getJsxOxcStaticPropertyName, isJsxDefineComponentImportSpecifier, mayContainJsxAutoComponentEntry, resolveOxcComponentExpression, resolveOxcRenderExpression, unwrapOxcExpression } from "./operations/jsxAutoComponents.mjs";
7
- import { collectOnPageScrollPerformanceWarnings, collectOnPageScrollWarningsWithBabel, collectOnPageScrollWarningsWithOxc, collectPageScrollInspection, collectPageScrollInspectionWithOxc, createLineStartOffsets, createWarningPrefix, getCallExpressionCalleeName, getLocationFromOffset, getMemberExpressionPropertyName, getOnPageScrollCallbackArgument, getOxcCallExpressionCalleeName, getOxcMemberExpressionPropertyName, getOxcStaticPropertyName, isOnPageScrollCallee, isOxcFunctionLike, isOxcOnPageScrollCallee, isStaticPropertyName } from "./operations/onPageScroll.mjs";
7
+ import { _ as isOxcOnPageScrollCallee, a as collectPageScrollInspection, c as getCallExpressionCalleeName, d as getOnPageScrollCallbackArgument, f as getOxcCallExpressionCalleeName, g as isOxcFunctionLike, h as isOnPageScrollCallee, i as collectOnPageScrollWarningsWithBabel, l as getLocationFromOffset, m as getOxcStaticPropertyName, n as collectOnPageScrollWarningsWithOxc, o as createLineStartOffsets, p as getOxcMemberExpressionPropertyName, r as collectPageScrollInspectionWithOxc, s as createWarningPrefix, t as collectOnPageScrollPerformanceWarnings, u as getMemberExpressionPropertyName, v as isStaticPropertyName } from "./onPageScroll-FN_gheDb.mjs";
8
8
  import { hasPlatformApiMemberExpression, isPlatformApiIdentifier, isPlatformApiMemberExpression, mayContainPlatformApiAccess, mayContainPlatformApiIdentifierByText, platformApiIdentifierList, platformApiIdentifiers } from "./operations/platformApi.mjs";
9
9
  import { collectRequireTokens, getRequireAsyncLiteralToken, getStaticRequireLiteralValue, hasStaticRequireCall, isStaticRequireCall, mayContainRequireCallByText, mayContainStaticRequireLiteral } from "./operations/require.mjs";
10
10
  import { collectScriptSetupImportsFromCode, collectScriptSetupImportsWithBabel, collectScriptSetupImportsWithOxc, createScriptSetupImport, getScriptSetupImportedName, mayContainRelevantScriptSetupImports } from "./operations/scriptSetupImports.mjs";
@@ -0,0 +1,48 @@
1
+ import { t as AstEngineName } from "./types-Cn0gcZR9.mjs";
2
+ import * as t from "@babel/types";
3
+
4
+ //#region src/operations/onPageScroll/types.d.ts
5
+ interface PageScrollInspection {
6
+ empty: boolean;
7
+ hasSetDataCall: boolean;
8
+ syncApis: Set<string>;
9
+ }
10
+ interface OxcLoc {
11
+ line: number;
12
+ column: number;
13
+ }
14
+ //#endregion
15
+ //#region src/operations/onPageScroll/babel.d.ts
16
+ declare function collectPageScrollInspection(functionPath: any, node: t.ArrowFunctionExpression | t.FunctionExpression | t.ObjectMethod): PageScrollInspection;
17
+ declare function collectOnPageScrollWarningsWithBabel(code: string, filename: string): string[];
18
+ //#endregion
19
+ //#region src/operations/onPageScroll/oxc.d.ts
20
+ declare function collectPageScrollInspectionWithOxc(node: any): PageScrollInspection;
21
+ declare function collectOnPageScrollWarningsWithOxc(code: string, filename: string): string[];
22
+ //#endregion
23
+ //#region src/operations/onPageScroll/shared.d.ts
24
+ declare function isStaticPropertyName(key: t.Expression | t.Identifier | t.PrivateName): string | undefined;
25
+ declare function getMemberExpressionPropertyName(node: t.MemberExpression | t.OptionalMemberExpression): string | undefined;
26
+ declare function isOnPageScrollCallee(callee: t.Expression | t.V8IntrinsicIdentifier, hookNames: Set<string>, namespaceImports: Set<string>): boolean;
27
+ declare function getCallExpressionCalleeName(callee: t.Expression | t.V8IntrinsicIdentifier): string | undefined;
28
+ declare function getOnPageScrollCallbackArgument(node: {
29
+ arguments?: Array<t.Expression | t.SpreadElement | t.ArgumentPlaceholder | null>;
30
+ }): t.FunctionExpression | t.ArrowFunctionExpression | undefined;
31
+ declare function createWarningPrefix(filename: string, line?: number, column?: number): string;
32
+ declare function getOxcStaticPropertyName(node: any): string | undefined;
33
+ declare function getOxcMemberExpressionPropertyName(node: any): string | undefined;
34
+ declare function isOxcFunctionLike(node: any): boolean;
35
+ declare function isOxcOnPageScrollCallee(callee: any, hookNames: Set<string>, namespaceImports: Set<string>): boolean;
36
+ declare function getOxcCallExpressionCalleeName(callee: any): string | undefined;
37
+ declare function createLineStartOffsets(code: string): number[];
38
+ declare function getLocationFromOffset(offset: number | undefined, lineStarts: number[]): OxcLoc | undefined;
39
+ //#endregion
40
+ //#region src/operations/onPageScroll/index.d.ts
41
+ /**
42
+ * 静态检测 onPageScroll 中的常见性能风险并返回告警文案。
43
+ */
44
+ declare function collectOnPageScrollPerformanceWarnings(code: string, filename: string, options?: {
45
+ engine?: AstEngineName;
46
+ }): string[];
47
+ //#endregion
48
+ export { collectOnPageScrollWarningsWithBabel as _, getLocationFromOffset as a, getOxcCallExpressionCalleeName as c, isOnPageScrollCallee as d, isOxcFunctionLike as f, collectPageScrollInspectionWithOxc as g, collectOnPageScrollWarningsWithOxc as h, getCallExpressionCalleeName as i, getOxcMemberExpressionPropertyName as l, isStaticPropertyName as m, createLineStartOffsets as n, getMemberExpressionPropertyName as o, isOxcOnPageScrollCallee as p, createWarningPrefix as r, getOnPageScrollCallbackArgument as s, collectOnPageScrollPerformanceWarnings as t, getOxcStaticPropertyName as u, collectPageScrollInspection as v };
@@ -0,0 +1,271 @@
1
+ import { parseJsLike, traverse } from "./babel.mjs";
2
+ import { t as parseJsLikeWithEngine } from "./engine-DHqNPCDA.mjs";
3
+ //#region src/operations/onPageScroll/shared.ts
4
+ function isStaticPropertyName(key) {
5
+ if (key.type === "Identifier") return key.name;
6
+ if (key.type === "StringLiteral") return key.value;
7
+ }
8
+ function getMemberExpressionPropertyName(node) {
9
+ if (node.computed) return node.property.type === "StringLiteral" ? node.property.value : void 0;
10
+ return node.property.type === "Identifier" ? node.property.name : void 0;
11
+ }
12
+ function isOnPageScrollCallee(callee, hookNames, namespaceImports) {
13
+ if (callee.type === "Identifier") return hookNames.has(callee.name);
14
+ if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
15
+ const object = callee.object;
16
+ const propName = getMemberExpressionPropertyName(callee);
17
+ return object.type === "Identifier" && namespaceImports.has(object.name) && propName === "onPageScroll";
18
+ }
19
+ return false;
20
+ }
21
+ function getCallExpressionCalleeName(callee) {
22
+ if (callee.type === "Identifier") return callee.name;
23
+ if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") return getMemberExpressionPropertyName(callee);
24
+ }
25
+ function getOnPageScrollCallbackArgument(node) {
26
+ const arg0 = node.arguments?.[0];
27
+ if (!arg0 || arg0.type === "SpreadElement") return;
28
+ return arg0.type === "FunctionExpression" || arg0.type === "ArrowFunctionExpression" ? arg0 : void 0;
29
+ }
30
+ function createWarningPrefix(filename, line, column) {
31
+ return `[weapp-vite][onPageScroll] ${filename}:${typeof line === "number" && typeof column === "number" ? `${line}:${column}` : "?:?"}`;
32
+ }
33
+ function getOxcStaticPropertyName(node) {
34
+ if (!node) return;
35
+ if (node.type === "Identifier") return node.name;
36
+ if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return node.value;
37
+ }
38
+ function getOxcMemberExpressionPropertyName(node) {
39
+ if (!node || node.type !== "MemberExpression") return;
40
+ if (node.computed) return getOxcStaticPropertyName(node.property);
41
+ return node.property?.type === "Identifier" ? node.property.name : void 0;
42
+ }
43
+ function isOxcFunctionLike(node) {
44
+ return node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression";
45
+ }
46
+ function isOxcOnPageScrollCallee(callee, hookNames, namespaceImports) {
47
+ if (!callee) return false;
48
+ if (callee.type === "Identifier") return hookNames.has(callee.name);
49
+ if (callee.type === "MemberExpression") {
50
+ const propName = getOxcMemberExpressionPropertyName(callee);
51
+ return callee.object?.type === "Identifier" && namespaceImports.has(callee.object.name) && propName === "onPageScroll";
52
+ }
53
+ return false;
54
+ }
55
+ function getOxcCallExpressionCalleeName(callee) {
56
+ if (!callee) return;
57
+ if (callee.type === "Identifier") return callee.name;
58
+ if (callee.type === "MemberExpression") return getOxcMemberExpressionPropertyName(callee);
59
+ }
60
+ function createLineStartOffsets(code) {
61
+ const offsets = [0];
62
+ for (let index = 0; index < code.length; index += 1) if (code.charCodeAt(index) === 10) offsets.push(index + 1);
63
+ return offsets;
64
+ }
65
+ function getLocationFromOffset(offset, lineStarts) {
66
+ if (typeof offset !== "number" || offset < 0) return;
67
+ let low = 0;
68
+ let high = lineStarts.length - 1;
69
+ while (low <= high) {
70
+ const mid = Math.floor((low + high) / 2);
71
+ if (lineStarts[mid] <= offset) low = mid + 1;
72
+ else high = mid - 1;
73
+ }
74
+ const lineIndex = Math.max(0, low - 1);
75
+ return {
76
+ line: lineIndex + 1,
77
+ column: offset - lineStarts[lineIndex] + 1
78
+ };
79
+ }
80
+ //#endregion
81
+ //#region src/operations/onPageScroll/babel.ts
82
+ function collectPageScrollInspection(functionPath, node) {
83
+ const inspection = {
84
+ empty: node.body.type === "BlockStatement" && node.body.body.length === 0,
85
+ hasSetDataCall: false,
86
+ syncApis: /* @__PURE__ */ new Set()
87
+ };
88
+ functionPath.traverse({
89
+ Function(innerPath) {
90
+ if (innerPath !== functionPath) innerPath.skip();
91
+ },
92
+ CallExpression(callPath) {
93
+ const callee = callPath.node.callee;
94
+ if (getCallExpressionCalleeName(callee) === "setData") inspection.hasSetDataCall = true;
95
+ if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
96
+ const object = callee.object;
97
+ if (object.type === "Identifier" && object.name === "wx") {
98
+ const propertyName = getMemberExpressionPropertyName(callee);
99
+ if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
100
+ }
101
+ }
102
+ },
103
+ OptionalCallExpression(callPath) {
104
+ const callee = callPath.node.callee;
105
+ if (getCallExpressionCalleeName(callee) === "setData") inspection.hasSetDataCall = true;
106
+ if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
107
+ const object = callee.object;
108
+ if (object.type === "Identifier" && object.name === "wx") {
109
+ const propertyName = getMemberExpressionPropertyName(callee);
110
+ if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
111
+ }
112
+ }
113
+ }
114
+ });
115
+ return inspection;
116
+ }
117
+ function collectOnPageScrollWarningsWithBabel(code, filename) {
118
+ const ast = parseJsLike(code);
119
+ const onPageScrollHookNames = new Set(["onPageScroll"]);
120
+ const namespaceImports = /* @__PURE__ */ new Set();
121
+ for (const statement of ast.program.body) {
122
+ if (statement.type !== "ImportDeclaration" || statement.source.value !== "wevu") continue;
123
+ for (const specifier of statement.specifiers) {
124
+ if (specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === "onPageScroll") onPageScrollHookNames.add(specifier.local.name);
125
+ if (specifier.type === "ImportNamespaceSpecifier") namespaceImports.add(specifier.local.name);
126
+ }
127
+ }
128
+ const warnings = [];
129
+ const warningSet = /* @__PURE__ */ new Set();
130
+ const addWarning = (warning) => {
131
+ if (warningSet.has(warning)) return;
132
+ warningSet.add(warning);
133
+ warnings.push(warning);
134
+ };
135
+ const reportInspection = (functionPath, node, sourceLabel) => {
136
+ const inspection = collectPageScrollInspection(functionPath, node);
137
+ const line = node.loc?.start.line;
138
+ const prefix = createWarningPrefix(filename, line, typeof node.loc?.start.column === "number" ? node.loc.start.column + 1 : void 0);
139
+ if (inspection.empty) addWarning(`${prefix} 检测到空的 ${sourceLabel} 回调,建议移除无效监听以降低滚动时调度开销。`);
140
+ if (inspection.hasSetDataCall) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用 setData,建议改用节流、IntersectionObserver 或合并更新。`);
141
+ for (const syncApi of inspection.syncApis) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用同步 API(${syncApi}),可能阻塞渲染线程。`);
142
+ };
143
+ traverse(ast, {
144
+ ObjectMethod(path) {
145
+ if (isStaticPropertyName(path.node.key) !== "onPageScroll") return;
146
+ reportInspection(path, path.node, "onPageScroll");
147
+ },
148
+ ObjectProperty(path) {
149
+ if (path.node.computed) return;
150
+ if (isStaticPropertyName(path.node.key) !== "onPageScroll") return;
151
+ const value = path.node.value;
152
+ if (value.type !== "FunctionExpression" && value.type !== "ArrowFunctionExpression") return;
153
+ reportInspection(path.get("value"), value, "onPageScroll");
154
+ },
155
+ CallExpression(path) {
156
+ if (!isOnPageScrollCallee(path.node.callee, onPageScrollHookNames, namespaceImports)) return;
157
+ const arg0 = getOnPageScrollCallbackArgument(path.node);
158
+ if (!arg0) return;
159
+ reportInspection(path.get("arguments.0"), arg0, "onPageScroll(...)");
160
+ },
161
+ OptionalCallExpression(path) {
162
+ if (!isOnPageScrollCallee(path.node.callee, onPageScrollHookNames, namespaceImports)) return;
163
+ const arg0 = getOnPageScrollCallbackArgument(path.node);
164
+ if (!arg0) return;
165
+ reportInspection(path.get("arguments.0"), arg0, "onPageScroll(...)");
166
+ }
167
+ });
168
+ return warnings;
169
+ }
170
+ //#endregion
171
+ //#region src/operations/onPageScroll/oxc.ts
172
+ function collectPageScrollInspectionWithOxc(node) {
173
+ const inspection = {
174
+ empty: node.body?.type === "BlockStatement" && node.body.body.length === 0,
175
+ hasSetDataCall: false,
176
+ syncApis: /* @__PURE__ */ new Set()
177
+ };
178
+ const root = node.body?.type === "BlockStatement" ? node.body : node.body;
179
+ function visit(current, allowNestedFunctions = false) {
180
+ if (!current) return;
181
+ if (!allowNestedFunctions && (current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression")) return;
182
+ if (current.type === "CallExpression") {
183
+ if (getOxcCallExpressionCalleeName(current.callee) === "setData") inspection.hasSetDataCall = true;
184
+ if (current.callee?.type === "MemberExpression" && current.callee.object?.type === "Identifier" && current.callee.object.name === "wx") {
185
+ const propertyName = getOxcMemberExpressionPropertyName(current.callee);
186
+ if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
187
+ }
188
+ } else if (current.type === "ChainExpression") {
189
+ visit(current.expression, allowNestedFunctions);
190
+ return;
191
+ }
192
+ for (const value of Object.values(current)) {
193
+ if (!value) continue;
194
+ if (Array.isArray(value)) {
195
+ for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
196
+ } else if (typeof value === "object" && typeof value.type === "string") visit(value);
197
+ }
198
+ }
199
+ if (root) visit(root, true);
200
+ return inspection;
201
+ }
202
+ function collectOnPageScrollWarningsWithOxc(code, filename) {
203
+ const ast = parseJsLikeWithEngine(code, {
204
+ engine: "oxc",
205
+ filename: "inline.ts"
206
+ });
207
+ const onPageScrollHookNames = new Set(["onPageScroll"]);
208
+ const namespaceImports = /* @__PURE__ */ new Set();
209
+ for (const statement of ast.body ?? []) {
210
+ if (statement?.type !== "ImportDeclaration" || statement.source?.value !== "wevu") continue;
211
+ for (const specifier of statement.specifiers ?? []) if (specifier.type === "ImportSpecifier" && specifier.imported?.type === "Identifier" && specifier.imported.name === "onPageScroll" && specifier.local?.type === "Identifier") onPageScrollHookNames.add(specifier.local.name);
212
+ else if (specifier.type === "ImportNamespaceSpecifier" && specifier.local?.type === "Identifier") namespaceImports.add(specifier.local.name);
213
+ }
214
+ const lineStarts = createLineStartOffsets(code);
215
+ const warnings = [];
216
+ const warningSet = /* @__PURE__ */ new Set();
217
+ const addWarning = (warning) => {
218
+ if (warningSet.has(warning)) return;
219
+ warningSet.add(warning);
220
+ warnings.push(warning);
221
+ };
222
+ const reportInspection = (node, sourceLabel, startOffset = node.start) => {
223
+ const inspection = collectPageScrollInspectionWithOxc(node);
224
+ const loc = getLocationFromOffset(startOffset, lineStarts);
225
+ const prefix = createWarningPrefix(filename, loc?.line, loc?.column);
226
+ if (inspection.empty) addWarning(`${prefix} 检测到空的 ${sourceLabel} 回调,建议移除无效监听以降低滚动时调度开销。`);
227
+ if (inspection.hasSetDataCall) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用 setData,建议改用节流、IntersectionObserver 或合并更新。`);
228
+ for (const syncApi of inspection.syncApis) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用同步 API(${syncApi}),可能阻塞渲染线程。`);
229
+ };
230
+ function visit(node) {
231
+ if (!node) return;
232
+ if (node.type === "Property" && !node.computed && getOxcStaticPropertyName(node.key) === "onPageScroll" && isOxcFunctionLike(node.value)) {
233
+ const startOffset = node.method ? node.key?.end : node.value.start;
234
+ reportInspection(node.value, "onPageScroll", startOffset);
235
+ } else if (node.type === "CallExpression" && isOxcOnPageScrollCallee(node.callee, onPageScrollHookNames, namespaceImports)) {
236
+ const arg0 = node.arguments?.[0];
237
+ if (arg0 && arg0.type !== "SpreadElement" && isOxcFunctionLike(arg0)) reportInspection(arg0, "onPageScroll(...)");
238
+ } else if (node.type === "ChainExpression" && node.expression?.type === "CallExpression") {
239
+ const arg0 = node.expression.arguments?.[0];
240
+ if (isOxcOnPageScrollCallee(node.expression.callee, onPageScrollHookNames, namespaceImports) && arg0 && arg0.type !== "SpreadElement" && isOxcFunctionLike(arg0)) reportInspection(arg0, "onPageScroll(...)");
241
+ }
242
+ for (const value of Object.values(node)) {
243
+ if (!value) continue;
244
+ if (Array.isArray(value)) {
245
+ for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
246
+ } else if (typeof value === "object" && typeof value.type === "string") visit(value);
247
+ }
248
+ }
249
+ visit(ast);
250
+ return warnings;
251
+ }
252
+ //#endregion
253
+ //#region src/operations/onPageScroll/index.ts
254
+ /**
255
+ * 静态检测 onPageScroll 中的常见性能风险并返回告警文案。
256
+ */
257
+ function collectOnPageScrollPerformanceWarnings(code, filename, options) {
258
+ if (!code.includes("onPageScroll")) return [];
259
+ if (options?.engine === "oxc") try {
260
+ return collectOnPageScrollWarningsWithOxc(code, filename);
261
+ } catch {
262
+ return [];
263
+ }
264
+ try {
265
+ return collectOnPageScrollWarningsWithBabel(code, filename);
266
+ } catch {
267
+ return [];
268
+ }
269
+ }
270
+ //#endregion
271
+ export { isOxcOnPageScrollCallee as _, collectPageScrollInspection as a, getCallExpressionCalleeName as c, getOnPageScrollCallbackArgument as d, getOxcCallExpressionCalleeName as f, isOxcFunctionLike as g, isOnPageScrollCallee as h, collectOnPageScrollWarningsWithBabel as i, getLocationFromOffset as l, getOxcStaticPropertyName as m, collectOnPageScrollWarningsWithOxc as n, createLineStartOffsets as o, getOxcMemberExpressionPropertyName as p, collectPageScrollInspectionWithOxc as r, createWarningPrefix as s, collectOnPageScrollPerformanceWarnings as t, getMemberExpressionPropertyName as u, isStaticPropertyName as v };
@@ -1,4 +1,4 @@
1
- import { AstEngineName } from "../types.mjs";
1
+ import { t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
  import * as t from "@babel/types";
3
3
  import { NodePath } from "@babel/traverse";
4
4
 
@@ -1,4 +1,4 @@
1
- import { AstEngineName } from "../types.mjs";
1
+ import { t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
 
3
3
  //#region src/operations/featureFlags.d.ts
4
4
  interface FeatureFlagOptions<TFeature extends string> {
@@ -1,8 +1,8 @@
1
- import { AstEngineName } from "../types.mjs";
1
+ import { t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
  import * as t from "@babel/types";
3
3
  import { Expression, ObjectExpression } from "@babel/types";
4
4
 
5
- //#region src/operations/jsxAutoComponents.d.ts
5
+ //#region src/operations/jsxAutoComponents/types.d.ts
6
6
  interface JsxImportedComponent {
7
7
  localName: string;
8
8
  importSource: string;
@@ -24,12 +24,8 @@ interface JsxBabelModuleAnalysisOptions {
24
24
  isDefineComponentSource?: (source: string) => boolean;
25
25
  resolveBabelComponentExpression?: (declaration: t.Declaration | t.Expression | null, defineComponentDecls: Map<string, ObjectExpression>, defineComponentAliases: Set<string>) => Expression | null;
26
26
  }
27
- declare function mayContainJsxAutoComponentEntry(source: string): boolean;
28
- declare function defaultIsDefineComponentSource(source: string): source is "vue";
29
- declare function getJsxImportedName(imported: any): any;
30
- declare function createJsxImportedComponent(localName: string, importSource: string, kind: JsxImportedComponent['kind'], imported?: any): JsxImportedComponent;
31
- declare function getJsxImportLocalName(specifier: any): any;
32
- declare function isJsxDefineComponentImportSpecifier(specifier: any): boolean;
27
+ //#endregion
28
+ //#region src/operations/jsxAutoComponents/babel.d.ts
33
29
  declare function defaultResolveBabelComponentExpression(declaration: t.Declaration | t.Expression | null, defineComponentDecls: Map<string, ObjectExpression>, defineComponentAliases: Set<string>): Expression | null;
34
30
  declare function defaultResolveBabelRenderExpression(componentExpr: Expression): Expression | null;
35
31
  declare function collectJsxImportedComponentsAndDefaultExportFromBabelAst(ast: t.File, options?: JsxBabelModuleAnalysisOptions): {
@@ -37,13 +33,25 @@ declare function collectJsxImportedComponentsAndDefaultExportFromBabelAst(ast: t
37
33
  exportDefaultExpression: null;
38
34
  };
39
35
  declare function collectJsxTemplateTagsFromBabelExpression(renderExpression: Expression, isCollectableTag: (tag: string) => boolean): Set<string>;
36
+ declare function collectJsxAutoComponentsWithBabel(source: string, options: Required<JsxAutoComponentAnalysisOptions>): JsxAutoComponentContext;
37
+ //#endregion
38
+ //#region src/operations/jsxAutoComponents/oxc.d.ts
40
39
  declare function unwrapOxcExpression(node: any): any;
41
40
  declare function getJsxOxcStaticPropertyName(node: any): any;
42
41
  declare function resolveOxcComponentExpression(declaration: any, defineComponentDecls: Map<string, any>, defineComponentAliases: Set<string>): any;
43
42
  declare function resolveOxcRenderExpression(componentExpr: any): any;
44
43
  declare function collectJsxTemplateTagsFromOxc(renderExpression: any, isCollectableTag: (tag: string) => boolean): Set<string>;
45
- declare function collectJsxAutoComponentsWithBabel(source: string, options: Required<JsxAutoComponentAnalysisOptions>): JsxAutoComponentContext;
46
44
  declare function collectJsxAutoComponentsWithOxc(source: string, options: Required<Pick<JsxAutoComponentAnalysisOptions, 'isCollectableTag' | 'isDefineComponentSource'>>): JsxAutoComponentContext;
45
+ //#endregion
46
+ //#region src/operations/jsxAutoComponents/shared.d.ts
47
+ declare function mayContainJsxAutoComponentEntry(source: string): boolean;
48
+ declare function defaultIsDefineComponentSource(source: string): source is "vue";
49
+ declare function getJsxImportedName(imported: any): any;
50
+ declare function createJsxImportedComponent(localName: string, importSource: string, kind: JsxImportedComponent['kind'], imported?: any): JsxImportedComponent;
51
+ declare function getJsxImportLocalName(specifier: any): any;
52
+ declare function isJsxDefineComponentImportSpecifier(specifier: any): boolean;
53
+ //#endregion
54
+ //#region src/operations/jsxAutoComponents/index.d.ts
47
55
  /**
48
56
  * 从 JSX 源码中收集自动 usingComponents 所需的导入组件与模板标签。
49
57
  */
@@ -3,7 +3,7 @@ import { getObjectPropertyByKey, resolveRenderableExpression } from "../babelNod
3
3
  import * as t from "@babel/types";
4
4
  import { parseSync } from "oxc-parser";
5
5
  import { walk } from "oxc-walker";
6
- //#region src/operations/jsxAutoComponents.ts
6
+ //#region src/operations/jsxAutoComponents/shared.ts
7
7
  function mayContainJsxAutoComponentEntry(source) {
8
8
  return source.includes("import") || source.includes("export default");
9
9
  }
@@ -28,6 +28,8 @@ function getJsxImportLocalName(specifier) {
28
28
  function isJsxDefineComponentImportSpecifier(specifier) {
29
29
  return t.isImportSpecifier(specifier) ? t.isIdentifier(specifier.imported, { name: "defineComponent" }) : specifier?.type === "ImportSpecifier" && specifier.imported?.type === "Identifier" && specifier.imported.name === "defineComponent";
30
30
  }
31
+ //#endregion
32
+ //#region src/operations/jsxAutoComponents/babel.ts
31
33
  function defaultResolveBabelComponentExpression(declaration, defineComponentDecls, defineComponentAliases) {
32
34
  if (!declaration) return null;
33
35
  if (t.isObjectExpression(declaration)) return declaration;
@@ -153,6 +155,24 @@ function collectJsxTemplateTagsFromBabelExpression(renderExpression, isCollectab
153
155
  walk(renderExpression);
154
156
  return tags;
155
157
  }
158
+ function collectJsxAutoComponentsWithBabel(source, options) {
159
+ const { importedComponents, exportDefaultExpression } = collectJsxImportedComponentsAndDefaultExportFromBabelAst(parse(source, BABEL_TS_MODULE_PARSER_OPTIONS), options);
160
+ if (!exportDefaultExpression) return {
161
+ templateTags: /* @__PURE__ */ new Set(),
162
+ importedComponents
163
+ };
164
+ const renderExpression = options.resolveBabelRenderExpression(exportDefaultExpression);
165
+ if (!renderExpression) return {
166
+ templateTags: /* @__PURE__ */ new Set(),
167
+ importedComponents
168
+ };
169
+ return {
170
+ templateTags: collectJsxTemplateTagsFromBabelExpression(renderExpression, options.isCollectableTag),
171
+ importedComponents
172
+ };
173
+ }
174
+ //#endregion
175
+ //#region src/operations/jsxAutoComponents/oxc.ts
156
176
  function unwrapOxcExpression(node) {
157
177
  let current = node;
158
178
  while (current && (current.type === "TSAsExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSNonNullExpression" || current.type === "ParenthesizedExpression")) current = current.expression;
@@ -208,22 +228,6 @@ function collectJsxTemplateTagsFromOxc(renderExpression, isCollectableTag) {
208
228
  } });
209
229
  return tags;
210
230
  }
211
- function collectJsxAutoComponentsWithBabel(source, options) {
212
- const { importedComponents, exportDefaultExpression } = collectJsxImportedComponentsAndDefaultExportFromBabelAst(parse(source, BABEL_TS_MODULE_PARSER_OPTIONS), options);
213
- if (!exportDefaultExpression) return {
214
- templateTags: /* @__PURE__ */ new Set(),
215
- importedComponents
216
- };
217
- const renderExpression = options.resolveBabelRenderExpression(exportDefaultExpression);
218
- if (!renderExpression) return {
219
- templateTags: /* @__PURE__ */ new Set(),
220
- importedComponents
221
- };
222
- return {
223
- templateTags: collectJsxTemplateTagsFromBabelExpression(renderExpression, options.isCollectableTag),
224
- importedComponents
225
- };
226
- }
227
231
  function collectJsxAutoComponentsWithOxc(source, options) {
228
232
  const ast = parseSync("inline.tsx", source).program;
229
233
  const defineComponentAliases = new Set(["defineComponent", "_defineComponent"]);
@@ -285,6 +289,8 @@ function collectJsxAutoComponentsWithOxc(source, options) {
285
289
  importedComponents
286
290
  };
287
291
  }
292
+ //#endregion
293
+ //#region src/operations/jsxAutoComponents/index.ts
288
294
  /**
289
295
  * 从 JSX 源码中收集自动 usingComponents 所需的导入组件与模板标签。
290
296
  */
@@ -1,40 +1,2 @@
1
- import { AstEngineName } from "../types.mjs";
2
- import * as t from "@babel/types";
3
-
4
- //#region src/operations/onPageScroll.d.ts
5
- interface PageScrollInspection {
6
- empty: boolean;
7
- hasSetDataCall: boolean;
8
- syncApis: Set<string>;
9
- }
10
- interface OxcLoc {
11
- line: number;
12
- column: number;
13
- }
14
- declare function isStaticPropertyName(key: t.Expression | t.Identifier | t.PrivateName): string | undefined;
15
- declare function getMemberExpressionPropertyName(node: t.MemberExpression | t.OptionalMemberExpression): string | undefined;
16
- declare function isOnPageScrollCallee(callee: t.Expression | t.V8IntrinsicIdentifier, hookNames: Set<string>, namespaceImports: Set<string>): boolean;
17
- declare function getCallExpressionCalleeName(callee: t.Expression | t.V8IntrinsicIdentifier): string | undefined;
18
- declare function getOnPageScrollCallbackArgument(node: {
19
- arguments?: Array<t.Expression | t.SpreadElement | t.ArgumentPlaceholder | null>;
20
- }): t.FunctionExpression | t.ArrowFunctionExpression | undefined;
21
- declare function collectPageScrollInspection(functionPath: any, node: t.ArrowFunctionExpression | t.FunctionExpression | t.ObjectMethod): PageScrollInspection;
22
- declare function createWarningPrefix(filename: string, line?: number, column?: number): string;
23
- declare function getOxcStaticPropertyName(node: any): string | undefined;
24
- declare function getOxcMemberExpressionPropertyName(node: any): string | undefined;
25
- declare function isOxcFunctionLike(node: any): boolean;
26
- declare function isOxcOnPageScrollCallee(callee: any, hookNames: Set<string>, namespaceImports: Set<string>): boolean;
27
- declare function getOxcCallExpressionCalleeName(callee: any): string | undefined;
28
- declare function createLineStartOffsets(code: string): number[];
29
- declare function getLocationFromOffset(offset: number | undefined, lineStarts: number[]): OxcLoc | undefined;
30
- declare function collectPageScrollInspectionWithOxc(node: any): PageScrollInspection;
31
- declare function collectOnPageScrollWarningsWithOxc(code: string, filename: string): string[];
32
- declare function collectOnPageScrollWarningsWithBabel(code: string, filename: string): string[];
33
- /**
34
- * 静态检测 onPageScroll 中的常见性能风险并返回告警文案。
35
- */
36
- declare function collectOnPageScrollPerformanceWarnings(code: string, filename: string, options?: {
37
- engine?: AstEngineName;
38
- }): string[];
39
- //#endregion
1
+ import { _ as collectOnPageScrollWarningsWithBabel, a as getLocationFromOffset, c as getOxcCallExpressionCalleeName, d as isOnPageScrollCallee, f as isOxcFunctionLike, g as collectPageScrollInspectionWithOxc, h as collectOnPageScrollWarningsWithOxc, i as getCallExpressionCalleeName, l as getOxcMemberExpressionPropertyName, m as isStaticPropertyName, n as createLineStartOffsets, o as getMemberExpressionPropertyName, p as isOxcOnPageScrollCallee, r as createWarningPrefix, s as getOnPageScrollCallbackArgument, t as collectOnPageScrollPerformanceWarnings, u as getOxcStaticPropertyName, v as collectPageScrollInspection } from "../onPageScroll-C9pqH5L1.mjs";
40
2
  export { collectOnPageScrollPerformanceWarnings, collectOnPageScrollWarningsWithBabel, collectOnPageScrollWarningsWithOxc, collectPageScrollInspection, collectPageScrollInspectionWithOxc, createLineStartOffsets, createWarningPrefix, getCallExpressionCalleeName, getLocationFromOffset, getMemberExpressionPropertyName, getOnPageScrollCallbackArgument, getOxcCallExpressionCalleeName, getOxcMemberExpressionPropertyName, getOxcStaticPropertyName, isOnPageScrollCallee, isOxcFunctionLike, isOxcOnPageScrollCallee, isStaticPropertyName };
@@ -1,265 +1,2 @@
1
- import { parseJsLike, traverse } from "../babel.mjs";
2
- import { t as parseJsLikeWithEngine } from "../engine-DHqNPCDA.mjs";
3
- //#region src/operations/onPageScroll.ts
4
- function isStaticPropertyName(key) {
5
- if (key.type === "Identifier") return key.name;
6
- if (key.type === "StringLiteral") return key.value;
7
- }
8
- function getMemberExpressionPropertyName(node) {
9
- if (node.computed) return node.property.type === "StringLiteral" ? node.property.value : void 0;
10
- return node.property.type === "Identifier" ? node.property.name : void 0;
11
- }
12
- function isOnPageScrollCallee(callee, hookNames, namespaceImports) {
13
- if (callee.type === "Identifier") return hookNames.has(callee.name);
14
- if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
15
- const object = callee.object;
16
- const propName = getMemberExpressionPropertyName(callee);
17
- return object.type === "Identifier" && namespaceImports.has(object.name) && propName === "onPageScroll";
18
- }
19
- return false;
20
- }
21
- function getCallExpressionCalleeName(callee) {
22
- if (callee.type === "Identifier") return callee.name;
23
- if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") return getMemberExpressionPropertyName(callee);
24
- }
25
- function getOnPageScrollCallbackArgument(node) {
26
- const arg0 = node.arguments?.[0];
27
- if (!arg0 || arg0.type === "SpreadElement") return;
28
- return arg0.type === "FunctionExpression" || arg0.type === "ArrowFunctionExpression" ? arg0 : void 0;
29
- }
30
- function collectPageScrollInspection(functionPath, node) {
31
- const inspection = {
32
- empty: node.body.type === "BlockStatement" && node.body.body.length === 0,
33
- hasSetDataCall: false,
34
- syncApis: /* @__PURE__ */ new Set()
35
- };
36
- functionPath.traverse({
37
- Function(innerPath) {
38
- if (innerPath !== functionPath) innerPath.skip();
39
- },
40
- CallExpression(callPath) {
41
- const callee = callPath.node.callee;
42
- if (getCallExpressionCalleeName(callee) === "setData") inspection.hasSetDataCall = true;
43
- if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
44
- const object = callee.object;
45
- if (object.type === "Identifier" && object.name === "wx") {
46
- const propertyName = getMemberExpressionPropertyName(callee);
47
- if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
48
- }
49
- }
50
- },
51
- OptionalCallExpression(callPath) {
52
- const callee = callPath.node.callee;
53
- if (getCallExpressionCalleeName(callee) === "setData") inspection.hasSetDataCall = true;
54
- if (callee.type === "MemberExpression" || callee.type === "OptionalMemberExpression") {
55
- const object = callee.object;
56
- if (object.type === "Identifier" && object.name === "wx") {
57
- const propertyName = getMemberExpressionPropertyName(callee);
58
- if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
59
- }
60
- }
61
- }
62
- });
63
- return inspection;
64
- }
65
- function createWarningPrefix(filename, line, column) {
66
- return `[weapp-vite][onPageScroll] ${filename}:${typeof line === "number" && typeof column === "number" ? `${line}:${column}` : "?:?"}`;
67
- }
68
- function getOxcStaticPropertyName(node) {
69
- if (!node) return;
70
- if (node.type === "Identifier") return node.name;
71
- if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return node.value;
72
- }
73
- function getOxcMemberExpressionPropertyName(node) {
74
- if (!node || node.type !== "MemberExpression") return;
75
- if (node.computed) return getOxcStaticPropertyName(node.property);
76
- return node.property?.type === "Identifier" ? node.property.name : void 0;
77
- }
78
- function isOxcFunctionLike(node) {
79
- return node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression";
80
- }
81
- function isOxcOnPageScrollCallee(callee, hookNames, namespaceImports) {
82
- if (!callee) return false;
83
- if (callee.type === "Identifier") return hookNames.has(callee.name);
84
- if (callee.type === "MemberExpression") {
85
- const propName = getOxcMemberExpressionPropertyName(callee);
86
- return callee.object?.type === "Identifier" && namespaceImports.has(callee.object.name) && propName === "onPageScroll";
87
- }
88
- return false;
89
- }
90
- function getOxcCallExpressionCalleeName(callee) {
91
- if (!callee) return;
92
- if (callee.type === "Identifier") return callee.name;
93
- if (callee.type === "MemberExpression") return getOxcMemberExpressionPropertyName(callee);
94
- }
95
- function createLineStartOffsets(code) {
96
- const offsets = [0];
97
- for (let index = 0; index < code.length; index += 1) if (code.charCodeAt(index) === 10) offsets.push(index + 1);
98
- return offsets;
99
- }
100
- function getLocationFromOffset(offset, lineStarts) {
101
- if (typeof offset !== "number" || offset < 0) return;
102
- let low = 0;
103
- let high = lineStarts.length - 1;
104
- while (low <= high) {
105
- const mid = Math.floor((low + high) / 2);
106
- if (lineStarts[mid] <= offset) low = mid + 1;
107
- else high = mid - 1;
108
- }
109
- const lineIndex = Math.max(0, low - 1);
110
- return {
111
- line: lineIndex + 1,
112
- column: offset - lineStarts[lineIndex] + 1
113
- };
114
- }
115
- function collectPageScrollInspectionWithOxc(node) {
116
- const inspection = {
117
- empty: node.body?.type === "BlockStatement" && node.body.body.length === 0,
118
- hasSetDataCall: false,
119
- syncApis: /* @__PURE__ */ new Set()
120
- };
121
- const root = node.body?.type === "BlockStatement" ? node.body : node.body;
122
- function visit(current, allowNestedFunctions = false) {
123
- if (!current) return;
124
- if (!allowNestedFunctions && (current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression")) return;
125
- if (current.type === "CallExpression") {
126
- if (getOxcCallExpressionCalleeName(current.callee) === "setData") inspection.hasSetDataCall = true;
127
- if (current.callee?.type === "MemberExpression" && current.callee.object?.type === "Identifier" && current.callee.object.name === "wx") {
128
- const propertyName = getOxcMemberExpressionPropertyName(current.callee);
129
- if (propertyName && propertyName.endsWith("Sync")) inspection.syncApis.add(`wx.${propertyName}`);
130
- }
131
- } else if (current.type === "ChainExpression") {
132
- visit(current.expression, allowNestedFunctions);
133
- return;
134
- }
135
- for (const value of Object.values(current)) {
136
- if (!value) continue;
137
- if (Array.isArray(value)) {
138
- for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
139
- } else if (typeof value === "object" && typeof value.type === "string") visit(value);
140
- }
141
- }
142
- if (root) visit(root, true);
143
- return inspection;
144
- }
145
- function collectOnPageScrollWarningsWithOxc(code, filename) {
146
- const ast = parseJsLikeWithEngine(code, {
147
- engine: "oxc",
148
- filename: "inline.ts"
149
- });
150
- const onPageScrollHookNames = new Set(["onPageScroll"]);
151
- const namespaceImports = /* @__PURE__ */ new Set();
152
- for (const statement of ast.body ?? []) {
153
- if (statement?.type !== "ImportDeclaration" || statement.source?.value !== "wevu") continue;
154
- for (const specifier of statement.specifiers ?? []) if (specifier.type === "ImportSpecifier" && specifier.imported?.type === "Identifier" && specifier.imported.name === "onPageScroll" && specifier.local?.type === "Identifier") onPageScrollHookNames.add(specifier.local.name);
155
- else if (specifier.type === "ImportNamespaceSpecifier" && specifier.local?.type === "Identifier") namespaceImports.add(specifier.local.name);
156
- }
157
- const lineStarts = createLineStartOffsets(code);
158
- const warnings = [];
159
- const warningSet = /* @__PURE__ */ new Set();
160
- const addWarning = (warning) => {
161
- if (warningSet.has(warning)) return;
162
- warningSet.add(warning);
163
- warnings.push(warning);
164
- };
165
- const reportInspection = (node, sourceLabel, startOffset = node.start) => {
166
- const inspection = collectPageScrollInspectionWithOxc(node);
167
- const loc = getLocationFromOffset(startOffset, lineStarts);
168
- const prefix = createWarningPrefix(filename, loc?.line, loc?.column);
169
- if (inspection.empty) addWarning(`${prefix} 检测到空的 ${sourceLabel} 回调,建议移除无效监听以降低滚动时调度开销。`);
170
- if (inspection.hasSetDataCall) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用 setData,建议改用节流、IntersectionObserver 或合并更新。`);
171
- for (const syncApi of inspection.syncApis) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用同步 API(${syncApi}),可能阻塞渲染线程。`);
172
- };
173
- function visit(node) {
174
- if (!node) return;
175
- if (node.type === "Property" && !node.computed && getOxcStaticPropertyName(node.key) === "onPageScroll" && isOxcFunctionLike(node.value)) {
176
- const startOffset = node.method ? node.key?.end : node.value.start;
177
- reportInspection(node.value, "onPageScroll", startOffset);
178
- } else if (node.type === "CallExpression" && isOxcOnPageScrollCallee(node.callee, onPageScrollHookNames, namespaceImports)) {
179
- const arg0 = node.arguments?.[0];
180
- if (arg0 && arg0.type !== "SpreadElement" && isOxcFunctionLike(arg0)) reportInspection(arg0, "onPageScroll(...)");
181
- } else if (node.type === "ChainExpression" && node.expression?.type === "CallExpression") {
182
- const arg0 = node.expression.arguments?.[0];
183
- if (isOxcOnPageScrollCallee(node.expression.callee, onPageScrollHookNames, namespaceImports) && arg0 && arg0.type !== "SpreadElement" && isOxcFunctionLike(arg0)) reportInspection(arg0, "onPageScroll(...)");
184
- }
185
- for (const value of Object.values(node)) {
186
- if (!value) continue;
187
- if (Array.isArray(value)) {
188
- for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
189
- } else if (typeof value === "object" && typeof value.type === "string") visit(value);
190
- }
191
- }
192
- visit(ast);
193
- return warnings;
194
- }
195
- function collectOnPageScrollWarningsWithBabel(code, filename) {
196
- const ast = parseJsLike(code);
197
- const onPageScrollHookNames = new Set(["onPageScroll"]);
198
- const namespaceImports = /* @__PURE__ */ new Set();
199
- for (const statement of ast.program.body) {
200
- if (statement.type !== "ImportDeclaration" || statement.source.value !== "wevu") continue;
201
- for (const specifier of statement.specifiers) {
202
- if (specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === "onPageScroll") onPageScrollHookNames.add(specifier.local.name);
203
- if (specifier.type === "ImportNamespaceSpecifier") namespaceImports.add(specifier.local.name);
204
- }
205
- }
206
- const warnings = [];
207
- const warningSet = /* @__PURE__ */ new Set();
208
- const addWarning = (warning) => {
209
- if (warningSet.has(warning)) return;
210
- warningSet.add(warning);
211
- warnings.push(warning);
212
- };
213
- const reportInspection = (functionPath, node, sourceLabel) => {
214
- const inspection = collectPageScrollInspection(functionPath, node);
215
- const line = node.loc?.start.line;
216
- const prefix = createWarningPrefix(filename, line, typeof node.loc?.start.column === "number" ? node.loc.start.column + 1 : void 0);
217
- if (inspection.empty) addWarning(`${prefix} 检测到空的 ${sourceLabel} 回调,建议移除无效监听以降低滚动时调度开销。`);
218
- if (inspection.hasSetDataCall) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用 setData,建议改用节流、IntersectionObserver 或合并更新。`);
219
- for (const syncApi of inspection.syncApis) addWarning(`${prefix} 检测到 ${sourceLabel} 内调用同步 API(${syncApi}),可能阻塞渲染线程。`);
220
- };
221
- traverse(ast, {
222
- ObjectMethod(path) {
223
- if (isStaticPropertyName(path.node.key) !== "onPageScroll") return;
224
- reportInspection(path, path.node, "onPageScroll");
225
- },
226
- ObjectProperty(path) {
227
- if (path.node.computed) return;
228
- if (isStaticPropertyName(path.node.key) !== "onPageScroll") return;
229
- const value = path.node.value;
230
- if (value.type !== "FunctionExpression" && value.type !== "ArrowFunctionExpression") return;
231
- reportInspection(path.get("value"), value, "onPageScroll");
232
- },
233
- CallExpression(path) {
234
- if (!isOnPageScrollCallee(path.node.callee, onPageScrollHookNames, namespaceImports)) return;
235
- const arg0 = getOnPageScrollCallbackArgument(path.node);
236
- if (!arg0) return;
237
- reportInspection(path.get("arguments.0"), arg0, "onPageScroll(...)");
238
- },
239
- OptionalCallExpression(path) {
240
- if (!isOnPageScrollCallee(path.node.callee, onPageScrollHookNames, namespaceImports)) return;
241
- const arg0 = getOnPageScrollCallbackArgument(path.node);
242
- if (!arg0) return;
243
- reportInspection(path.get("arguments.0"), arg0, "onPageScroll(...)");
244
- }
245
- });
246
- return warnings;
247
- }
248
- /**
249
- * 静态检测 onPageScroll 中的常见性能风险并返回告警文案。
250
- */
251
- function collectOnPageScrollPerformanceWarnings(code, filename, options) {
252
- if (!code.includes("onPageScroll")) return [];
253
- if (options?.engine === "oxc") try {
254
- return collectOnPageScrollWarningsWithOxc(code, filename);
255
- } catch {
256
- return [];
257
- }
258
- try {
259
- return collectOnPageScrollWarningsWithBabel(code, filename);
260
- } catch {
261
- return [];
262
- }
263
- }
264
- //#endregion
1
+ import { _ as isOxcOnPageScrollCallee, a as collectPageScrollInspection, c as getCallExpressionCalleeName, d as getOnPageScrollCallbackArgument, f as getOxcCallExpressionCalleeName, g as isOxcFunctionLike, h as isOnPageScrollCallee, i as collectOnPageScrollWarningsWithBabel, l as getLocationFromOffset, m as getOxcStaticPropertyName, n as collectOnPageScrollWarningsWithOxc, o as createLineStartOffsets, p as getOxcMemberExpressionPropertyName, r as collectPageScrollInspectionWithOxc, s as createWarningPrefix, t as collectOnPageScrollPerformanceWarnings, u as getMemberExpressionPropertyName, v as isStaticPropertyName } from "../onPageScroll-FN_gheDb.mjs";
265
2
  export { collectOnPageScrollPerformanceWarnings, collectOnPageScrollWarningsWithBabel, collectOnPageScrollWarningsWithOxc, collectPageScrollInspection, collectPageScrollInspectionWithOxc, createLineStartOffsets, createWarningPrefix, getCallExpressionCalleeName, getLocationFromOffset, getMemberExpressionPropertyName, getOnPageScrollCallbackArgument, getOxcCallExpressionCalleeName, getOxcMemberExpressionPropertyName, getOxcStaticPropertyName, isOnPageScrollCallee, isOxcFunctionLike, isOxcOnPageScrollCallee, isStaticPropertyName };
@@ -1,4 +1,4 @@
1
- import { AstEngineName, AstParserLike } from "../types.mjs";
1
+ import { n as AstParserLike, t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
  import { Program } from "@oxc-project/types";
3
3
 
4
4
  //#region src/operations/platformApi.d.ts
@@ -1,4 +1,4 @@
1
- import { AstEngineName, AstParserLike } from "../types.mjs";
1
+ import { n as AstParserLike, t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
  import { Program } from "@oxc-project/types";
3
3
 
4
4
  //#region src/operations/require.d.ts
@@ -1,4 +1,4 @@
1
- import { AstEngineName } from "../types.mjs";
1
+ import { t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
 
3
3
  //#region src/operations/scriptSetupImports.d.ts
4
4
  interface ScriptSetupImport {
@@ -1,4 +1,4 @@
1
- import { AstEngineName } from "../types.mjs";
1
+ import { t as AstEngineName } from "../types-Cn0gcZR9.mjs";
2
2
 
3
3
  //#region src/operations/setDataPick.d.ts
4
4
  declare function collectLoopScopeAliases(template: string): Set<string>;
@@ -0,0 +1,24 @@
1
+ //#region src/types.d.ts
2
+ /**
3
+ * AST 引擎名称。
4
+ */
5
+ type AstEngineName = 'babel' | 'oxc';
6
+ /**
7
+ * AST 相关配置。
8
+ */
9
+ interface WeappAstConfig {
10
+ /**
11
+ * AST 引擎。
12
+ * - `babel`: 默认兼容模式
13
+ * - `oxc`: 优先使用 Oxc 做解析/分析
14
+ */
15
+ engine?: AstEngineName;
16
+ }
17
+ /**
18
+ * 兼容 Rolldown/Vite `this.parse` 形状的解析器。
19
+ */
20
+ interface AstParserLike {
21
+ parse?: (input: string, options?: unknown) => unknown;
22
+ }
23
+ //#endregion
24
+ export { AstParserLike as n, WeappAstConfig as r, AstEngineName as t };
package/dist/types.d.mts CHANGED
@@ -1,24 +1,2 @@
1
- //#region src/types.d.ts
2
- /**
3
- * AST 引擎名称。
4
- */
5
- type AstEngineName = 'babel' | 'oxc';
6
- /**
7
- * AST 相关配置。
8
- */
9
- interface WeappAstConfig {
10
- /**
11
- * AST 引擎。
12
- * - `babel`: 默认兼容模式
13
- * - `oxc`: 优先使用 Oxc 做解析/分析
14
- */
15
- engine?: AstEngineName;
16
- }
17
- /**
18
- * 兼容 Rolldown/Vite `this.parse` 形状的解析器。
19
- */
20
- interface AstParserLike {
21
- parse?: (input: string, options?: unknown) => unknown;
22
- }
23
- //#endregion
1
+ import { n as AstParserLike, r as WeappAstConfig, t as AstEngineName } from "./types-Cn0gcZR9.mjs";
24
2
  export { AstEngineName, AstParserLike, WeappAstConfig };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@weapp-vite/ast",
3
3
  "type": "module",
4
- "version": "6.15.0",
4
+ "version": "6.15.3",
5
5
  "description": "weapp-vite 共享 AST 分析工具包,统一 Babel/Oxc 解析与常用分析操作",
6
6
  "author": "ice breaker <1324318532@qq.com>",
7
7
  "license": "MIT",
@@ -106,8 +106,8 @@
106
106
  "@babel/parser": "^7.29.2",
107
107
  "@babel/traverse": "^7.29.0",
108
108
  "@babel/types": "^7.29.0",
109
- "@oxc-project/types": "^0.124.0",
110
- "oxc-parser": "^0.124.0",
109
+ "@oxc-project/types": "^0.125.0",
110
+ "oxc-parser": "^0.125.0",
111
111
  "oxc-walker": "^0.7.0"
112
112
  },
113
113
  "publishConfig": {