@wevu/compiler 6.21.0 → 6.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +26 -5
- package/dist/index.mjs +163 -121
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -353,9 +353,16 @@ interface TemplateCompileOptions {
|
|
|
353
353
|
wxsExtension?: string;
|
|
354
354
|
classStyleWxsSrc?: string;
|
|
355
355
|
functionPropNames?: Iterable<FunctionPropNameMatcher>;
|
|
356
|
+
/**
|
|
357
|
+
* 允许保留在小程序模板中的直接函数调用名。
|
|
358
|
+
*/
|
|
359
|
+
templateSafeCallNames?: Iterable<string>;
|
|
356
360
|
wevuComponentTags?: Iterable<string>;
|
|
357
361
|
componentNameMap?: Record<string, string>;
|
|
358
362
|
miniProgramComponentTags?: Iterable<string>;
|
|
363
|
+
scopeId?: string;
|
|
364
|
+
slottedScopeId?: string;
|
|
365
|
+
cssVars?: boolean;
|
|
359
366
|
}
|
|
360
367
|
/**
|
|
361
368
|
* 作用域插槽编译模式。
|
|
@@ -604,6 +611,10 @@ interface CompileVueFileOptions {
|
|
|
604
611
|
* 是否在当前阶段改写 scoped 选择器。预处理语言应由最终 CSS 管线完成隔离时可关闭。
|
|
605
612
|
*/
|
|
606
613
|
transformScoped?: boolean;
|
|
614
|
+
/**
|
|
615
|
+
* 按预处理语言传递的 Vite CSS 预处理选项。
|
|
616
|
+
*/
|
|
617
|
+
preprocessOptions?: Record<string, Record<string, unknown>>;
|
|
607
618
|
};
|
|
608
619
|
json?: {
|
|
609
620
|
kind?: 'app' | 'page' | 'component';
|
|
@@ -690,7 +701,6 @@ declare function clearFileCaches(): void;
|
|
|
690
701
|
declare function transformNestedWxssVars(source: string): string;
|
|
691
702
|
//#endregion
|
|
692
703
|
//#region src/plugins/vue/compiler/style.d.ts
|
|
693
|
-
declare function transformVueDeepSelectors(source: string): string;
|
|
694
704
|
/**
|
|
695
705
|
* 样式编译结果。
|
|
696
706
|
*/
|
|
@@ -698,23 +708,30 @@ interface StyleCompileResult {
|
|
|
698
708
|
code: string;
|
|
699
709
|
map?: string;
|
|
700
710
|
scopedId?: string;
|
|
711
|
+
usesSlotted?: boolean;
|
|
701
712
|
modules?: Record<string, Record<string, string>>;
|
|
713
|
+
dependencies?: string[];
|
|
702
714
|
}
|
|
703
715
|
/**
|
|
704
716
|
* 样式编译选项。
|
|
705
717
|
*/
|
|
706
718
|
interface StyleCompileOptions {
|
|
707
719
|
id: string;
|
|
720
|
+
filename?: string;
|
|
708
721
|
scoped?: boolean;
|
|
709
722
|
transformScoped?: boolean;
|
|
710
723
|
modules?: boolean | string;
|
|
711
|
-
preprocessOptions?: Record<string,
|
|
724
|
+
preprocessOptions?: Record<string, unknown>;
|
|
712
725
|
preserveDeepSelectors?: boolean;
|
|
713
726
|
}
|
|
714
727
|
/**
|
|
715
|
-
*
|
|
728
|
+
* compiler-sfc 已在 scoped 插件中处理 deep 选择器,此函数保留为兼容入口。
|
|
716
729
|
*/
|
|
717
|
-
declare function
|
|
730
|
+
declare function transformVueDeepSelectors(source: string): string;
|
|
731
|
+
/**
|
|
732
|
+
* 将 Vue SFC style 块编译为可交给 Vite CSS 管线的内容。
|
|
733
|
+
*/
|
|
734
|
+
declare function compileVueStyleToWxss(styleBlock: SFCStyleBlock, options: StyleCompileOptions): Promise<StyleCompileResult>;
|
|
718
735
|
//#endregion
|
|
719
736
|
//#region src/plugins/vue/compiler/template/classStyleRuntime.d.ts
|
|
720
737
|
/**
|
|
@@ -833,7 +850,7 @@ declare function createJsonMerger(strategy: JsonMergeStrategy | undefined, baseC
|
|
|
833
850
|
//#endregion
|
|
834
851
|
//#region src/plugins/vue/transform/scopedId.d.ts
|
|
835
852
|
/**
|
|
836
|
-
*
|
|
853
|
+
* 根据项目内相对路径生成跨机器稳定的 scoped ID。
|
|
837
854
|
*/
|
|
838
855
|
declare function generateScopedId(filename: string): string;
|
|
839
856
|
//#endregion
|
|
@@ -929,6 +946,10 @@ interface TransformScriptOptions {
|
|
|
929
946
|
* 当前组件模板包含 scoped slot outlet,需要接收 scoped slot 桥接属性。
|
|
930
947
|
*/
|
|
931
948
|
scopedSlotHostProperties?: boolean;
|
|
949
|
+
/**
|
|
950
|
+
* 当前 SFC 的 CSS Modules 映射。
|
|
951
|
+
*/
|
|
952
|
+
cssModules?: Record<string, Record<string, string>>;
|
|
932
953
|
}
|
|
933
954
|
//#endregion
|
|
934
955
|
//#region src/plugins/vue/transform/transformScript/index.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEVU_CLASS_STYLE_RUNTIME_FILE, WEVU_CLASS_STYLE_RUNTIME_MODULE, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_FUNCTION_PROP_PATHS_KEY, WEVU_INLINE_HANDLER, WEVU_INLINE_MAP_KEY, WEVU_IS_PAGE_KEY, WEVU_JSX_ISLAND_DATA_KEY, WEVU_JSX_ISLAND_HANDLER, WEVU_JSX_ISLAND_TEMPLATE_NAME, WEVU_LAYOUT_HOSTS_KEY, WEVU_LAYOUT_HOST_ID_PREFIX, WEVU_LAYOUT_HOST_REF_PREFIX, WEVU_MODEL_HANDLER, WEVU_OWNER_HANDLER, WEVU_PROPS_ALIASES_KEY, WEVU_PROPS_DERIVED_KEYS_KEY, WEVU_PROPS_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_FUNCTION_TOKEN, WEVU_SLOT_NAMES_ATTR, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_OWNER_KEY, WEVU_SLOT_OWNER_PROXY_KEY, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_PROPS_DATA_KEY, WEVU_SLOT_PROPS_KEY, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY, WEVU_TEMPLATE_REFS_KEY, WEVU_TEMPLATE_REF_CLASS_PREFIX } from "@weapp-core/constants";
|
|
2
|
+
import { WEAPP_I18N_RUNTIME_MARKER, WEAPP_VITE_RUNTIME_REACTIVITY_VIRTUAL_ID, WEAPP_VITE_RUNTIME_TEMPLATE_VIRTUAL_ID, WEAPP_VITE_RUNTIME_VIRTUAL_ID, WEVU_CLASS_STYLE_RUNTIME_FILE, WEVU_CLASS_STYLE_RUNTIME_MODULE, WEVU_CSS_MODULES_KEY, WEVU_CSS_VARS_STYLE_KEY, WEVU_EXPRESSION_ERROR_IDENTIFIER, WEVU_FUNCTION_PROP_PATHS_KEY, WEVU_INLINE_HANDLER, WEVU_INLINE_MAP_KEY, WEVU_IS_PAGE_KEY, WEVU_JSX_ISLAND_DATA_KEY, WEVU_JSX_ISLAND_HANDLER, WEVU_JSX_ISLAND_TEMPLATE_NAME, WEVU_LAYOUT_HOSTS_KEY, WEVU_LAYOUT_HOST_ID_PREFIX, WEVU_LAYOUT_HOST_REF_PREFIX, WEVU_MODEL_HANDLER, WEVU_OWNER_HANDLER, WEVU_PROPS_ALIASES_KEY, WEVU_PROPS_DERIVED_KEYS_KEY, WEVU_PROPS_KEY, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_BASE, WEVU_SLOT_FALLBACK_VIRTUAL_HOST_TAG_NAME, WEVU_SLOT_FUNCTION_TOKEN, WEVU_SLOT_NAMES_ATTR, WEVU_SLOT_NAMES_PROP, WEVU_SLOT_OWNER_ID_ATTR, WEVU_SLOT_OWNER_ID_KEY, WEVU_SLOT_OWNER_ID_PROP, WEVU_SLOT_OWNER_KEY, WEVU_SLOT_OWNER_PROXY_KEY, WEVU_SLOT_PROPS_ATTR, WEVU_SLOT_PROPS_DATA_KEY, WEVU_SLOT_PROPS_KEY, WEVU_SLOT_SCOPE_ATTR, WEVU_SLOT_SCOPE_KEY, WEVU_TEMPLATE_REFS_KEY, WEVU_TEMPLATE_REF_CLASS_PREFIX } from "@weapp-core/constants";
|
|
3
3
|
import { getMiniProgramRuntimeGlobalKeys, getMiniProgramTemplatePreset, removeExtensionDeep } from "@weapp-core/shared";
|
|
4
4
|
import path from "pathe";
|
|
5
5
|
import { NodeTypes, baseParse } from "@vue/compiler-core";
|
|
@@ -18,7 +18,7 @@ import { LRUCache } from "lru-cache";
|
|
|
18
18
|
import { collectJsxImportedComponentsAndDefaultExportFromBabelAst, collectJsxTemplateTagsFromBabelExpression, getObjectPropertyByKey, getRenderPropertyFromComponentOptions, parseJsLikeWithEngine, resolveRenderExpressionFromComponentOptions, toStaticObjectKey, unwrapTypeScriptExpression } from "@weapp-vite/ast";
|
|
19
19
|
import vueJsxPlugin from "@vue/babel-plugin-jsx";
|
|
20
20
|
import { transformSync } from "@weapp-vite/ast/babelCore";
|
|
21
|
-
import { compileScript, parse } from "vue/compiler-sfc";
|
|
21
|
+
import { compileScript, compileStyleAsync, parse } from "vue/compiler-sfc";
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
23
|
import postcss from "postcss";
|
|
24
24
|
import selectorParser from "postcss-selector-parser";
|
|
@@ -2523,6 +2523,8 @@ const INTERNAL_RUNTIME_VALUE_EXPORTS = /* @__PURE__ */ new Set([
|
|
|
2523
2523
|
"triggerRef",
|
|
2524
2524
|
"unref",
|
|
2525
2525
|
"useAttrs",
|
|
2526
|
+
"useCssModule",
|
|
2527
|
+
"useCssVars",
|
|
2526
2528
|
"useAsyncPullDownRefresh",
|
|
2527
2529
|
"useBindModel",
|
|
2528
2530
|
"useBoundingClientRect",
|
|
@@ -2605,6 +2607,8 @@ function createImportVisitors(program, state) {
|
|
|
2605
2607
|
"resolveComponent",
|
|
2606
2608
|
"resolveDirective",
|
|
2607
2609
|
"useAttrs",
|
|
2610
|
+
"useCssModule",
|
|
2611
|
+
"useCssVars",
|
|
2608
2612
|
"useSlots",
|
|
2609
2613
|
"useModel",
|
|
2610
2614
|
"mergeModels",
|
|
@@ -3673,6 +3677,14 @@ function injectFunctionPropPaths(componentOptionsObject, paths) {
|
|
|
3673
3677
|
componentOptionsObject.properties.push(t.objectProperty(t.identifier(WEVU_FUNCTION_PROP_PATHS_KEY), t.arrayExpression(uniquePaths.map((path) => t.stringLiteral(path)))));
|
|
3674
3678
|
return true;
|
|
3675
3679
|
}
|
|
3680
|
+
function createObjectLiteral(value) {
|
|
3681
|
+
return t.objectExpression(Object.entries(value).map(([key, item]) => t.objectProperty(t.stringLiteral(key), item && typeof item === "object" && !Array.isArray(item) ? createObjectLiteral(item) : t.valueToNode(item))));
|
|
3682
|
+
}
|
|
3683
|
+
function injectCssModules(componentOptionsObject, modules) {
|
|
3684
|
+
if (hasStaticProperty(componentOptionsObject, WEVU_CSS_MODULES_KEY)) return false;
|
|
3685
|
+
componentOptionsObject.properties.push(t.objectProperty(t.stringLiteral(WEVU_CSS_MODULES_KEY), createObjectLiteral(modules)));
|
|
3686
|
+
return true;
|
|
3687
|
+
}
|
|
3676
3688
|
function createScopedSlotHostPropertyDefinition(typeName, value) {
|
|
3677
3689
|
return t.objectExpression([t.objectProperty(t.identifier("type"), typeName === "String" ? t.identifier("String") : t.nullLiteral()), t.objectProperty(t.identifier("value"), value === null ? t.nullLiteral() : t.stringLiteral(value))]);
|
|
3678
3690
|
}
|
|
@@ -3806,6 +3818,7 @@ function rewriteDefaultExport(ast, state, options, enabledPageFeatures, serializ
|
|
|
3806
3818
|
if (componentOptionsObject) transformed = injectSetupInitialData(componentOptionsObject) || transformed;
|
|
3807
3819
|
if (componentOptionsObject && options?.relaxStructuredTypeOnlyProps) transformed = relaxStructuredTypeOnlyProps(componentOptionsObject) || transformed;
|
|
3808
3820
|
if (componentOptionsObject && options?.scopedSlotHostProperties) transformed = injectScopedSlotHostProperties(componentOptionsObject) || transformed;
|
|
3821
|
+
if (componentOptionsObject && options?.cssModules && Object.keys(options.cssModules).length) transformed = injectCssModules(componentOptionsObject, options.cssModules) || transformed;
|
|
3809
3822
|
if (componentOptionsObject) {
|
|
3810
3823
|
transformed = injectPropsAliases(componentOptionsObject, options?.propsAliases) || transformed;
|
|
3811
3824
|
transformed = injectPropsDerivedKeys(componentOptionsObject, options?.propsDerivedKeys) || transformed;
|
|
@@ -3928,6 +3941,31 @@ function createInlineExpressionId(seed) {
|
|
|
3928
3941
|
return `i${seed.toString(36)}`;
|
|
3929
3942
|
}
|
|
3930
3943
|
//#endregion
|
|
3944
|
+
//#region src/plugins/vue/compiler/template/expression/numeric.ts
|
|
3945
|
+
const DIGIT_NUMERIC_SEPARATOR_RE = /\d_\d/;
|
|
3946
|
+
const NON_DECIMAL_NUMERIC_LITERAL_RE = /\b0[bxo][\da-f_]/i;
|
|
3947
|
+
const DECIMAL_BIGINT_LITERAL_RE = /\b\d[\d_]*n\b/;
|
|
3948
|
+
const NON_DECIMAL_NUMERIC_RAW_RE = /^0[bxo]/i;
|
|
3949
|
+
function hasExtendedNumericLiteralSyntax(exp) {
|
|
3950
|
+
return DIGIT_NUMERIC_SEPARATOR_RE.test(exp) || NON_DECIMAL_NUMERIC_LITERAL_RE.test(exp) || DECIMAL_BIGINT_LITERAL_RE.test(exp);
|
|
3951
|
+
}
|
|
3952
|
+
function serializeBigIntForWxml(value) {
|
|
3953
|
+
const asNumber = Number(value);
|
|
3954
|
+
if (!Number.isSafeInteger(asNumber)) return t.stringLiteral(value.toString());
|
|
3955
|
+
return asNumber < 0 ? t.unaryExpression("-", t.numericLiteral(Math.abs(asNumber))) : t.numericLiteral(asNumber);
|
|
3956
|
+
}
|
|
3957
|
+
function normalizeTopLevelBigInt(expression) {
|
|
3958
|
+
if (t.isBigIntLiteral(expression)) return serializeBigIntForWxml(BigInt(expression.value));
|
|
3959
|
+
if (t.isUnaryExpression(expression, { operator: "-" }) && t.isBigIntLiteral(expression.argument)) return serializeBigIntForWxml(-BigInt(expression.argument.value));
|
|
3960
|
+
return expression;
|
|
3961
|
+
}
|
|
3962
|
+
function canonicalizeNumericLiteral(node) {
|
|
3963
|
+
const raw = node.extra?.raw;
|
|
3964
|
+
if (typeof raw !== "string" || !raw.includes("_") && !NON_DECIMAL_NUMERIC_RAW_RE.test(raw)) return;
|
|
3965
|
+
delete node.extra?.raw;
|
|
3966
|
+
delete node.extra?.rawValue;
|
|
3967
|
+
}
|
|
3968
|
+
//#endregion
|
|
3931
3969
|
//#region src/plugins/vue/compiler/template/expression/wxml.ts
|
|
3932
3970
|
function templateLiteralToConcat(node) {
|
|
3933
3971
|
const segments = [];
|
|
@@ -4027,7 +4065,8 @@ function normalizeWxmlExpression(exp) {
|
|
|
4027
4065
|
const hasTypeScriptSyntax = /\s(?:as|satisfies)\s/.test(exp) || /[\w$)\]]!(?=[.[\s,);:?]|$)/.test(exp) || /^\s*<[^>]+>/.test(exp);
|
|
4028
4066
|
const needsVueSlotsRewrite = exp.includes("$slots");
|
|
4029
4067
|
const needsThisRewrite = /\bthis\./.test(exp);
|
|
4030
|
-
|
|
4068
|
+
const needsNumericLiteralRewrite = hasExtendedNumericLiteralSyntax(exp);
|
|
4069
|
+
if (!exp.includes("`") && !exp.includes("??") && !exp.includes("?.") && !hasTypeScriptSyntax && !needsVueSlotsRewrite && !needsThisRewrite && !needsNumericLiteralRewrite) return exp;
|
|
4031
4070
|
try {
|
|
4032
4071
|
const ast = parse$3(`(${exp})`, {
|
|
4033
4072
|
sourceType: "module",
|
|
@@ -4036,6 +4075,8 @@ function normalizeWxmlExpression(exp) {
|
|
|
4036
4075
|
const stmt = ast.program.body[0];
|
|
4037
4076
|
if (!stmt || !("expression" in stmt)) return exp;
|
|
4038
4077
|
if (needsVueSlotsRewrite) rewriteVueSlotsExpression(ast);
|
|
4078
|
+
const expressionStatement = stmt;
|
|
4079
|
+
expressionStatement.expression = normalizeTopLevelBigInt(expressionStatement.expression);
|
|
4039
4080
|
traverse(ast, {
|
|
4040
4081
|
MemberExpression: { exit(path) {
|
|
4041
4082
|
const node = path.node;
|
|
@@ -4052,6 +4093,9 @@ function normalizeWxmlExpression(exp) {
|
|
|
4052
4093
|
TSTypeAssertion(path) {
|
|
4053
4094
|
path.replaceWith(path.node.expression);
|
|
4054
4095
|
},
|
|
4096
|
+
NumericLiteral(path) {
|
|
4097
|
+
canonicalizeNumericLiteral(path.node);
|
|
4098
|
+
},
|
|
4055
4099
|
OptionalMemberExpression: { exit(path) {
|
|
4056
4100
|
if (isOptionalChainNode(path.parentPath.node)) return;
|
|
4057
4101
|
path.replaceWith(lowerOptionalChain(path.node));
|
|
@@ -6609,106 +6653,69 @@ function transformNestedWxssVars(source) {
|
|
|
6609
6653
|
}
|
|
6610
6654
|
//#endregion
|
|
6611
6655
|
//#region src/plugins/vue/compiler/style.ts
|
|
6612
|
-
|
|
6613
|
-
|
|
6656
|
+
function normalizeStyleError(error) {
|
|
6657
|
+
return error instanceof Error ? error.message : String(error);
|
|
6658
|
+
}
|
|
6659
|
+
function hasSlottedScopeSelector(source, slottedScopeId) {
|
|
6660
|
+
let found = false;
|
|
6661
|
+
const processor = selectorParser((selectors) => {
|
|
6662
|
+
selectors.walkAttributes((attribute) => {
|
|
6663
|
+
if (attribute.attribute === slottedScopeId) found = true;
|
|
6664
|
+
});
|
|
6665
|
+
});
|
|
6666
|
+
postcss.parse(source).walkRules((rule) => {
|
|
6667
|
+
if (!found) processor.processSync(rule.selector);
|
|
6668
|
+
});
|
|
6669
|
+
return found;
|
|
6670
|
+
}
|
|
6671
|
+
/**
|
|
6672
|
+
* compiler-sfc 已在 scoped 插件中处理 deep 选择器,此函数保留为兼容入口。
|
|
6673
|
+
*/
|
|
6614
6674
|
function transformVueDeepSelectors(source) {
|
|
6615
|
-
if (!source.includes(":deep") && !source.includes("::v-deep")) return source;
|
|
6616
6675
|
const root = postcss.parse(source);
|
|
6617
6676
|
const processor = selectorParser((selectors) => {
|
|
6618
6677
|
selectors.walkTags((tag) => {
|
|
6619
|
-
const
|
|
6620
|
-
if (
|
|
6678
|
+
const mapped = DEFAULT_HTML_TO_WXML_TAG_MAP[tag.value.toLowerCase()];
|
|
6679
|
+
if (mapped && mapped !== tag.value.toLowerCase()) tag.replaceWith(selectorParser.className({ value: tag.value.toLowerCase() }));
|
|
6621
6680
|
});
|
|
6622
6681
|
selectors.walkPseudos((pseudo) => {
|
|
6623
|
-
if (
|
|
6682
|
+
if (![":deep", "::v-deep"].includes(pseudo.value)) return;
|
|
6624
6683
|
const replacement = pseudo.nodes?.[0]?.nodes.map((node) => node.clone()) ?? [];
|
|
6625
|
-
|
|
6626
|
-
else {
|
|
6627
|
-
const previous = pseudo.prev();
|
|
6628
|
-
const next = pseudo.next();
|
|
6629
|
-
if (next?.type === "combinator" && (!previous || previous.type === "combinator")) next.remove();
|
|
6630
|
-
pseudo.remove();
|
|
6631
|
-
}
|
|
6684
|
+
replacement.length ? pseudo.replaceWith(...replacement) : pseudo.remove();
|
|
6632
6685
|
});
|
|
6633
6686
|
});
|
|
6634
6687
|
root.walkRules((rule) => {
|
|
6635
|
-
|
|
6688
|
+
rule.selector = processor.processSync(rule.selector).replace(/\s{2,}/g, " ").trim();
|
|
6636
6689
|
});
|
|
6637
6690
|
return root.toString();
|
|
6638
6691
|
}
|
|
6639
6692
|
/**
|
|
6640
|
-
*
|
|
6641
|
-
* 为每个选择器添加特定的 scoped 属性
|
|
6693
|
+
* 将 Vue SFC style 块编译为可交给 Vite CSS 管线的内容。
|
|
6642
6694
|
*/
|
|
6643
|
-
function
|
|
6644
|
-
const
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6695
|
+
async function compileVueStyleToWxss(styleBlock, options) {
|
|
6696
|
+
const filename = options.filename ?? `style-${options.id}.${styleBlock.lang || "css"}`;
|
|
6697
|
+
const moduleName = typeof styleBlock.module === "string" ? styleBlock.module : typeof options.modules === "string" ? options.modules : "$style";
|
|
6698
|
+
const modules = Boolean(options.modules || styleBlock.module);
|
|
6699
|
+
const result = await compileStyleAsync({
|
|
6700
|
+
filename,
|
|
6701
|
+
id: `data-v-${options.id}`,
|
|
6702
|
+
source: styleBlock.content,
|
|
6703
|
+
scoped: options.transformScoped !== false && Boolean(options.scoped || styleBlock.scoped),
|
|
6704
|
+
modules,
|
|
6705
|
+
modulesOptions: modules ? { generateScopedName: (name) => `${name}_${options.id}` } : void 0,
|
|
6706
|
+
preprocessLang: styleBlock.lang,
|
|
6707
|
+
preprocessOptions: options.preprocessOptions
|
|
6653
6708
|
});
|
|
6654
|
-
}
|
|
6655
|
-
/**
|
|
6656
|
-
* 样式转换:CSS → WXSS
|
|
6657
|
-
* 处理小程序不支持的 CSS 特性
|
|
6658
|
-
*/
|
|
6659
|
-
/**
|
|
6660
|
-
* 生成简单的 hash
|
|
6661
|
-
*/
|
|
6662
|
-
function generateHash(str) {
|
|
6663
|
-
let hash = 0;
|
|
6664
|
-
for (let i = 0; i < str.length; i++) {
|
|
6665
|
-
const char = str.charCodeAt(i);
|
|
6666
|
-
hash = (hash << 5) - hash + char;
|
|
6667
|
-
hash = hash & hash;
|
|
6668
|
-
}
|
|
6669
|
-
return Math.abs(hash).toString(36) + str.length.toString(36);
|
|
6670
|
-
}
|
|
6671
|
-
/**
|
|
6672
|
-
* 转换 CSS Modules
|
|
6673
|
-
*/
|
|
6674
|
-
function transformCssModules(source, id) {
|
|
6675
|
-
const classes = {};
|
|
6676
|
-
const hash = generateHash(id);
|
|
6677
|
-
const classRegex = new RegExp(CSS_CLASS_RE.source, CSS_CLASS_RE.flags);
|
|
6678
|
-
const foundClasses = [];
|
|
6679
|
-
let result = classRegex.exec(source);
|
|
6680
|
-
while (result !== null) {
|
|
6681
|
-
foundClasses.push(result[1]);
|
|
6682
|
-
result = classRegex.exec(source);
|
|
6683
|
-
}
|
|
6684
|
-
for (const className of foundClasses) classes[className] = `${className}_${hash}`;
|
|
6685
|
-
let code = source;
|
|
6686
|
-
for (const [original, scoped] of Object.entries(classes)) {
|
|
6687
|
-
const regex = new RegExp(`\\.${original}\\b`, "g");
|
|
6688
|
-
code = code.replace(regex, `.${scoped}`);
|
|
6689
|
-
}
|
|
6709
|
+
if (result.errors.length) throw new Error(`SFC 样式编译失败(${filename}):${result.errors.map(normalizeStyleError).join("; ")}`);
|
|
6690
6710
|
return {
|
|
6691
|
-
code,
|
|
6692
|
-
|
|
6711
|
+
code: options.preserveDeepSelectors ? result.code : transformVueDeepSelectors(result.code),
|
|
6712
|
+
map: result.map ? JSON.stringify(result.map) : void 0,
|
|
6713
|
+
scopedId: options.scoped || styleBlock.scoped ? `data-v-${options.id}` : void 0,
|
|
6714
|
+
usesSlotted: hasSlottedScopeSelector(result.code, `data-v-${options.id}-s`),
|
|
6715
|
+
modules: result.modules ? { [moduleName]: result.modules } : void 0,
|
|
6716
|
+
dependencies: [...result.dependencies]
|
|
6693
6717
|
};
|
|
6694
6718
|
}
|
|
6695
|
-
/**
|
|
6696
|
-
* 将 Vue SFC 的 style 块转换为 WXSS
|
|
6697
|
-
*/
|
|
6698
|
-
function compileVueStyleToWxss(styleBlock, options) {
|
|
6699
|
-
const { id, scoped, modules, preserveDeepSelectors, transformScoped = true } = options;
|
|
6700
|
-
let code = styleBlock.content;
|
|
6701
|
-
if (transformScoped && (scoped || styleBlock.scoped)) code = transformScopedCss(code, id);
|
|
6702
|
-
if (modules || styleBlock.module) {
|
|
6703
|
-
const moduleName = typeof styleBlock.module === "string" ? styleBlock.module : "$style";
|
|
6704
|
-
const moduleResult = transformCssModules(code, id);
|
|
6705
|
-
return {
|
|
6706
|
-
code: preserveDeepSelectors ? moduleResult.code : transformVueDeepSelectors(moduleResult.code),
|
|
6707
|
-
modules: { [moduleName]: moduleResult.classes }
|
|
6708
|
-
};
|
|
6709
|
-
}
|
|
6710
|
-
return { code: preserveDeepSelectors ? code : transformVueDeepSelectors(code) };
|
|
6711
|
-
}
|
|
6712
6719
|
//#endregion
|
|
6713
6720
|
//#region src/plugins/vue/compiler/template/classStyleRuntime.ts
|
|
6714
6721
|
/**
|
|
@@ -7944,7 +7951,7 @@ function buildForIndexAccess$1(context) {
|
|
|
7944
7951
|
/**
|
|
7945
7952
|
* 检测表达式是否包含小程序模板不稳定的调用语义。
|
|
7946
7953
|
*/
|
|
7947
|
-
function shouldFallbackToRuntimeBinding(exp) {
|
|
7954
|
+
function shouldFallbackToRuntimeBinding(exp, templateSafeCallNames = /* @__PURE__ */ new Set()) {
|
|
7948
7955
|
const trimmed = exp.trim();
|
|
7949
7956
|
if (!trimmed) return false;
|
|
7950
7957
|
const parsed = parseBabelExpressionFile(normalizeWxmlExpression(trimmed));
|
|
@@ -7952,6 +7959,7 @@ function shouldFallbackToRuntimeBinding(exp) {
|
|
|
7952
7959
|
let shouldFallback = false;
|
|
7953
7960
|
traverse(parsed.ast, {
|
|
7954
7961
|
CallExpression(path) {
|
|
7962
|
+
if (path.node.callee.type === "Identifier" && templateSafeCallNames.has(path.node.callee.name)) return;
|
|
7955
7963
|
shouldFallback = true;
|
|
7956
7964
|
path.stop();
|
|
7957
7965
|
},
|
|
@@ -7963,6 +7971,10 @@ function shouldFallbackToRuntimeBinding(exp) {
|
|
|
7963
7971
|
if (path.node.operator !== "typeof") return;
|
|
7964
7972
|
shouldFallback = true;
|
|
7965
7973
|
path.stop();
|
|
7974
|
+
},
|
|
7975
|
+
BigIntLiteral(path) {
|
|
7976
|
+
shouldFallback = true;
|
|
7977
|
+
path.stop();
|
|
7966
7978
|
}
|
|
7967
7979
|
});
|
|
7968
7980
|
return shouldFallback;
|
|
@@ -8291,7 +8303,7 @@ function transformBindDirective(node, context, forInfo, options) {
|
|
|
8291
8303
|
if (context.objectLiteralBindMode === "inline" || isStaticObjectLiteral(rawExpValue)) return createInlineObjectLiteralAttr(argValue, rawExpValue, context);
|
|
8292
8304
|
return createBindRuntimeAttr(argValue, rawExpValue, context);
|
|
8293
8305
|
}
|
|
8294
|
-
if (shouldFallbackToRuntimeBinding(rawExpValue)) {
|
|
8306
|
+
if (shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames)) {
|
|
8295
8307
|
const runtimeAttr = createBindRuntimeAttr(argValue, rawExpValue, context);
|
|
8296
8308
|
if (runtimeAttr) return runtimeAttr;
|
|
8297
8309
|
}
|
|
@@ -8557,6 +8569,7 @@ function collectElementAttributes(node, context, options) {
|
|
|
8557
8569
|
const resolvedTag = options?.resolvedTag ?? resolveTemplateTagName(node.tag, context);
|
|
8558
8570
|
const isComponentElement = options?.isComponent ?? !isBuiltinTag(resolvedTag);
|
|
8559
8571
|
const attrs = options?.extraAttrs ? [...options.extraAttrs] : [];
|
|
8572
|
+
if (context.scopeId) attrs.push(`${context.scopeId}=""`);
|
|
8560
8573
|
const mappedTagClass = resolveMappedHtmlTagClassName(node.tag, context, resolvedTag);
|
|
8561
8574
|
let staticClass;
|
|
8562
8575
|
let staticId;
|
|
@@ -8636,7 +8649,7 @@ function collectElementAttributes(node, context, options) {
|
|
|
8636
8649
|
}
|
|
8637
8650
|
if (prop.name === "text" && prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
8638
8651
|
const rawExp = prop.exp.content;
|
|
8639
|
-
vTextExp = (shouldFallbackToRuntimeBinding(rawExp) ? registerRuntimeBindingExpression(rawExp, context, { hint: "v-text" }) : null) ?? normalizeWxmlExpressionWithContext(rawExp, context);
|
|
8652
|
+
vTextExp = (shouldFallbackToRuntimeBinding(rawExp, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExp, context, { hint: "v-text" }) : null) ?? normalizeWxmlExpressionWithContext(rawExp, context);
|
|
8640
8653
|
continue;
|
|
8641
8654
|
}
|
|
8642
8655
|
const dir = transformDirective(prop, context, node, options?.forInfo, { isComponent: isComponentElement });
|
|
@@ -8680,7 +8693,7 @@ function collectElementAttributes(node, context, options) {
|
|
|
8680
8693
|
if (staticId) attrs.unshift(`id="${staticId}"`);
|
|
8681
8694
|
const classAttr = renderClassAttribute(staticClass, dynamicClassExp, context);
|
|
8682
8695
|
if (classAttr) attrs.unshift(classAttr);
|
|
8683
|
-
const styleAttr = renderStyleAttribute(staticStyle, dynamicStyleExp, vShowExp, context);
|
|
8696
|
+
const styleAttr = renderStyleAttribute(staticStyle, context.cssVars ? dynamicStyleExp ? `[${dynamicStyleExp}, ${WEVU_CSS_VARS_STYLE_KEY}]` : WEVU_CSS_VARS_STYLE_KEY : dynamicStyleExp, vShowExp, context);
|
|
8684
8697
|
if (styleAttr) attrs.unshift(styleAttr);
|
|
8685
8698
|
return {
|
|
8686
8699
|
attrs,
|
|
@@ -9039,6 +9052,7 @@ function renderPlainSlotOutlet(node, context, transformNode) {
|
|
|
9039
9052
|
if (hasScopeBindings) context.warnings.push("已禁用作用域插槽参数,插槽绑定将被忽略。");
|
|
9040
9053
|
const fallbackContent = node.children.map((child) => transformNode(child, context)).join("");
|
|
9041
9054
|
const slotAttrs = [];
|
|
9055
|
+
if (context.slottedScopeId) slotAttrs.push(`${context.slottedScopeId}=""`);
|
|
9042
9056
|
const nameAttr = renderSlotNameAttribute(slotNameInfo, context, "name");
|
|
9043
9057
|
if (nameAttr) slotAttrs.push(nameAttr);
|
|
9044
9058
|
const slotAttrString = slotAttrs.length ? ` ${slotAttrs.join(" ")}` : "";
|
|
@@ -9103,6 +9117,7 @@ function transformSlotElement(node, context, transformNode) {
|
|
|
9103
9117
|
let fallbackContent = "";
|
|
9104
9118
|
if (node.children.length > 0) fallbackContent = node.children.map((child) => transformNode(child, context)).join("");
|
|
9105
9119
|
const slotAttrs = [];
|
|
9120
|
+
if (context.slottedScopeId) slotAttrs.push(`${context.slottedScopeId}=""`);
|
|
9106
9121
|
const nameAttr = renderSlotNameAttribute(slotNameInfo, context, "name");
|
|
9107
9122
|
if (nameAttr) slotAttrs.push(nameAttr);
|
|
9108
9123
|
const slotAttrString = slotAttrs.length ? ` ${slotAttrs.join(" ")}` : "";
|
|
@@ -9122,6 +9137,7 @@ function transformSlotElement(node, context, transformNode) {
|
|
|
9122
9137
|
`${WEVU_SLOT_OWNER_ID_ATTR}="${renderMustache(WEVU_SLOT_OWNER_ID_PROP, context)}"`,
|
|
9123
9138
|
`${WEVU_SLOT_PROPS_ATTR}="${renderMustache(slotPropsExp, context)}"`
|
|
9124
9139
|
];
|
|
9140
|
+
if (context.slottedScopeId) scopedAttrs.push(`${context.slottedScopeId}=""`);
|
|
9125
9141
|
if (context.slotMultipleInstance) scopedAttrs.push(`${WEVU_SLOT_SCOPE_ATTR}="${renderMustache(WEVU_SLOT_SCOPE_KEY, context)}"`);
|
|
9126
9142
|
const scopedTag = `<${genericKey}${scopedAttrs.length ? ` ${scopedAttrs.join(" ")}` : ""} />`;
|
|
9127
9143
|
const nativeFallbackTag = context.forStack.length > 0 ? "" : context.platform.wrapIf(`!${WEVU_SLOT_OWNER_ID_PROP}`, slotTag, (exp) => renderMustache(exp, context));
|
|
@@ -9598,10 +9614,10 @@ function transformNormalElement(node, context, transformNode) {
|
|
|
9598
9614
|
//#region src/plugins/vue/compiler/template/elements/tag-structural.ts
|
|
9599
9615
|
const REGEX_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
|
|
9600
9616
|
function resolveConditionExpression$1(rawExpValue, context, hint) {
|
|
9601
|
-
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9617
|
+
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9602
9618
|
}
|
|
9603
9619
|
function resolveListExpression(rawExpValue, context, hint) {
|
|
9604
|
-
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9620
|
+
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9605
9621
|
}
|
|
9606
9622
|
function transformIfElement(node, context, transformNode) {
|
|
9607
9623
|
const renderTemplateMustache = (exp) => renderMustache(exp, context);
|
|
@@ -9705,7 +9721,7 @@ function transformForElement(node, context, transformNode) {
|
|
|
9705
9721
|
const TEMPLATE_OPEN_RE = /<template/g;
|
|
9706
9722
|
const TEMPLATE_CLOSE_RE = /<\/template>/g;
|
|
9707
9723
|
function resolveConditionExpression(rawExpValue, context, hint) {
|
|
9708
|
-
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9724
|
+
return (context.rewriteScopedSlot || shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context);
|
|
9709
9725
|
}
|
|
9710
9726
|
function transformTransitionElement(node, context, transformNode) {
|
|
9711
9727
|
context.warnings.push("<transition> 组件:过渡效果需要动画库或运行时支持,仅渲染子节点。");
|
|
@@ -9806,7 +9822,7 @@ function transformInterpolation(node, context) {
|
|
|
9806
9822
|
const { content } = node;
|
|
9807
9823
|
if (content.type === NodeTypes.SIMPLE_EXPRESSION) {
|
|
9808
9824
|
const rawExpValue = content.content;
|
|
9809
|
-
return renderMustache((shouldFallbackToRuntimeBinding(rawExpValue) ? registerRuntimeBindingExpression(rawExpValue, context, { hint: "插值表达式" }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context), context);
|
|
9825
|
+
return renderMustache((shouldFallbackToRuntimeBinding(rawExpValue, context.templateSafeCallNames) ? registerRuntimeBindingExpression(rawExpValue, context, { hint: "插值表达式" }) : null) ?? normalizeWxmlExpressionWithContext(rawExpValue, context), context);
|
|
9810
9826
|
}
|
|
9811
9827
|
/* istanbul ignore next */
|
|
9812
9828
|
return renderMustache("", context);
|
|
@@ -9929,8 +9945,12 @@ function compileVueTemplateToWxml(template, filename, options) {
|
|
|
9929
9945
|
inlineExpressionSeed: 0,
|
|
9930
9946
|
functionPropPaths: /* @__PURE__ */ new Set(),
|
|
9931
9947
|
functionPropNames: Array.from(options?.functionPropNames ?? []),
|
|
9948
|
+
templateSafeCallNames: new Set(options?.templateSafeCallNames ?? []),
|
|
9932
9949
|
wevuComponentTags: options?.wevuComponentTags ? new Set(options.wevuComponentTags) : void 0,
|
|
9933
|
-
miniProgramComponentTags: options?.miniProgramComponentTags ? new Set(options.miniProgramComponentTags) : void 0
|
|
9950
|
+
miniProgramComponentTags: options?.miniProgramComponentTags ? new Set(options.miniProgramComponentTags) : void 0,
|
|
9951
|
+
scopeId: options?.scopeId,
|
|
9952
|
+
slottedScopeId: options?.slottedScopeId,
|
|
9953
|
+
cssVars: options?.cssVars
|
|
9934
9954
|
};
|
|
9935
9955
|
let wxml = ast.children.map((child) => transformNode(child, context)).join("");
|
|
9936
9956
|
if (context.classStyleWxs) wxml = `${buildClassStyleWxsTag(context.classStyleWxsExtension || "wxs", context.classStyleWxsSrc)}\n${wxml}`;
|
|
@@ -9961,6 +9981,25 @@ function compileVueTemplateToWxml(template, filename, options) {
|
|
|
9961
9981
|
}
|
|
9962
9982
|
}
|
|
9963
9983
|
//#endregion
|
|
9984
|
+
//#region src/plugins/vue/transform/scopedId.ts
|
|
9985
|
+
const SOURCE_ROOT_RE = /(?:^|\/)src\/(.+)$/;
|
|
9986
|
+
function normalizeScopedIdInput(filename) {
|
|
9987
|
+
const normalized = filename.replace(/\\/g, "/");
|
|
9988
|
+
return normalized.match(SOURCE_ROOT_RE)?.[1] ?? normalized.replace(/^.*?\/(pages|components|layouts)\//, "$1/");
|
|
9989
|
+
}
|
|
9990
|
+
/**
|
|
9991
|
+
* 根据项目内相对路径生成跨机器稳定的 scoped ID。
|
|
9992
|
+
*/
|
|
9993
|
+
function generateScopedId(filename) {
|
|
9994
|
+
const input = normalizeScopedIdInput(filename);
|
|
9995
|
+
let hash = 2166136261;
|
|
9996
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
9997
|
+
hash ^= input.charCodeAt(index);
|
|
9998
|
+
hash = Math.imul(hash, 16777619);
|
|
9999
|
+
}
|
|
10000
|
+
return (hash >>> 0).toString(36);
|
|
10001
|
+
}
|
|
10002
|
+
//#endregion
|
|
9964
10003
|
//#region src/ast/native.ts
|
|
9965
10004
|
const require = createRequire(import.meta.url);
|
|
9966
10005
|
let binding;
|
|
@@ -10568,6 +10607,10 @@ const OBJECT_TO_STRING = Object.prototype.toString;
|
|
|
10568
10607
|
function isIdentifierLikeKey(key) {
|
|
10569
10608
|
return IDENTIFIER_LIKE_KEY_RE.test(key);
|
|
10570
10609
|
}
|
|
10610
|
+
function resolveRuntimeMarkerIdentifier(value, scopeValues) {
|
|
10611
|
+
if (value[WEAPP_I18N_RUNTIME_MARKER] !== true) return;
|
|
10612
|
+
return Object.entries(scopeValues).find(([name, scopeValue]) => isIdentifierLikeKey(name) && scopeValue === value)?.[0];
|
|
10613
|
+
}
|
|
10571
10614
|
function getObjectTag(value) {
|
|
10572
10615
|
return OBJECT_TO_STRING.call(value);
|
|
10573
10616
|
}
|
|
@@ -10665,6 +10708,8 @@ function serializeStaticValueToExpression(value, seen = /* @__PURE__ */ new Weak
|
|
|
10665
10708
|
if (getObjectTag(value) === "[object RegExp]") return value.toString();
|
|
10666
10709
|
if (Array.isArray(value)) return `[${value.map((item) => serializeStaticValueToExpression(item, seen, scopeValues)).join(", ")}]`;
|
|
10667
10710
|
if (value && typeof value === "object") {
|
|
10711
|
+
const runtimeIdentifier = resolveRuntimeMarkerIdentifier(value, scopeValues);
|
|
10712
|
+
if (runtimeIdentifier) return runtimeIdentifier;
|
|
10668
10713
|
if (seen.has(value)) throw new Error("defineOptions 的参数中不支持循环引用。");
|
|
10669
10714
|
seen.add(value);
|
|
10670
10715
|
const proto = Object.getPrototypeOf(value);
|
|
@@ -11311,7 +11356,7 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
|
|
|
11311
11356
|
let propsDerivedKeys;
|
|
11312
11357
|
if (descriptor.script || descriptor.scriptSetup) {
|
|
11313
11358
|
const scriptCompiled = precompiledScript ?? compileScript(descriptorForCompile, {
|
|
11314
|
-
id: filename,
|
|
11359
|
+
id: generateScopedId(filename),
|
|
11315
11360
|
isProd: false
|
|
11316
11361
|
});
|
|
11317
11362
|
warnReservedScriptSetupProps(descriptorForCompile.scriptSetup?.content, options?.warn, {
|
|
@@ -11356,6 +11401,7 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
|
|
|
11356
11401
|
functionPropPaths: templateCompiled?.functionPropPaths,
|
|
11357
11402
|
propsAliases,
|
|
11358
11403
|
propsDerivedKeys,
|
|
11404
|
+
cssModules: precomputedScriptPhaseInfo?.cssModules,
|
|
11359
11405
|
relaxStructuredTypeOnlyProps,
|
|
11360
11406
|
scopedSlotHostProperties: Boolean(templateCompiled?.componentGenerics && Object.keys(templateCompiled.componentGenerics).length > 0)
|
|
11361
11407
|
});
|
|
@@ -11376,42 +11422,29 @@ async function compileScriptPhase(descriptor, descriptorForCompile, filename, op
|
|
|
11376
11422
|
};
|
|
11377
11423
|
}
|
|
11378
11424
|
//#endregion
|
|
11379
|
-
//#region src/plugins/vue/transform/scopedId.ts
|
|
11380
|
-
/**
|
|
11381
|
-
* 生成 scoped ID
|
|
11382
|
-
*/
|
|
11383
|
-
function generateScopedId(filename) {
|
|
11384
|
-
const hash = filename.split("").reduce((acc, char) => {
|
|
11385
|
-
return (acc << 5) - acc + char.charCodeAt(0);
|
|
11386
|
-
}, 0);
|
|
11387
|
-
return Math.abs(hash).toString(36);
|
|
11388
|
-
}
|
|
11389
|
-
//#endregion
|
|
11390
11425
|
//#region src/plugins/vue/transform/compileVueFile/style.ts
|
|
11391
|
-
function compileStylePhase(descriptor, filename, result, options) {
|
|
11392
|
-
if (descriptor.styles.length === 0) return;
|
|
11426
|
+
async function compileStylePhase(descriptor, filename, result, options) {
|
|
11427
|
+
if (descriptor.styles.length === 0) return { usesSlotted: false };
|
|
11393
11428
|
const scopedId = generateScopedId(filename);
|
|
11394
|
-
const compiledStyles = descriptor.styles.map((styleBlock) => {
|
|
11395
|
-
return compileVueStyleToWxss(styleBlock, {
|
|
11429
|
+
const compiledStyles = await Promise.all(descriptor.styles.map(async (styleBlock) => {
|
|
11430
|
+
return await compileVueStyleToWxss(styleBlock, {
|
|
11396
11431
|
id: scopedId,
|
|
11432
|
+
filename,
|
|
11397
11433
|
scoped: styleBlock.scoped,
|
|
11398
11434
|
modules: styleBlock.module,
|
|
11435
|
+
preprocessOptions: options?.preprocessOptions?.[styleBlock.lang || "css"],
|
|
11399
11436
|
preserveDeepSelectors: options?.preserveDeepSelectors,
|
|
11400
11437
|
transformScoped: options?.transformScoped
|
|
11401
11438
|
});
|
|
11402
|
-
});
|
|
11439
|
+
}));
|
|
11403
11440
|
result.style = compiledStyles.map((s) => s.code.trim()).filter(Boolean).join("\n\n");
|
|
11404
|
-
if (!compiledStyles.some((s) => s.modules)) return;
|
|
11441
|
+
if (!compiledStyles.some((s) => s.modules)) return { usesSlotted: compiledStyles.some((style) => style.usesSlotted) };
|
|
11405
11442
|
const modulesMap = {};
|
|
11406
11443
|
compiledStyles.forEach((compiled) => {
|
|
11407
11444
|
if (compiled.modules) Object.assign(modulesMap, compiled.modules);
|
|
11408
11445
|
});
|
|
11409
11446
|
result.cssModules = modulesMap;
|
|
11410
|
-
|
|
11411
|
-
// 模块化样式(CSS Modules)
|
|
11412
|
-
const __cssModules = ${JSON.stringify(modulesMap, null, 2)}
|
|
11413
|
-
${result.script}
|
|
11414
|
-
`;
|
|
11447
|
+
return { usesSlotted: compiledStyles.some((style) => style.usesSlotted) };
|
|
11415
11448
|
}
|
|
11416
11449
|
//#endregion
|
|
11417
11450
|
//#region src/plugins/vue/transform/compileVueFile/template.ts
|
|
@@ -11471,6 +11504,7 @@ async function refreshVueFileJsonConfig(source, filename, cachedResult, options)
|
|
|
11471
11504
|
*/
|
|
11472
11505
|
async function compileVueFile(source, filename, options) {
|
|
11473
11506
|
const parsed = await parseVueFile(source, filename, options);
|
|
11507
|
+
const sfcId = generateScopedId(filename);
|
|
11474
11508
|
const result = { meta: {
|
|
11475
11509
|
...parsed.meta,
|
|
11476
11510
|
styleBlocks: parsed.descriptor.styles
|
|
@@ -11486,24 +11520,32 @@ async function compileVueFile(source, filename, options) {
|
|
|
11486
11520
|
autoImportTags
|
|
11487
11521
|
});
|
|
11488
11522
|
const scriptCompiled = parsed.descriptor.script || parsed.descriptor.scriptSetup ? compileScript(parsed.descriptorForCompile, {
|
|
11489
|
-
id:
|
|
11523
|
+
id: sfcId,
|
|
11490
11524
|
isProd: false
|
|
11491
11525
|
}) : void 0;
|
|
11492
11526
|
const propsAliases = scriptCompiled ? resolveScriptSetupPropsAliases(scriptCompiled.bindings) : void 0;
|
|
11493
11527
|
const propsDerivedKeys = scriptCompiled ? resolveEffectivePropsDerivedKeys(scriptCompiled.bindings, scriptCompiled.content) : void 0;
|
|
11528
|
+
const styleCompiled = await compileStylePhase(parsed.descriptor, filename, result, options?.style);
|
|
11529
|
+
const scopedId = parsed.descriptor.styles.some((style) => style.scoped) ? `data-v-${sfcId}` : void 0;
|
|
11494
11530
|
const baseTemplateOptions = parsed.isAppFile ? {
|
|
11495
11531
|
...options?.template,
|
|
11496
11532
|
isPage: options?.isPage,
|
|
11497
11533
|
propsAliases,
|
|
11498
11534
|
propsDerivedKeys,
|
|
11499
11535
|
scriptSetupBindings: scriptCompiled?.bindings,
|
|
11500
|
-
scopedSlotsRequireProps: true
|
|
11536
|
+
scopedSlotsRequireProps: true,
|
|
11537
|
+
scopeId: scopedId,
|
|
11538
|
+
slottedScopeId: scopedId && styleCompiled.usesSlotted ? `${scopedId}-s` : void 0,
|
|
11539
|
+
cssVars: parsed.descriptor.cssVars.length > 0
|
|
11501
11540
|
} : {
|
|
11502
11541
|
...options?.template,
|
|
11503
11542
|
isPage: options?.isPage,
|
|
11504
11543
|
propsAliases,
|
|
11505
11544
|
propsDerivedKeys,
|
|
11506
|
-
scriptSetupBindings: scriptCompiled?.bindings
|
|
11545
|
+
scriptSetupBindings: scriptCompiled?.bindings,
|
|
11546
|
+
scopeId: scopedId,
|
|
11547
|
+
slottedScopeId: scopedId && styleCompiled.usesSlotted ? `${scopedId}-s` : void 0,
|
|
11548
|
+
cssVars: parsed.descriptor.cssVars.length > 0
|
|
11507
11549
|
};
|
|
11508
11550
|
const templateOptions = componentSourceInfo.wevuComponentTags.size ? {
|
|
11509
11551
|
...baseTemplateOptions,
|
|
@@ -11519,12 +11561,12 @@ async function compileVueFile(source, filename, options) {
|
|
|
11519
11561
|
const templateCompiled = compileTemplatePhase(parsed.descriptor, filename, templateOptions, result);
|
|
11520
11562
|
const scriptPhase = await compileScriptPhase(parsed.descriptor, parsed.descriptorForCompile, filename, options, autoUsingComponents, templateCompiled, parsed.isAppFile, componentSourceInfo, scriptCompiled, {
|
|
11521
11563
|
propsAliases,
|
|
11522
|
-
propsDerivedKeys
|
|
11564
|
+
propsDerivedKeys,
|
|
11565
|
+
cssModules: result.cssModules
|
|
11523
11566
|
});
|
|
11524
11567
|
result.script = scriptPhase.script;
|
|
11525
11568
|
result.scriptMap = scriptPhase.scriptMap;
|
|
11526
11569
|
if (scriptPhase.template) result.template = scriptPhase.template;
|
|
11527
|
-
compileStylePhase(parsed.descriptor, filename, result, options?.style);
|
|
11528
11570
|
await compileConfigPhase({
|
|
11529
11571
|
descriptor: parsed.descriptor,
|
|
11530
11572
|
filename,
|
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.22.0",
|
|
5
5
|
"description": "wevu 编译器基础包,面向小程序模板的编译与转换",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"postcss": "^8.5.26",
|
|
54
54
|
"postcss-selector-parser": "^7.1.5",
|
|
55
55
|
"vue": "^3.5.41",
|
|
56
|
-
"@weapp-core/constants": "0.
|
|
56
|
+
"@weapp-core/constants": "0.2.0",
|
|
57
|
+
"@weapp-vite/ast": "6.22.0",
|
|
57
58
|
"@weapp-core/shared": "3.1.1",
|
|
58
|
-
"rolldown-require": "2.0.26"
|
|
59
|
-
"@weapp-vite/ast": "6.21.0"
|
|
59
|
+
"rolldown-require": "2.0.26"
|
|
60
60
|
},
|
|
61
61
|
"publishConfig": {
|
|
62
62
|
"access": "public",
|