@wevu/compiler 6.8.0 → 6.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +70 -4
- package/dist/index.mjs +331 -258
- package/package.json +5 -8
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import * as t from "@
|
|
2
|
-
import { Expression } from "@
|
|
1
|
+
import * as t from "@weapp-vite/ast/babelTypes";
|
|
2
|
+
import { Expression } from "@weapp-vite/ast/babelTypes";
|
|
3
|
+
import { AstEngineName, AstEngineName as AstEngineName$1 } from "@weapp-vite/ast";
|
|
3
4
|
import { LRUCache } from "lru-cache";
|
|
4
5
|
import { SFCBlock, SFCDescriptor, SFCParseResult, SFCStyleBlock } from "vue/compiler-sfc";
|
|
5
6
|
|
|
@@ -385,6 +386,7 @@ interface AutoImportTagsOptions {
|
|
|
385
386
|
* 编译 Vue SFC 的选项集合。
|
|
386
387
|
*/
|
|
387
388
|
interface CompileVueFileOptions {
|
|
389
|
+
astEngine?: AstEngineName$1;
|
|
388
390
|
isPage?: boolean;
|
|
389
391
|
isApp?: boolean;
|
|
390
392
|
warn?: (message: string) => void;
|
|
@@ -648,6 +650,67 @@ interface ModuleResolver {
|
|
|
648
650
|
loadCode: (id: string) => Promise<string | undefined>;
|
|
649
651
|
}
|
|
650
652
|
//#endregion
|
|
653
|
+
//#region src/ast/operations/pageFeatures.d.ts
|
|
654
|
+
/**
|
|
655
|
+
* 从源码中收集 wevu 页面特性。
|
|
656
|
+
*/
|
|
657
|
+
declare function collectWevuPageFeatureFlagsFromCode(code: string, options?: {
|
|
658
|
+
astEngine?: AstEngineName$1;
|
|
659
|
+
}): Set<WevuPageFeatureFlag>;
|
|
660
|
+
//#endregion
|
|
661
|
+
//#region src/plugins/wevu/pageFeatures/moduleAnalysis.d.ts
|
|
662
|
+
type FunctionLike = t.FunctionDeclaration | t.FunctionExpression | t.ArrowFunctionExpression | t.ObjectMethod | {
|
|
663
|
+
type: string;
|
|
664
|
+
[key: string]: any;
|
|
665
|
+
};
|
|
666
|
+
type ExportTarget = {
|
|
667
|
+
type: 'local';
|
|
668
|
+
localName: string;
|
|
669
|
+
} | {
|
|
670
|
+
type: 'reexport';
|
|
671
|
+
source: string;
|
|
672
|
+
importedName: string;
|
|
673
|
+
} | {
|
|
674
|
+
type: 'inline';
|
|
675
|
+
node: FunctionLike;
|
|
676
|
+
};
|
|
677
|
+
type ImportBinding = {
|
|
678
|
+
kind: 'named';
|
|
679
|
+
source: string;
|
|
680
|
+
importedName: string;
|
|
681
|
+
} | {
|
|
682
|
+
kind: 'default';
|
|
683
|
+
source: string;
|
|
684
|
+
} | {
|
|
685
|
+
kind: 'namespace';
|
|
686
|
+
source: string;
|
|
687
|
+
};
|
|
688
|
+
interface ModuleAnalysis {
|
|
689
|
+
id: string;
|
|
690
|
+
engine: AstEngineName$1;
|
|
691
|
+
ast?: t.File;
|
|
692
|
+
wevuNamedHookLocals: Map<string, WevuPageFeatureFlag>;
|
|
693
|
+
wevuNamespaceLocals: Set<string>;
|
|
694
|
+
importedBindings: Map<string, ImportBinding>;
|
|
695
|
+
localFunctions: Map<string, FunctionLike>;
|
|
696
|
+
exports: Map<string, ExportTarget>;
|
|
697
|
+
}
|
|
698
|
+
//#endregion
|
|
699
|
+
//#region src/plugins/wevu/pageFeatures/optionsObjects.d.ts
|
|
700
|
+
declare function collectTargetOptionsObjectsFromCode(code: string, moduleId: string, options?: {
|
|
701
|
+
astEngine?: AstEngineName$1;
|
|
702
|
+
}): {
|
|
703
|
+
optionsObjects: t.ObjectExpression[];
|
|
704
|
+
module: ModuleAnalysis;
|
|
705
|
+
};
|
|
706
|
+
//#endregion
|
|
707
|
+
//#region src/plugins/wevu/pageFeatures/reachability/index.d.ts
|
|
708
|
+
declare function collectWevuFeaturesFromCodeReachableImports(code: string, options: {
|
|
709
|
+
id: string;
|
|
710
|
+
resolver: ModuleResolver;
|
|
711
|
+
astEngine?: AstEngineName$1;
|
|
712
|
+
}): Promise<Set<WevuPageFeatureFlag>>;
|
|
713
|
+
//#endregion
|
|
651
714
|
//#region src/plugins/wevu/pageFeatures/flags.d.ts
|
|
652
715
|
/**
|
|
653
716
|
* 扫描 AST,收集启用的 wevu 页面特性标识。
|
|
@@ -662,7 +725,9 @@ declare function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject: t.Ob
|
|
|
662
725
|
/**
|
|
663
726
|
* 在 JS 源码中注入 wevu 页面特性(基于本文件分析)。
|
|
664
727
|
*/
|
|
665
|
-
declare function injectWevuPageFeaturesInJs(source: string
|
|
728
|
+
declare function injectWevuPageFeaturesInJs(source: string, options?: {
|
|
729
|
+
astEngine?: AstEngineName$1;
|
|
730
|
+
}): {
|
|
666
731
|
code: string;
|
|
667
732
|
transformed: boolean;
|
|
668
733
|
};
|
|
@@ -672,6 +737,7 @@ declare function injectWevuPageFeaturesInJs(source: string): {
|
|
|
672
737
|
declare function injectWevuPageFeaturesInJsWithResolver(source: string, options: {
|
|
673
738
|
id: string;
|
|
674
739
|
resolver: ModuleResolver;
|
|
740
|
+
astEngine?: AstEngineName$1;
|
|
675
741
|
}): Promise<{
|
|
676
742
|
code: string;
|
|
677
743
|
transformed: boolean;
|
|
@@ -722,4 +788,4 @@ interface CollectVueTemplateTagsOptions {
|
|
|
722
788
|
*/
|
|
723
789
|
declare function collectVueTemplateTags(template: string, options: CollectVueTemplateTagsOptions): Set<string>;
|
|
724
790
|
//#endregion
|
|
725
|
-
export { type AutoImportTagsOptions, type AutoUsingComponentsOptions, CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, type ClassStyleBinding, type ClassStyleRuntime, type CollectVueTemplateTagsOptions, type CompileVueFileOptions, type ForParseResult, type InlineExpressionAsset, type JsLikeLang, type JsonConfig, type JsonMergeContext, type JsonMergeStage, type JsonMergeStrategy, type MiniProgramPlatform, type ModuleResolver, type MpPlatform, RESERVED_VUE_COMPONENT_TAGS, type ReadAndParseSfcOptions, type ResolveSfcBlockSrcOptions, type ScopedSlotComponentAsset, type StyleCompileOptions, type StyleCompileResult, type TemplateCompileOptions, type TemplateCompileResult, type TemplateRefBinding, type TransformResult, type TransformScriptOptions, VUE_COMPONENT_TAG_RE, type VueTransformResult, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, type WevuDefaults, type WevuPageFeatureFlag, type WevuPageHookName, WevuRuntimeApiName, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectVueTemplateTags, collectWevuPageFeatureFlags, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|
|
791
|
+
export { type AstEngineName, type AutoImportTagsOptions, type AutoUsingComponentsOptions, CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, type ClassStyleBinding, type ClassStyleRuntime, type CollectVueTemplateTagsOptions, type CompileVueFileOptions, type ForParseResult, type InlineExpressionAsset, type JsLikeLang, type JsonConfig, type JsonMergeContext, type JsonMergeStage, type JsonMergeStrategy, type MiniProgramPlatform, type ModuleResolver, type MpPlatform, RESERVED_VUE_COMPONENT_TAGS, type ReadAndParseSfcOptions, type ResolveSfcBlockSrcOptions, type ScopedSlotComponentAsset, type StyleCompileOptions, type StyleCompileResult, type TemplateCompileOptions, type TemplateCompileResult, type TemplateRefBinding, type TransformResult, type TransformScriptOptions, VUE_COMPONENT_TAG_RE, type VueTransformResult, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, type WevuDefaults, type WevuPageFeatureFlag, type WevuPageHookName, WevuRuntimeApiName, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
1
|
import { removeExtensionDeep } from "@weapp-core/shared";
|
|
3
2
|
import path from "pathe";
|
|
4
3
|
import { NodeTypes, baseParse } from "@vue/compiler-core";
|
|
5
4
|
import { createHash } from "node:crypto";
|
|
6
|
-
import * as t from "@
|
|
5
|
+
import * as t from "@weapp-vite/ast/babelTypes";
|
|
7
6
|
import fs from "fs-extra";
|
|
8
7
|
import MagicString from "magic-string";
|
|
9
8
|
import { recursive } from "merge";
|
|
10
9
|
import { bundleRequire } from "rolldown-require";
|
|
11
|
-
import { parse as parse$2 } from "@babel
|
|
10
|
+
import { BABEL_TS_MODULE_PARSER_OPTIONS, generate, parse as parse$2, parseJsLike, traverse } from "@weapp-vite/ast/babel";
|
|
12
11
|
import fs$1 from "node:fs";
|
|
13
12
|
import os from "node:os";
|
|
14
13
|
import process from "node:process";
|
|
14
|
+
import { collectFeatureFlagsFromCode, collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, getRenderPropertyFromComponentOptions, parseJsLikeWithEngine, resolveRenderExpressionFromComponentOptions, toStaticObjectKey, unwrapTypeScriptExpression } from "@weapp-vite/ast";
|
|
15
15
|
import { LRUCache } from "lru-cache";
|
|
16
16
|
import { compileScript, parse } from "vue/compiler-sfc";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
@@ -314,57 +314,6 @@ async function withTempDirLock(tempDir, fn) {
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
//#endregion
|
|
317
|
-
//#region src/utils/babel.ts
|
|
318
|
-
const BABEL_TS_MODULE_PLUGINS = [
|
|
319
|
-
"typescript",
|
|
320
|
-
"decorators-legacy",
|
|
321
|
-
"classProperties",
|
|
322
|
-
"classPrivateProperties",
|
|
323
|
-
"classPrivateMethods",
|
|
324
|
-
"jsx"
|
|
325
|
-
];
|
|
326
|
-
const BABEL_TS_MODULE_PARSER_OPTIONS = {
|
|
327
|
-
sourceType: "module",
|
|
328
|
-
plugins: BABEL_TS_MODULE_PLUGINS
|
|
329
|
-
};
|
|
330
|
-
const nodeRequire = createRequire(import.meta.url);
|
|
331
|
-
let cachedTraverse;
|
|
332
|
-
let cachedGenerate;
|
|
333
|
-
function requireCallableDefault(id) {
|
|
334
|
-
const mod = nodeRequire(id);
|
|
335
|
-
if (typeof mod === "function") return mod;
|
|
336
|
-
if (mod && (typeof mod === "object" || typeof mod === "function") && "default" in mod) {
|
|
337
|
-
const candidate = mod.default;
|
|
338
|
-
if (typeof candidate === "function") return candidate;
|
|
339
|
-
}
|
|
340
|
-
throw new TypeError(`Invalid module shape for ${id}`);
|
|
341
|
-
}
|
|
342
|
-
function getTraverse() {
|
|
343
|
-
if (!cachedTraverse) cachedTraverse = requireCallableDefault("@babel/traverse");
|
|
344
|
-
return cachedTraverse;
|
|
345
|
-
}
|
|
346
|
-
function getGenerate() {
|
|
347
|
-
if (!cachedGenerate) cachedGenerate = requireCallableDefault("@babel/generator");
|
|
348
|
-
return cachedGenerate;
|
|
349
|
-
}
|
|
350
|
-
const traverse = (...args) => {
|
|
351
|
-
return getTraverse()(...args);
|
|
352
|
-
};
|
|
353
|
-
const generate = (...args) => {
|
|
354
|
-
return getGenerate()(...args);
|
|
355
|
-
};
|
|
356
|
-
function parseJsLike(source) {
|
|
357
|
-
return parse$2(source, {
|
|
358
|
-
sourceType: "module",
|
|
359
|
-
plugins: [
|
|
360
|
-
...BABEL_TS_MODULE_PLUGINS,
|
|
361
|
-
"dynamicImport",
|
|
362
|
-
"optionalChaining",
|
|
363
|
-
"nullishCoalescingOperator"
|
|
364
|
-
]
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
//#endregion
|
|
368
317
|
//#region src/utils/path.ts
|
|
369
318
|
const BACKSLASH_RE$4 = /\\/g;
|
|
370
319
|
const LEADING_SLASH_RE = /^[\\/]+/;
|
|
@@ -840,17 +789,48 @@ function injectWevuPageFeatureFlagsIntoOptionsObject(optionsObject, enabled) {
|
|
|
840
789
|
return changed;
|
|
841
790
|
}
|
|
842
791
|
//#endregion
|
|
792
|
+
//#region src/ast/operations/pageFeatures.ts
|
|
793
|
+
function collectWithBabel(code) {
|
|
794
|
+
return collectWevuPageFeatureFlags(parseJsLike(code));
|
|
795
|
+
}
|
|
796
|
+
function collectWithOxc(code) {
|
|
797
|
+
return collectFeatureFlagsFromCode(code, {
|
|
798
|
+
astEngine: "oxc",
|
|
799
|
+
moduleId: WE_VU_MODULE_ID,
|
|
800
|
+
hookToFeature: WE_VU_PAGE_HOOK_TO_FEATURE
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* 从源码中收集 wevu 页面特性。
|
|
805
|
+
*/
|
|
806
|
+
function collectWevuPageFeatureFlagsFromCode(code, options) {
|
|
807
|
+
const engine = options?.astEngine ?? "babel";
|
|
808
|
+
try {
|
|
809
|
+
return engine === "oxc" ? collectWithOxc(code) : collectWithBabel(code);
|
|
810
|
+
} catch {
|
|
811
|
+
return /* @__PURE__ */ new Set();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
//#endregion
|
|
843
815
|
//#region src/plugins/wevu/pageFeatures/moduleAnalysis.ts
|
|
816
|
+
function createEmptyModuleAnalysis(id, engine) {
|
|
817
|
+
return {
|
|
818
|
+
id,
|
|
819
|
+
engine,
|
|
820
|
+
wevuNamedHookLocals: /* @__PURE__ */ new Map(),
|
|
821
|
+
wevuNamespaceLocals: /* @__PURE__ */ new Set(),
|
|
822
|
+
importedBindings: /* @__PURE__ */ new Map(),
|
|
823
|
+
localFunctions: /* @__PURE__ */ new Map(),
|
|
824
|
+
exports: /* @__PURE__ */ new Map()
|
|
825
|
+
};
|
|
826
|
+
}
|
|
844
827
|
const externalModuleAnalysisCache = new LRUCache({ max: 256 });
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
analysis
|
|
852
|
-
});
|
|
853
|
-
return analysis;
|
|
828
|
+
const moduleAnalysisCache = new LRUCache({ max: 512 });
|
|
829
|
+
function createExternalModuleAnalysisCacheKey(moduleId, astEngine) {
|
|
830
|
+
return `${astEngine ?? "babel"}::${moduleId}`;
|
|
831
|
+
}
|
|
832
|
+
function createModuleAnalysisCacheKey(moduleId, astEngine) {
|
|
833
|
+
return `${astEngine ?? "babel"}::${moduleId}`;
|
|
854
834
|
}
|
|
855
835
|
function getFunctionLikeFromExpression(node) {
|
|
856
836
|
if (!node) return null;
|
|
@@ -977,6 +957,7 @@ function createModuleAnalysis(id, ast) {
|
|
|
977
957
|
}
|
|
978
958
|
return {
|
|
979
959
|
id,
|
|
960
|
+
engine: "babel",
|
|
980
961
|
ast,
|
|
981
962
|
wevuNamedHookLocals,
|
|
982
963
|
wevuNamespaceLocals,
|
|
@@ -985,6 +966,166 @@ function createModuleAnalysis(id, ast) {
|
|
|
985
966
|
exports
|
|
986
967
|
};
|
|
987
968
|
}
|
|
969
|
+
function isOxcFunctionLike(node) {
|
|
970
|
+
return node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression";
|
|
971
|
+
}
|
|
972
|
+
function getImportedSpecifierName(node) {
|
|
973
|
+
if (node?.type === "Identifier") return node.name;
|
|
974
|
+
if ((node?.type === "StringLiteral" || node?.type === "Literal") && typeof node.value === "string") return node.value;
|
|
975
|
+
}
|
|
976
|
+
function resolveOxcParseFilename(id) {
|
|
977
|
+
if (path.extname(id)) return id;
|
|
978
|
+
return `${id}.js`;
|
|
979
|
+
}
|
|
980
|
+
function createModuleAnalysisWithOxc(id, code) {
|
|
981
|
+
const ast = parseJsLikeWithEngine(code, {
|
|
982
|
+
engine: "oxc",
|
|
983
|
+
filename: resolveOxcParseFilename(id)
|
|
984
|
+
});
|
|
985
|
+
const localFunctions = /* @__PURE__ */ new Map();
|
|
986
|
+
const exports = /* @__PURE__ */ new Map();
|
|
987
|
+
const importedBindings = /* @__PURE__ */ new Map();
|
|
988
|
+
const wevuNamedHookLocals = /* @__PURE__ */ new Map();
|
|
989
|
+
const wevuNamespaceLocals = /* @__PURE__ */ new Set();
|
|
990
|
+
function registerFunctionDeclaration(node) {
|
|
991
|
+
if (node?.id?.type === "Identifier") localFunctions.set(node.id.name, node);
|
|
992
|
+
}
|
|
993
|
+
function registerVariableFunction(node) {
|
|
994
|
+
if (node?.id?.type !== "Identifier" || !isOxcFunctionLike(node.init)) return;
|
|
995
|
+
localFunctions.set(node.id.name, node.init);
|
|
996
|
+
}
|
|
997
|
+
for (const stmt of ast.body ?? []) {
|
|
998
|
+
if (stmt?.type === "FunctionDeclaration") {
|
|
999
|
+
registerFunctionDeclaration(stmt);
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
if (stmt?.type === "VariableDeclaration") {
|
|
1003
|
+
for (const decl of stmt.declarations ?? []) registerVariableFunction(decl);
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (stmt?.type === "ImportDeclaration") {
|
|
1007
|
+
const source = getImportedSpecifierName(stmt.source);
|
|
1008
|
+
if (!source) continue;
|
|
1009
|
+
for (const specifier of stmt.specifiers ?? []) if (specifier.type === "ImportSpecifier" && specifier.local?.type === "Identifier") {
|
|
1010
|
+
const importedName = getImportedSpecifierName(specifier.imported);
|
|
1011
|
+
if (!importedName) continue;
|
|
1012
|
+
if (source === "wevu") {
|
|
1013
|
+
const matched = WE_VU_PAGE_HOOK_TO_FEATURE[importedName];
|
|
1014
|
+
if (matched) wevuNamedHookLocals.set(specifier.local.name, matched);
|
|
1015
|
+
}
|
|
1016
|
+
importedBindings.set(specifier.local.name, {
|
|
1017
|
+
kind: "named",
|
|
1018
|
+
source,
|
|
1019
|
+
importedName
|
|
1020
|
+
});
|
|
1021
|
+
} else if (specifier.type === "ImportDefaultSpecifier" && specifier.local?.type === "Identifier") importedBindings.set(specifier.local.name, {
|
|
1022
|
+
kind: "default",
|
|
1023
|
+
source
|
|
1024
|
+
});
|
|
1025
|
+
else if (specifier.type === "ImportNamespaceSpecifier" && specifier.local?.type === "Identifier") {
|
|
1026
|
+
importedBindings.set(specifier.local.name, {
|
|
1027
|
+
kind: "namespace",
|
|
1028
|
+
source
|
|
1029
|
+
});
|
|
1030
|
+
if (source === "wevu") wevuNamespaceLocals.add(specifier.local.name);
|
|
1031
|
+
}
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
if (stmt?.type === "ExportNamedDeclaration") {
|
|
1035
|
+
if (stmt.declaration?.type === "FunctionDeclaration") {
|
|
1036
|
+
registerFunctionDeclaration(stmt.declaration);
|
|
1037
|
+
if (stmt.declaration.id?.type === "Identifier") exports.set(stmt.declaration.id.name, {
|
|
1038
|
+
type: "local",
|
|
1039
|
+
localName: stmt.declaration.id.name
|
|
1040
|
+
});
|
|
1041
|
+
continue;
|
|
1042
|
+
}
|
|
1043
|
+
if (stmt.declaration?.type === "VariableDeclaration") {
|
|
1044
|
+
for (const decl of stmt.declaration.declarations ?? []) {
|
|
1045
|
+
registerVariableFunction(decl);
|
|
1046
|
+
if (decl.id?.type === "Identifier") exports.set(decl.id.name, {
|
|
1047
|
+
type: "local",
|
|
1048
|
+
localName: decl.id.name
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
const source = getImportedSpecifierName(stmt.source);
|
|
1054
|
+
for (const spec of stmt.specifiers ?? []) {
|
|
1055
|
+
if (spec?.type !== "ExportSpecifier") continue;
|
|
1056
|
+
const exportedName = getImportedSpecifierName(spec.exported);
|
|
1057
|
+
const localName = getImportedSpecifierName(spec.local);
|
|
1058
|
+
if (!exportedName || !localName) continue;
|
|
1059
|
+
if (source) exports.set(exportedName, {
|
|
1060
|
+
type: "reexport",
|
|
1061
|
+
source,
|
|
1062
|
+
importedName: localName
|
|
1063
|
+
});
|
|
1064
|
+
else exports.set(exportedName, {
|
|
1065
|
+
type: "local",
|
|
1066
|
+
localName
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
continue;
|
|
1070
|
+
}
|
|
1071
|
+
if (stmt?.type === "ExportDefaultDeclaration") {
|
|
1072
|
+
const decl = stmt.declaration;
|
|
1073
|
+
if (decl?.type === "FunctionDeclaration") {
|
|
1074
|
+
registerFunctionDeclaration(decl);
|
|
1075
|
+
if (decl.id?.type === "Identifier") exports.set("default", {
|
|
1076
|
+
type: "local",
|
|
1077
|
+
localName: decl.id.name
|
|
1078
|
+
});
|
|
1079
|
+
else exports.set("default", {
|
|
1080
|
+
type: "inline",
|
|
1081
|
+
node: decl
|
|
1082
|
+
});
|
|
1083
|
+
} else if (decl?.type === "Identifier") exports.set("default", {
|
|
1084
|
+
type: "local",
|
|
1085
|
+
localName: decl.name
|
|
1086
|
+
});
|
|
1087
|
+
else if (isOxcFunctionLike(decl)) exports.set("default", {
|
|
1088
|
+
type: "inline",
|
|
1089
|
+
node: decl
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
return {
|
|
1094
|
+
id,
|
|
1095
|
+
engine: "oxc",
|
|
1096
|
+
wevuNamedHookLocals,
|
|
1097
|
+
wevuNamespaceLocals,
|
|
1098
|
+
importedBindings,
|
|
1099
|
+
localFunctions,
|
|
1100
|
+
exports
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
function createModuleAnalysisFromCode(id, code, options) {
|
|
1104
|
+
const engine = options?.astEngine ?? "babel";
|
|
1105
|
+
const cacheKey = createModuleAnalysisCacheKey(id, engine);
|
|
1106
|
+
const cached = moduleAnalysisCache.get(cacheKey);
|
|
1107
|
+
if (cached && cached.code === code) return cached.analysis;
|
|
1108
|
+
let analysis;
|
|
1109
|
+
if (engine === "oxc") if (!code.includes("import") && !code.includes("export")) analysis = createEmptyModuleAnalysis(id, "oxc");
|
|
1110
|
+
else analysis = createModuleAnalysisWithOxc(id, code);
|
|
1111
|
+
else analysis = createModuleAnalysis(id, parseJsLike(code));
|
|
1112
|
+
moduleAnalysisCache.set(cacheKey, {
|
|
1113
|
+
code,
|
|
1114
|
+
analysis
|
|
1115
|
+
});
|
|
1116
|
+
return analysis;
|
|
1117
|
+
}
|
|
1118
|
+
function getOrCreateExternalModuleAnalysis(moduleId, code, options) {
|
|
1119
|
+
const cacheKey = createExternalModuleAnalysisCacheKey(moduleId, options?.astEngine);
|
|
1120
|
+
const cached = externalModuleAnalysisCache.get(cacheKey);
|
|
1121
|
+
if (cached && cached.code === code) return cached.analysis;
|
|
1122
|
+
const analysis = createModuleAnalysisFromCode(moduleId, code, options);
|
|
1123
|
+
externalModuleAnalysisCache.set(cacheKey, {
|
|
1124
|
+
code,
|
|
1125
|
+
analysis
|
|
1126
|
+
});
|
|
1127
|
+
return analysis;
|
|
1128
|
+
}
|
|
988
1129
|
//#endregion
|
|
989
1130
|
//#region src/plugins/wevu/pageFeatures/optionsObjects.ts
|
|
990
1131
|
function unwrapTypeLikeExpression$2(node) {
|
|
@@ -1082,6 +1223,25 @@ function collectTargetOptionsObjects(ast, moduleId) {
|
|
|
1082
1223
|
module
|
|
1083
1224
|
};
|
|
1084
1225
|
}
|
|
1226
|
+
function collectTargetOptionsObjectsFromCode(code, moduleId, options) {
|
|
1227
|
+
if (options?.astEngine === "oxc") {
|
|
1228
|
+
if (!(code.includes("wevu") && (code.includes(WE_VU_RUNTIME_APIS.defineComponent) || code.includes(WE_VU_RUNTIME_APIS.createWevuComponent)))) return {
|
|
1229
|
+
optionsObjects: [],
|
|
1230
|
+
module: createEmptyModuleAnalysis(moduleId, "oxc")
|
|
1231
|
+
};
|
|
1232
|
+
const module = createModuleAnalysisFromCode(moduleId, code, options);
|
|
1233
|
+
if (![...module.importedBindings.values()].some((binding) => binding.source === "wevu" && (binding.kind === "namespace" || binding.kind === "named" && (binding.importedName === WE_VU_RUNTIME_APIS.defineComponent || binding.importedName === WE_VU_RUNTIME_APIS.createWevuComponent)))) return {
|
|
1234
|
+
optionsObjects: [],
|
|
1235
|
+
module
|
|
1236
|
+
};
|
|
1237
|
+
return {
|
|
1238
|
+
optionsObjects: collectTargetOptionsObjects(parseJsLike(code), moduleId).optionsObjects,
|
|
1239
|
+
module
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
const ast = createModuleAnalysisFromCode(moduleId, code, options).ast;
|
|
1243
|
+
return collectTargetOptionsObjects(ast, moduleId);
|
|
1244
|
+
}
|
|
1085
1245
|
//#endregion
|
|
1086
1246
|
//#region src/plugins/wevu/pageFeatures/reachability/calls.ts
|
|
1087
1247
|
function getCallCalleeName(callee) {
|
|
@@ -1097,8 +1257,36 @@ function getCallCalleeName(callee) {
|
|
|
1097
1257
|
};
|
|
1098
1258
|
return null;
|
|
1099
1259
|
}
|
|
1100
|
-
function collectCalledBindingsFromFunctionBody(fn) {
|
|
1260
|
+
function collectCalledBindingsFromFunctionBody(fn, engine = "babel") {
|
|
1101
1261
|
const called = [];
|
|
1262
|
+
if (engine === "oxc") {
|
|
1263
|
+
const visit = (node) => {
|
|
1264
|
+
if (!node) return;
|
|
1265
|
+
if (node.type === "CallExpression") {
|
|
1266
|
+
const callee = node.callee;
|
|
1267
|
+
if (callee?.type === "Identifier") called.push({
|
|
1268
|
+
type: "ident",
|
|
1269
|
+
name: callee.name
|
|
1270
|
+
});
|
|
1271
|
+
else if (callee?.type === "MemberExpression" && !callee.computed && callee.object?.type === "Identifier" && callee.property?.type === "Identifier") called.push({
|
|
1272
|
+
type: "member",
|
|
1273
|
+
object: callee.object.name,
|
|
1274
|
+
property: callee.property.name
|
|
1275
|
+
});
|
|
1276
|
+
} else if (node.type === "ChainExpression") {
|
|
1277
|
+
visit(node.expression);
|
|
1278
|
+
return;
|
|
1279
|
+
}
|
|
1280
|
+
for (const value of Object.values(node)) {
|
|
1281
|
+
if (!value) continue;
|
|
1282
|
+
if (Array.isArray(value)) {
|
|
1283
|
+
for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
|
|
1284
|
+
} else if (typeof value === "object" && typeof value.type === "string") visit(value);
|
|
1285
|
+
}
|
|
1286
|
+
};
|
|
1287
|
+
visit(fn);
|
|
1288
|
+
return called;
|
|
1289
|
+
}
|
|
1102
1290
|
t.traverseFast(fn, (node) => {
|
|
1103
1291
|
if (t.isCallExpression(node)) {
|
|
1104
1292
|
const name = getCallCalleeName(node.callee);
|
|
@@ -1114,6 +1302,34 @@ function collectCalledBindingsFromFunctionBody(fn) {
|
|
|
1114
1302
|
//#region src/plugins/wevu/pageFeatures/reachability/hooks.ts
|
|
1115
1303
|
function collectWevuHookCallsInFunctionBody(module, fn) {
|
|
1116
1304
|
const enabled = /* @__PURE__ */ new Set();
|
|
1305
|
+
if (module.engine === "oxc") {
|
|
1306
|
+
const visit = (node) => {
|
|
1307
|
+
if (!node) return;
|
|
1308
|
+
if (node.type === "CallExpression") {
|
|
1309
|
+
const callee = node.callee;
|
|
1310
|
+
if (callee?.type === "Identifier") {
|
|
1311
|
+
const matched = module.wevuNamedHookLocals.get(callee.name);
|
|
1312
|
+
if (matched) enabled.add(matched);
|
|
1313
|
+
} else if (callee?.type === "MemberExpression" && !callee.computed && callee.object?.type === "Identifier" && callee.property?.type === "Identifier") {
|
|
1314
|
+
if (module.wevuNamespaceLocals.has(callee.object.name)) {
|
|
1315
|
+
const matched = WE_VU_PAGE_HOOK_TO_FEATURE[callee.property.name];
|
|
1316
|
+
if (matched) enabled.add(matched);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
} else if (node.type === "ChainExpression") {
|
|
1320
|
+
visit(node.expression);
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
for (const value of Object.values(node)) {
|
|
1324
|
+
if (!value) continue;
|
|
1325
|
+
if (Array.isArray(value)) {
|
|
1326
|
+
for (const child of value) if (child && typeof child === "object" && typeof child.type === "string") visit(child);
|
|
1327
|
+
} else if (typeof value === "object" && typeof value.type === "string") visit(value);
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
visit(fn);
|
|
1331
|
+
return enabled;
|
|
1332
|
+
}
|
|
1117
1333
|
t.traverseFast(fn, (node) => {
|
|
1118
1334
|
if (t.isCallExpression(node)) {
|
|
1119
1335
|
const callee = node.callee;
|
|
@@ -1159,7 +1375,7 @@ function resolveExportedFunctionNode(module, exportName) {
|
|
|
1159
1375
|
if (target.type === "inline") return target;
|
|
1160
1376
|
return null;
|
|
1161
1377
|
}
|
|
1162
|
-
async function resolveExternalFunction(resolver, importerId, source, exportName, moduleCache) {
|
|
1378
|
+
async function resolveExternalFunction(resolver, importerId, source, exportName, moduleCache, options) {
|
|
1163
1379
|
if (source === "wevu") return null;
|
|
1164
1380
|
const resolvedId = await resolver.resolveId(source, importerId);
|
|
1165
1381
|
if (!resolvedId) return null;
|
|
@@ -1167,7 +1383,7 @@ async function resolveExternalFunction(resolver, importerId, source, exportName,
|
|
|
1167
1383
|
if (!code) return null;
|
|
1168
1384
|
let analysis = moduleCache.get(resolvedId);
|
|
1169
1385
|
if (!analysis) {
|
|
1170
|
-
analysis = getOrCreateExternalModuleAnalysis(resolvedId, code);
|
|
1386
|
+
analysis = getOrCreateExternalModuleAnalysis(resolvedId, code, options);
|
|
1171
1387
|
moduleCache.set(resolvedId, analysis);
|
|
1172
1388
|
}
|
|
1173
1389
|
const target = resolveExportedFunctionNode(analysis, exportName);
|
|
@@ -1191,7 +1407,7 @@ async function resolveExternalFunction(resolver, importerId, source, exportName,
|
|
|
1191
1407
|
async function walkReachableWevuFeatures(options) {
|
|
1192
1408
|
const { pageModule, setupFn, resolver, moduleCache } = options;
|
|
1193
1409
|
const enabled = /* @__PURE__ */ new Set();
|
|
1194
|
-
const seedCalls = collectCalledBindingsFromFunctionBody(setupFn);
|
|
1410
|
+
const seedCalls = collectCalledBindingsFromFunctionBody(setupFn, pageModule.engine);
|
|
1195
1411
|
const queue = [];
|
|
1196
1412
|
const visitedLocal = /* @__PURE__ */ new Set();
|
|
1197
1413
|
const visitedExternal = /* @__PURE__ */ new Set();
|
|
@@ -1238,18 +1454,18 @@ async function walkReachableWevuFeatures(options) {
|
|
|
1238
1454
|
const fn = pageModule.localFunctions.get(item.name);
|
|
1239
1455
|
if (!fn) continue;
|
|
1240
1456
|
for (const f of collectWevuHookCallsInFunctionBody(pageModule, fn)) enabled.add(f);
|
|
1241
|
-
const calls = collectCalledBindingsFromFunctionBody(fn);
|
|
1457
|
+
const calls = collectCalledBindingsFromFunctionBody(fn, pageModule.engine);
|
|
1242
1458
|
for (const call of calls) seedFromCall(call);
|
|
1243
1459
|
continue;
|
|
1244
1460
|
}
|
|
1245
|
-
const resolved = await resolveExternalFunction(resolver, item.importerId, item.source, item.exportName, moduleCache);
|
|
1461
|
+
const resolved = await resolveExternalFunction(resolver, item.importerId, item.source, item.exportName, moduleCache, { astEngine: options.astEngine });
|
|
1246
1462
|
if (!resolved) continue;
|
|
1247
1463
|
if ("reexport" in resolved) {
|
|
1248
1464
|
enqueueExternal(resolved.moduleId, resolved.reexport.source, resolved.reexport.importedName);
|
|
1249
1465
|
continue;
|
|
1250
1466
|
}
|
|
1251
1467
|
for (const f of collectWevuHookCallsInFunctionBody(resolved.module, resolved.fn)) enabled.add(f);
|
|
1252
|
-
const calls = collectCalledBindingsFromFunctionBody(resolved.fn);
|
|
1468
|
+
const calls = collectCalledBindingsFromFunctionBody(resolved.fn, resolved.module.engine);
|
|
1253
1469
|
for (const call of calls) if (call.type === "ident") {
|
|
1254
1470
|
const binding = resolved.module.importedBindings.get(call.name);
|
|
1255
1471
|
if (binding?.kind === "named") enqueueExternal(resolved.moduleId, binding.source, binding.importedName);
|
|
@@ -1261,7 +1477,7 @@ async function walkReachableWevuFeatures(options) {
|
|
|
1261
1477
|
const localFn = resolved.module.localFunctions.get(call.name);
|
|
1262
1478
|
if (localFn) {
|
|
1263
1479
|
for (const f of collectWevuHookCallsInFunctionBody(resolved.module, localFn)) enabled.add(f);
|
|
1264
|
-
for (const inner of collectCalledBindingsFromFunctionBody(localFn)) if (inner.type === "ident") {
|
|
1480
|
+
for (const inner of collectCalledBindingsFromFunctionBody(localFn, resolved.module.engine)) if (inner.type === "ident") {
|
|
1265
1481
|
const innerBinding = resolved.module.importedBindings.get(inner.name);
|
|
1266
1482
|
if (innerBinding?.kind === "named") enqueueExternal(resolved.moduleId, innerBinding.source, innerBinding.importedName);
|
|
1267
1483
|
else if (innerBinding?.kind === "default") enqueueExternal(resolved.moduleId, innerBinding.source, "default");
|
|
@@ -1278,26 +1494,40 @@ async function walkReachableWevuFeatures(options) {
|
|
|
1278
1494
|
}
|
|
1279
1495
|
//#endregion
|
|
1280
1496
|
//#region src/plugins/wevu/pageFeatures/reachability/index.ts
|
|
1281
|
-
async function collectWevuFeaturesFromSetupReachableImports(pageModule, setupFn, resolver, moduleCache) {
|
|
1497
|
+
async function collectWevuFeaturesFromSetupReachableImports(pageModule, setupFn, resolver, moduleCache, options) {
|
|
1282
1498
|
return await walkReachableWevuFeatures({
|
|
1283
1499
|
pageModule,
|
|
1284
1500
|
setupFn,
|
|
1285
1501
|
resolver,
|
|
1286
|
-
moduleCache
|
|
1502
|
+
moduleCache,
|
|
1503
|
+
astEngine: options?.astEngine
|
|
1287
1504
|
});
|
|
1288
1505
|
}
|
|
1506
|
+
async function collectWevuFeaturesFromCodeReachableImports(code, options) {
|
|
1507
|
+
const { optionsObjects, module } = collectTargetOptionsObjectsFromCode(code, options.id, { astEngine: options.astEngine });
|
|
1508
|
+
if (!optionsObjects.length) return /* @__PURE__ */ new Set();
|
|
1509
|
+
const moduleCache = new Map([[options.id, module]]);
|
|
1510
|
+
const enabled = /* @__PURE__ */ new Set();
|
|
1511
|
+
for (const optionsObject of optionsObjects) {
|
|
1512
|
+
const setupFn = getSetupFunctionFromOptionsObject(optionsObject);
|
|
1513
|
+
if (!setupFn) continue;
|
|
1514
|
+
const reachable = await collectWevuFeaturesFromSetupReachableImports(module, setupFn, options.resolver, moduleCache, { astEngine: options.astEngine });
|
|
1515
|
+
for (const feature of reachable) enabled.add(feature);
|
|
1516
|
+
}
|
|
1517
|
+
return enabled;
|
|
1518
|
+
}
|
|
1289
1519
|
//#endregion
|
|
1290
1520
|
//#region src/plugins/wevu/pageFeatures/inject.ts
|
|
1291
1521
|
/**
|
|
1292
1522
|
* 在 JS 源码中注入 wevu 页面特性(基于本文件分析)。
|
|
1293
1523
|
*/
|
|
1294
|
-
function injectWevuPageFeaturesInJs(source) {
|
|
1295
|
-
const
|
|
1296
|
-
const enabled = collectWevuPageFeatureFlags(ast);
|
|
1524
|
+
function injectWevuPageFeaturesInJs(source, options) {
|
|
1525
|
+
const enabled = collectWevuPageFeatureFlagsFromCode(source, options);
|
|
1297
1526
|
if (!enabled.size) return {
|
|
1298
1527
|
code: source,
|
|
1299
1528
|
transformed: false
|
|
1300
1529
|
};
|
|
1530
|
+
const ast = parseJsLike(source);
|
|
1301
1531
|
const { optionsObjects } = collectTargetOptionsObjects(ast, "<inline>");
|
|
1302
1532
|
if (!optionsObjects.length) return {
|
|
1303
1533
|
code: source,
|
|
@@ -1318,20 +1548,25 @@ function injectWevuPageFeaturesInJs(source) {
|
|
|
1318
1548
|
* 在 JS 源码中注入 wevu 页面特性(支持跨模块解析)。
|
|
1319
1549
|
*/
|
|
1320
1550
|
async function injectWevuPageFeaturesInJsWithResolver(source, options) {
|
|
1551
|
+
const preflight = collectTargetOptionsObjectsFromCode(source, options.id, { astEngine: options.astEngine });
|
|
1552
|
+
if (!preflight.optionsObjects.length) return {
|
|
1553
|
+
code: source,
|
|
1554
|
+
transformed: false
|
|
1555
|
+
};
|
|
1321
1556
|
const ast = parseJsLike(source);
|
|
1322
|
-
const { optionsObjects
|
|
1557
|
+
const { optionsObjects } = collectTargetOptionsObjects(ast, options.id);
|
|
1323
1558
|
if (!optionsObjects.length) return {
|
|
1324
1559
|
code: source,
|
|
1325
1560
|
transformed: false
|
|
1326
1561
|
};
|
|
1327
1562
|
const enabled = /* @__PURE__ */ new Set();
|
|
1328
|
-
for (const flag of
|
|
1563
|
+
for (const flag of collectWevuPageFeatureFlagsFromCode(source, options)) enabled.add(flag);
|
|
1329
1564
|
const moduleCache = /* @__PURE__ */ new Map();
|
|
1330
|
-
moduleCache.set(options.id, module);
|
|
1565
|
+
moduleCache.set(options.id, preflight.module);
|
|
1331
1566
|
for (const optionsObject of optionsObjects) {
|
|
1332
1567
|
const setupFn = getSetupFunctionFromOptionsObject(optionsObject);
|
|
1333
1568
|
if (!setupFn) continue;
|
|
1334
|
-
const fromImports = await collectWevuFeaturesFromSetupReachableImports(module, setupFn, options.resolver, moduleCache);
|
|
1569
|
+
const fromImports = await collectWevuFeaturesFromSetupReachableImports(preflight.module, setupFn, options.resolver, moduleCache, { astEngine: options.astEngine });
|
|
1335
1570
|
for (const flag of fromImports) enabled.add(flag);
|
|
1336
1571
|
}
|
|
1337
1572
|
if (!enabled.size) return {
|
|
@@ -2702,19 +2937,7 @@ function printExpression(exp) {
|
|
|
2702
2937
|
return generate(exp).code;
|
|
2703
2938
|
}
|
|
2704
2939
|
function unwrapTsExpression$2(exp) {
|
|
2705
|
-
|
|
2706
|
-
while (t.isTSAsExpression(current) || t.isTSTypeAssertion(current) || t.isTSNonNullExpression(current) || t.isParenthesizedExpression(current) || t.isTSInstantiationExpression(current)) {
|
|
2707
|
-
if (t.isTSAsExpression(current) || t.isTSTypeAssertion(current) || t.isTSNonNullExpression(current)) {
|
|
2708
|
-
current = current.expression;
|
|
2709
|
-
continue;
|
|
2710
|
-
}
|
|
2711
|
-
if (t.isParenthesizedExpression(current)) {
|
|
2712
|
-
current = current.expression;
|
|
2713
|
-
continue;
|
|
2714
|
-
}
|
|
2715
|
-
if (t.isTSInstantiationExpression(current)) current = current.expression;
|
|
2716
|
-
}
|
|
2717
|
-
return current;
|
|
2940
|
+
return unwrapTypeScriptExpression(exp);
|
|
2718
2941
|
}
|
|
2719
2942
|
function normalizeInterpolationExpression(exp) {
|
|
2720
2943
|
return normalizeWxmlExpression(printExpression(unwrapTsExpression$2(exp)));
|
|
@@ -2760,47 +2983,12 @@ function registerInlineExpression$1(exp, context) {
|
|
|
2760
2983
|
scopeKeys
|
|
2761
2984
|
};
|
|
2762
2985
|
}
|
|
2763
|
-
function toStaticObjectKey(key) {
|
|
2764
|
-
if (t.isIdentifier(key)) return key.name;
|
|
2765
|
-
if (t.isStringLiteral(key)) return key.value;
|
|
2766
|
-
return null;
|
|
2767
|
-
}
|
|
2768
|
-
function getObjectPropertyByKey(node, key) {
|
|
2769
|
-
for (const prop of node.properties) {
|
|
2770
|
-
if (t.isObjectMethod(prop)) {
|
|
2771
|
-
if (toStaticObjectKey(prop.key) === key) return prop;
|
|
2772
|
-
continue;
|
|
2773
|
-
}
|
|
2774
|
-
if (!t.isObjectProperty(prop) || prop.computed) continue;
|
|
2775
|
-
if (toStaticObjectKey(prop.key) === key) return prop;
|
|
2776
|
-
}
|
|
2777
|
-
return null;
|
|
2778
|
-
}
|
|
2779
2986
|
function toJsxTagName(name, context) {
|
|
2780
2987
|
if (t.isJSXIdentifier(name)) return name.name;
|
|
2781
2988
|
if (t.isJSXNamespacedName(name)) return `${name.namespace.name}:${name.name.name}`;
|
|
2782
2989
|
context.warnings.push("暂不支持 JSX 成员标签(如 <Foo.Bar />),已回退为 <view />。");
|
|
2783
2990
|
return "view";
|
|
2784
2991
|
}
|
|
2785
|
-
function resolveRenderableExpression(node) {
|
|
2786
|
-
if (t.isObjectMethod(node)) {
|
|
2787
|
-
for (const statement of node.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2788
|
-
return null;
|
|
2789
|
-
}
|
|
2790
|
-
if (!node.value) return null;
|
|
2791
|
-
const value = node.value;
|
|
2792
|
-
if (t.isArrowFunctionExpression(value)) {
|
|
2793
|
-
if (t.isBlockStatement(value.body)) {
|
|
2794
|
-
for (const statement of value.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2795
|
-
return null;
|
|
2796
|
-
}
|
|
2797
|
-
return unwrapTsExpression$2(value.body);
|
|
2798
|
-
}
|
|
2799
|
-
if (t.isFunctionExpression(value)) {
|
|
2800
|
-
for (const statement of value.body.body) if (t.isReturnStatement(statement) && statement.argument) return unwrapTsExpression$2(statement.argument);
|
|
2801
|
-
}
|
|
2802
|
-
return null;
|
|
2803
|
-
}
|
|
2804
2992
|
//#endregion
|
|
2805
2993
|
//#region src/plugins/jsx/compileJsx/script.ts
|
|
2806
2994
|
function removeRenderOptionFromObjectExpression(node) {
|
|
@@ -3177,81 +3365,16 @@ function resolveRenderExpression(componentExpr, context) {
|
|
|
3177
3365
|
context.warnings.push("JSX 编译仅支持对象字面量组件选项。");
|
|
3178
3366
|
return null;
|
|
3179
3367
|
}
|
|
3180
|
-
const
|
|
3181
|
-
if (!
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3368
|
+
const renderExpression = resolveRenderExpressionFromComponentOptions(componentExpr);
|
|
3369
|
+
if (!renderExpression) {
|
|
3370
|
+
if (!getRenderPropertyFromComponentOptions(componentExpr)) {
|
|
3371
|
+
context.warnings.push("未找到 render(),请在默认导出组件中声明 render 函数。");
|
|
3372
|
+
return null;
|
|
3373
|
+
}
|
|
3186
3374
|
context.warnings.push("render 不是可执行函数。");
|
|
3187
3375
|
return null;
|
|
3188
3376
|
}
|
|
3189
|
-
return
|
|
3190
|
-
}
|
|
3191
|
-
/**
|
|
3192
|
-
* 单次遍历同时收集导入组件信息和默认导出表达式,避免多次 traverse 开销。
|
|
3193
|
-
*/
|
|
3194
|
-
function collectImportsAndExportDefault(ast) {
|
|
3195
|
-
const defineComponentAliases = new Set(["defineComponent", "_defineComponent"]);
|
|
3196
|
-
const defineComponentDecls = /* @__PURE__ */ new Map();
|
|
3197
|
-
const imports = /* @__PURE__ */ new Map();
|
|
3198
|
-
let exportDefaultExpression = null;
|
|
3199
|
-
traverse(ast, {
|
|
3200
|
-
ImportDeclaration(path) {
|
|
3201
|
-
const source = path.node.source.value;
|
|
3202
|
-
if (source === "wevu" || source === "vue") for (const specifier of path.node.specifiers) {
|
|
3203
|
-
if (!t.isImportSpecifier(specifier)) continue;
|
|
3204
|
-
if (!t.isIdentifier(specifier.imported, { name: "defineComponent" })) continue;
|
|
3205
|
-
defineComponentAliases.add(specifier.local.name);
|
|
3206
|
-
}
|
|
3207
|
-
if (path.node.importKind === "type") return;
|
|
3208
|
-
if (!t.isStringLiteral(path.node.source)) return;
|
|
3209
|
-
const importSource = path.node.source.value;
|
|
3210
|
-
for (const specifier of path.node.specifiers) {
|
|
3211
|
-
if ("importKind" in specifier && specifier.importKind === "type") continue;
|
|
3212
|
-
if (!("local" in specifier) || !t.isIdentifier(specifier.local)) continue;
|
|
3213
|
-
const localName = specifier.local.name;
|
|
3214
|
-
if (t.isImportDefaultSpecifier(specifier)) {
|
|
3215
|
-
imports.set(localName, {
|
|
3216
|
-
localName,
|
|
3217
|
-
importSource,
|
|
3218
|
-
importedName: "default",
|
|
3219
|
-
kind: "default"
|
|
3220
|
-
});
|
|
3221
|
-
continue;
|
|
3222
|
-
}
|
|
3223
|
-
if (!t.isImportSpecifier(specifier)) continue;
|
|
3224
|
-
const importedName = t.isIdentifier(specifier.imported) ? specifier.imported.name : t.isStringLiteral(specifier.imported) ? specifier.imported.value : void 0;
|
|
3225
|
-
imports.set(localName, {
|
|
3226
|
-
localName,
|
|
3227
|
-
importSource,
|
|
3228
|
-
importedName,
|
|
3229
|
-
kind: "named"
|
|
3230
|
-
});
|
|
3231
|
-
}
|
|
3232
|
-
},
|
|
3233
|
-
VariableDeclarator(path) {
|
|
3234
|
-
if (!t.isIdentifier(path.node.id) || !path.node.init) return;
|
|
3235
|
-
if (t.isObjectExpression(path.node.init)) {
|
|
3236
|
-
defineComponentDecls.set(path.node.id.name, t.cloneNode(path.node.init, true));
|
|
3237
|
-
return;
|
|
3238
|
-
}
|
|
3239
|
-
if (!t.isCallExpression(path.node.init)) return;
|
|
3240
|
-
const callee = path.node.init.callee;
|
|
3241
|
-
if (!t.isIdentifier(callee) || !defineComponentAliases.has(callee.name)) return;
|
|
3242
|
-
const first = path.node.init.arguments[0];
|
|
3243
|
-
if (t.isObjectExpression(first)) defineComponentDecls.set(path.node.id.name, t.cloneNode(first, true));
|
|
3244
|
-
},
|
|
3245
|
-
ExportDefaultDeclaration(path) {
|
|
3246
|
-
const declaration = path.node.declaration;
|
|
3247
|
-
if (t.isDeclaration(declaration)) return;
|
|
3248
|
-
exportDefaultExpression = resolveComponentExpression(declaration, defineComponentDecls, defineComponentAliases);
|
|
3249
|
-
}
|
|
3250
|
-
});
|
|
3251
|
-
return {
|
|
3252
|
-
importedComponents: [...imports.values()],
|
|
3253
|
-
exportDefaultExpression
|
|
3254
|
-
};
|
|
3377
|
+
return renderExpression;
|
|
3255
3378
|
}
|
|
3256
3379
|
function isCollectableJsxTemplateTag(tag) {
|
|
3257
3380
|
if (!tag) return false;
|
|
@@ -3259,71 +3382,21 @@ function isCollectableJsxTemplateTag(tag) {
|
|
|
3259
3382
|
return !isBuiltinComponent(tag);
|
|
3260
3383
|
}
|
|
3261
3384
|
/**
|
|
3262
|
-
* 递归收集 JSX 表达式中的自定义组件标签名。
|
|
3263
|
-
* 直接遍历 AST 节点,无需 cloneNode 和 Babel traverse。
|
|
3264
|
-
*/
|
|
3265
|
-
function collectJsxTemplateTags(renderExpression) {
|
|
3266
|
-
const tags = /* @__PURE__ */ new Set();
|
|
3267
|
-
function walk(node) {
|
|
3268
|
-
if (t.isJSXElement(node)) {
|
|
3269
|
-
const { name } = node.openingElement;
|
|
3270
|
-
if (!t.isJSXMemberExpression(name)) {
|
|
3271
|
-
let tag = null;
|
|
3272
|
-
if (t.isJSXIdentifier(name)) tag = name.name;
|
|
3273
|
-
else if (t.isJSXNamespacedName(name)) tag = `${name.namespace.name}:${name.name.name}`;
|
|
3274
|
-
if (tag && isCollectableJsxTemplateTag(tag)) tags.add(tag);
|
|
3275
|
-
}
|
|
3276
|
-
for (const child of node.children) walk(child);
|
|
3277
|
-
return;
|
|
3278
|
-
}
|
|
3279
|
-
if (t.isJSXFragment(node)) {
|
|
3280
|
-
for (const child of node.children) walk(child);
|
|
3281
|
-
return;
|
|
3282
|
-
}
|
|
3283
|
-
if (t.isJSXExpressionContainer(node) && !t.isJSXEmptyExpression(node.expression)) {
|
|
3284
|
-
walk(node.expression);
|
|
3285
|
-
return;
|
|
3286
|
-
}
|
|
3287
|
-
if (t.isConditionalExpression(node)) {
|
|
3288
|
-
walk(node.consequent);
|
|
3289
|
-
walk(node.alternate);
|
|
3290
|
-
return;
|
|
3291
|
-
}
|
|
3292
|
-
if (t.isLogicalExpression(node)) {
|
|
3293
|
-
walk(node.left);
|
|
3294
|
-
walk(node.right);
|
|
3295
|
-
return;
|
|
3296
|
-
}
|
|
3297
|
-
if (t.isCallExpression(node)) {
|
|
3298
|
-
for (const arg of node.arguments) if (t.isExpression(arg)) walk(arg);
|
|
3299
|
-
return;
|
|
3300
|
-
}
|
|
3301
|
-
if (t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) {
|
|
3302
|
-
if (t.isBlockStatement(node.body)) {
|
|
3303
|
-
for (const stmt of node.body.body) if (t.isReturnStatement(stmt) && stmt.argument) walk(stmt.argument);
|
|
3304
|
-
} else walk(node.body);
|
|
3305
|
-
return;
|
|
3306
|
-
}
|
|
3307
|
-
if (t.isArrayExpression(node)) {
|
|
3308
|
-
for (const element of node.elements) if (element && t.isExpression(element)) walk(element);
|
|
3309
|
-
return;
|
|
3310
|
-
}
|
|
3311
|
-
if (t.isParenthesizedExpression(node) || t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node) || t.isTSNonNullExpression(node)) walk(node.expression);
|
|
3312
|
-
}
|
|
3313
|
-
walk(renderExpression);
|
|
3314
|
-
return tags;
|
|
3315
|
-
}
|
|
3316
|
-
/**
|
|
3317
3385
|
* 从已解析的 AST 中一次性提取 render 表达式和自动组件上下文。
|
|
3318
3386
|
* 内部只调用一次 collectImportsAndExportDefault,避免重复遍历。
|
|
3319
3387
|
*/
|
|
3320
3388
|
function analyzeJsxAst(ast, context) {
|
|
3321
|
-
const { importedComponents, exportDefaultExpression } =
|
|
3389
|
+
const { importedComponents, exportDefaultExpression } = collectJsxImportedComponentsAndDefaultExportFromBabelAst(ast, {
|
|
3390
|
+
isDefineComponentSource(source) {
|
|
3391
|
+
return source === "wevu" || source === "vue";
|
|
3392
|
+
},
|
|
3393
|
+
resolveBabelComponentExpression: resolveComponentExpression
|
|
3394
|
+
});
|
|
3322
3395
|
let renderExpression = null;
|
|
3323
3396
|
let templateTags = /* @__PURE__ */ new Set();
|
|
3324
3397
|
if (exportDefaultExpression) {
|
|
3325
3398
|
renderExpression = resolveRenderExpression(exportDefaultExpression, context);
|
|
3326
|
-
if (renderExpression) templateTags =
|
|
3399
|
+
if (renderExpression) templateTags = collectJsxTemplateTagsFromBabelExpression(renderExpression, isCollectableJsxTemplateTag);
|
|
3327
3400
|
}
|
|
3328
3401
|
return {
|
|
3329
3402
|
renderExpression,
|
|
@@ -7131,4 +7204,4 @@ async function compileVueFile(source, filename, options) {
|
|
|
7131
7204
|
return result;
|
|
7132
7205
|
}
|
|
7133
7206
|
//#endregion
|
|
7134
|
-
export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectVueTemplateTags, collectWevuPageFeatureFlags, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|
|
7207
|
+
export { CLASS_STYLE_WXS_FILE, CLASS_STYLE_WXS_MODULE, RESERVED_VUE_COMPONENT_TAGS, VUE_COMPONENT_TAG_RE, WE_VU_MODULE_ID, WE_VU_PAGE_HOOK_TO_FEATURE, WE_VU_RUNTIME_APIS, alipayPlatform, buildClassStyleComputedCode, buildClassStyleWxsTag, builtinComponentsSet, clearFileCaches, collectTargetOptionsObjectsFromCode, collectVueTemplateTags, collectWevuFeaturesFromCodeReachableImports, collectWevuPageFeatureFlags, collectWevuPageFeatureFlagsFromCode, compileConfigBlocks, compileJsxFile, compileVueFile as compileSfc, compileVueFile, compileVueStyleToWxss as compileStyle, compileVueStyleToWxss, compileVueTemplateToWxml as compileTemplate, compileVueTemplateToWxml, createJsonMerger, createPageEntryMatcher, evaluateJsLikeConfig, extractJsonMacroFromScriptSetup, generateScopedId, getClassStyleWxsSource, getMiniProgramTemplatePlatform, getSfcCheckMtime, injectWevuPageFeatureFlagsIntoOptionsObject, injectWevuPageFeaturesInJs, injectWevuPageFeaturesInJsWithResolver, invalidateFileCache, isAutoImportCandidateTag, isBuiltinComponent, isInvalidate, isJsonLikeLang, loadCache, mergeJsonWithStrategy, mtimeCache, normalizeConfigLang, pathExists, preprocessScriptSetupSrc, preprocessScriptSrc, readAndParseSfc, readFile, resolveClassStyleWxsLocation, resolveJsLikeLang, resolveSfcBlockSrc, restoreScriptSetupSrc, restoreScriptSrc, stripJsonMacroCallsFromCode, swanPlatform, transformScript, transformScript as transformSfcScript, ttPlatform, wechatPlatform };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wevu/compiler",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.9.1",
|
|
5
5
|
"description": "wevu 编译器基础包,面向小程序模板的编译与转换",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -41,20 +41,17 @@
|
|
|
41
41
|
"dist"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@babel/generator": "^7.29.1",
|
|
45
|
-
"@babel/parser": "^7.29.0",
|
|
46
|
-
"@babel/traverse": "^7.29.0",
|
|
47
|
-
"@babel/types": "^7.29.0",
|
|
48
44
|
"@vue/compiler-core": "^3.5.30",
|
|
49
45
|
"comment-json": "^4.6.2",
|
|
50
46
|
"fs-extra": "^11.3.4",
|
|
51
|
-
"lru-cache": "^11.2.
|
|
47
|
+
"lru-cache": "^11.2.7",
|
|
52
48
|
"magic-string": "^0.30.21",
|
|
53
49
|
"merge": "^2.1.1",
|
|
54
50
|
"pathe": "^2.0.3",
|
|
55
51
|
"vue": "^3.5.30",
|
|
56
|
-
"@weapp-
|
|
57
|
-
"rolldown-require": "2.0.
|
|
52
|
+
"@weapp-vite/ast": "6.9.1",
|
|
53
|
+
"rolldown-require": "2.0.8",
|
|
54
|
+
"@weapp-core/shared": "3.0.2"
|
|
58
55
|
},
|
|
59
56
|
"publishConfig": {
|
|
60
57
|
"access": "public",
|