@dimina/compiler 1.0.17 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/bin/index.cjs +10 -8
- package/dist/bin/index.js +6 -4
- package/dist/{compatibility-DnN63SVV.cjs → compatibility-CzIJUgPs.cjs} +94 -4
- package/dist/{compatibility-DbP7rQJN.js → compatibility-DdxfVhcK.js} +89 -5
- package/dist/core/logic-compiler.cjs +16 -18
- package/dist/core/logic-compiler.js +13 -16
- package/dist/core/style-compiler.cjs +61 -53
- package/dist/core/style-compiler.js +52 -45
- package/dist/core/view-compiler.cjs +202 -88
- package/dist/core/view-compiler.js +196 -84
- package/dist/{env-BWsUjuZE.cjs → env-B4U3zZUm.cjs} +182 -63
- package/dist/{env-iShlMOS1.js → env-OH3--qg8.js} +159 -26
- package/dist/index.cjs +113 -23
- package/dist/index.js +108 -19
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/package.json +8 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as checkTemplateCompatibility } from "../compatibility-
|
|
1
|
+
import { C as tagWhiteList, T as toMiniProgramModuleId, a as getComponent, b as getAbsolutePath, d as getTargetPath, f as getTemplateExts, g as resetStoreInfo, h as getWorkPath, m as getViewScriptTags, n as getAppId, o as getContentByPath, p as getViewScriptExts, w as transformRpx, y as collectAssets } from "../env-OH3--qg8.js";
|
|
2
|
+
import { r as takeCompatibilityWarnings, t as checkTemplateCompatibility } from "../compatibility-DdxfVhcK.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { isMainThread, parentPort } from "node:worker_threads";
|
|
5
5
|
import fs from "node:fs";
|
|
@@ -253,7 +253,10 @@ if (!isMainThread) parentPort.on("message", async ({ pages, storeInfo }) => {
|
|
|
253
253
|
compileResCache.clear();
|
|
254
254
|
wxsModuleRegistry.clear();
|
|
255
255
|
wxsFilePathMap.clear();
|
|
256
|
-
parentPort.postMessage({
|
|
256
|
+
parentPort.postMessage({
|
|
257
|
+
success: true,
|
|
258
|
+
compatibilityWarnings: takeCompatibilityWarnings()
|
|
259
|
+
});
|
|
257
260
|
} catch (error) {
|
|
258
261
|
compileResCache.clear();
|
|
259
262
|
wxsModuleRegistry.clear();
|
|
@@ -275,17 +278,26 @@ async function compileML(pages, root, progress) {
|
|
|
275
278
|
initWxsFilePathMap(getWorkPath());
|
|
276
279
|
for (const page of pages) {
|
|
277
280
|
const scriptRes = /* @__PURE__ */ new Map();
|
|
278
|
-
buildCompileView(page, false, scriptRes,
|
|
281
|
+
buildCompileView(page, false, scriptRes, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
|
|
279
282
|
let mergeRender = "";
|
|
280
283
|
for (const [key, value] of scriptRes.entries()) {
|
|
281
|
-
const
|
|
284
|
+
const amdFormat = `modDefine('${key}', function(require, module, exports) {
|
|
282
285
|
${value}
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
});`;
|
|
287
|
+
try {
|
|
288
|
+
const { code: minifiedCode } = await transform(amdFormat, {
|
|
289
|
+
minify: true,
|
|
290
|
+
target: ["es2020"],
|
|
291
|
+
platform: "browser"
|
|
292
|
+
});
|
|
293
|
+
mergeRender += minifiedCode;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
const location = error.errors?.[0]?.location;
|
|
296
|
+
const sourceLines = amdFormat.split("\n");
|
|
297
|
+
const sourceHint = location?.line ? sourceLines.slice(Math.max(0, location.line - 3), location.line + 2).map((line, index) => `${Math.max(1, location.line - 2) + index}: ${line.trim()}`).join("\n") : "";
|
|
298
|
+
error.message = `视图模块 ${key} 转换失败: ${error.message}${sourceHint ? `\n${sourceHint}` : ""}`;
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
289
301
|
}
|
|
290
302
|
scriptRes.clear();
|
|
291
303
|
const filename = `${page.path.replace(/\//g, "_")}`;
|
|
@@ -336,6 +348,17 @@ function scanWxsFiles(dir, workPath) {
|
|
|
336
348
|
function registerWxsModule(modulePath) {
|
|
337
349
|
wxsModuleRegistry.add(modulePath);
|
|
338
350
|
}
|
|
351
|
+
function getTemplateCompilerOptions(scopeId) {
|
|
352
|
+
return {
|
|
353
|
+
prefixIdentifiers: true,
|
|
354
|
+
hoistStatic: false,
|
|
355
|
+
cacheHandlers: true,
|
|
356
|
+
scopeId,
|
|
357
|
+
mode: "function",
|
|
358
|
+
inline: true,
|
|
359
|
+
isCustomElement: (tag) => !tag.startsWith("dd-")
|
|
360
|
+
};
|
|
361
|
+
}
|
|
339
362
|
/**
|
|
340
363
|
* 检查是否为已注册的 wxs 模块
|
|
341
364
|
* @param {string} modulePath - 模块路径
|
|
@@ -344,17 +367,10 @@ function registerWxsModule(modulePath) {
|
|
|
344
367
|
function isRegisteredWxsModule(modulePath) {
|
|
345
368
|
return wxsModuleRegistry.has(modulePath);
|
|
346
369
|
}
|
|
347
|
-
function buildCompileView(module, isComponent = false, scriptRes,
|
|
370
|
+
function buildCompileView(module, isComponent = false, scriptRes, activePaths = /* @__PURE__ */ new Set(), inheritedTemplatePaths = /* @__PURE__ */ new Set()) {
|
|
348
371
|
const currentPath = module.path;
|
|
349
|
-
if (
|
|
350
|
-
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
if (depthChain.length > 20) {
|
|
354
|
-
console.warn("[view]", `检测到深度依赖: ${[...depthChain, currentPath].join(" -> ")}`);
|
|
355
|
-
return;
|
|
356
|
-
}
|
|
357
|
-
depthChain = [...depthChain, currentPath];
|
|
372
|
+
if (activePaths.has(currentPath)) return;
|
|
373
|
+
activePaths.add(currentPath);
|
|
358
374
|
const allScriptModules = [];
|
|
359
375
|
const currentInstruction = compileModule(module, isComponent, scriptRes, { skipTemplatePaths: isComponent ? inheritedTemplatePaths : /* @__PURE__ */ new Set() });
|
|
360
376
|
if (currentInstruction && currentInstruction.scriptModule) allScriptModules.push(...currentInstruction.scriptModule);
|
|
@@ -363,11 +379,8 @@ function buildCompileView(module, isComponent = false, scriptRes, depthChain = [
|
|
|
363
379
|
if (module.usingComponents) for (const componentInfo of Object.values(module.usingComponents)) {
|
|
364
380
|
const componentModule = getComponent(componentInfo);
|
|
365
381
|
if (!componentModule) continue;
|
|
366
|
-
if (componentModule.path === module.path)
|
|
367
|
-
|
|
368
|
-
continue;
|
|
369
|
-
}
|
|
370
|
-
const componentInstruction = buildCompileView(componentModule, true, scriptRes, depthChain, childInheritedTemplatePaths);
|
|
382
|
+
if (componentModule.path === module.path) continue;
|
|
383
|
+
const componentInstruction = buildCompileView(componentModule, true, scriptRes, activePaths, childInheritedTemplatePaths);
|
|
371
384
|
if (componentInstruction && componentInstruction.scriptModule) {
|
|
372
385
|
for (const sm of componentInstruction.scriptModule) if (!allScriptModules.find((existing) => existing.path === sm.path)) allScriptModules.push(sm);
|
|
373
386
|
}
|
|
@@ -376,6 +389,7 @@ function buildCompileView(module, isComponent = false, scriptRes, depthChain = [
|
|
|
376
389
|
for (const sm of allScriptModules) if (!scriptRes.has(sm.path)) scriptRes.set(sm.path, sm.code);
|
|
377
390
|
compileModuleWithAllWxs(module, scriptRes, allScriptModules);
|
|
378
391
|
}
|
|
392
|
+
activePaths.delete(currentPath);
|
|
379
393
|
return {
|
|
380
394
|
scriptModule: allScriptModules,
|
|
381
395
|
templateModule: currentInstruction?.templateModule || []
|
|
@@ -428,14 +442,7 @@ function compileModule(module, isComponent, scriptRes, options = {}) {
|
|
|
428
442
|
filename: module.path,
|
|
429
443
|
id: `data-v-${module.id}`,
|
|
430
444
|
scoped: true,
|
|
431
|
-
compilerOptions: {
|
|
432
|
-
prefixIdentifiers: true,
|
|
433
|
-
hoistStatic: false,
|
|
434
|
-
cacheHandlers: true,
|
|
435
|
-
scopeId: `data-v-${module.id}`,
|
|
436
|
-
mode: "function",
|
|
437
|
-
inline: true
|
|
438
|
-
}
|
|
445
|
+
compilerOptions: getTemplateCompilerOptions(`data-v-${module.id}`)
|
|
439
446
|
});
|
|
440
447
|
let tplComponents = "{";
|
|
441
448
|
for (const tm of compileInstruction.templateModule) {
|
|
@@ -444,14 +451,7 @@ function compileModule(module, isComponent, scriptRes, options = {}) {
|
|
|
444
451
|
filename: tm.path,
|
|
445
452
|
id: `data-v-${module.id}`,
|
|
446
453
|
scoped: true,
|
|
447
|
-
compilerOptions: {
|
|
448
|
-
prefixIdentifiers: true,
|
|
449
|
-
hoistStatic: false,
|
|
450
|
-
cacheHandlers: true,
|
|
451
|
-
scopeId: `data-v-${module.id}`,
|
|
452
|
-
mode: "function",
|
|
453
|
-
inline: true
|
|
454
|
-
}
|
|
454
|
+
compilerOptions: getTemplateCompilerOptions(`data-v-${module.id}`)
|
|
455
455
|
});
|
|
456
456
|
code = insertWxsToRenderCode(code, compileInstruction.scriptModule, scriptRes, tm.path);
|
|
457
457
|
tplComponents += `'${tm.path}':${code},`;
|
|
@@ -461,8 +461,12 @@ function compileModule(module, isComponent, scriptRes, options = {}) {
|
|
|
461
461
|
const code = `Module({
|
|
462
462
|
path: '${module.path}',
|
|
463
463
|
id: '${module.id}',
|
|
464
|
+
appStyleScopeId: ${JSON.stringify(module.appStyleScopeId || null)},
|
|
465
|
+
sharedStyleScopeIds: ${JSON.stringify(module.sharedStyleScopeIds || [])},
|
|
466
|
+
styleIsolation: ${JSON.stringify(module.styleIsolation || "isolated")},
|
|
464
467
|
render: ${transCode},
|
|
465
468
|
usingComponents: ${JSON.stringify(module.usingComponents)},
|
|
469
|
+
customTabBar: ${JSON.stringify(module.customTabBar || null)},
|
|
466
470
|
tplComponents: ${tplComponents},
|
|
467
471
|
});`;
|
|
468
472
|
const allWxsModules = collectAllWxsModules(scriptRes, /* @__PURE__ */ new Set(), compileInstruction.scriptModule || []);
|
|
@@ -613,14 +617,7 @@ function compileModuleWithAllWxs(module, scriptRes, allScriptModules) {
|
|
|
613
617
|
filename: module.path,
|
|
614
618
|
id: `data-v-${module.id}`,
|
|
615
619
|
scoped: true,
|
|
616
|
-
compilerOptions: {
|
|
617
|
-
prefixIdentifiers: true,
|
|
618
|
-
hoistStatic: false,
|
|
619
|
-
cacheHandlers: true,
|
|
620
|
-
scopeId: `data-v-${module.id}`,
|
|
621
|
-
mode: "function",
|
|
622
|
-
inline: true
|
|
623
|
-
}
|
|
620
|
+
compilerOptions: getTemplateCompilerOptions(`data-v-${module.id}`)
|
|
624
621
|
});
|
|
625
622
|
let tplComponents = "{";
|
|
626
623
|
for (const tm of mergedInstruction.templateModule) {
|
|
@@ -629,14 +626,7 @@ function compileModuleWithAllWxs(module, scriptRes, allScriptModules) {
|
|
|
629
626
|
filename: tm.path,
|
|
630
627
|
id: `data-v-${module.id}`,
|
|
631
628
|
scoped: true,
|
|
632
|
-
compilerOptions: {
|
|
633
|
-
prefixIdentifiers: true,
|
|
634
|
-
hoistStatic: false,
|
|
635
|
-
cacheHandlers: true,
|
|
636
|
-
scopeId: `data-v-${module.id}`,
|
|
637
|
-
mode: "function",
|
|
638
|
-
inline: true
|
|
639
|
-
}
|
|
629
|
+
compilerOptions: getTemplateCompilerOptions(`data-v-${module.id}`)
|
|
640
630
|
});
|
|
641
631
|
code = insertWxsToRenderCode(code, allScriptModules, scriptRes, tm.path);
|
|
642
632
|
tplComponents += `'${tm.path}':${code},`;
|
|
@@ -646,8 +636,12 @@ function compileModuleWithAllWxs(module, scriptRes, allScriptModules) {
|
|
|
646
636
|
const code = `Module({
|
|
647
637
|
path: '${module.path}',
|
|
648
638
|
id: '${module.id}',
|
|
639
|
+
appStyleScopeId: ${JSON.stringify(module.appStyleScopeId || null)},
|
|
640
|
+
sharedStyleScopeIds: ${JSON.stringify(module.sharedStyleScopeIds || [])},
|
|
641
|
+
styleIsolation: ${JSON.stringify(module.styleIsolation || "isolated")},
|
|
649
642
|
render: ${transCode},
|
|
650
643
|
usingComponents: ${JSON.stringify(module.usingComponents)},
|
|
644
|
+
customTabBar: ${JSON.stringify(module.customTabBar || null)},
|
|
651
645
|
tplComponents: ${tplComponents},
|
|
652
646
|
});`;
|
|
653
647
|
const cacheData = {
|
|
@@ -729,12 +723,13 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder,
|
|
|
729
723
|
const workPath = getWorkPath();
|
|
730
724
|
const fullPath = getViewPath(workPath, path);
|
|
731
725
|
if (!fullPath) return { tpl: void 0 };
|
|
726
|
+
const sourcePath = toMiniProgramModuleId(fullPath, workPath).replace(buildExtStripRegex(getTemplateExts()), "");
|
|
732
727
|
const diagnosticSource = fullPath.startsWith(workPath) ? fullPath.slice(workPath.length) : path;
|
|
733
728
|
let content = getContentByPath(fullPath).trim();
|
|
734
729
|
if (!content) content = "<block></block>";
|
|
735
730
|
else {
|
|
736
731
|
checkTemplateCompatibility(content, diagnosticSource, components);
|
|
737
|
-
if (isComponent) content = `<
|
|
732
|
+
if (isComponent) content = `<component-host name="${path}">${content}</component-host>`;
|
|
738
733
|
else if (cheerio.load(content, {
|
|
739
734
|
xmlMode: true,
|
|
740
735
|
decodeEntities: false
|
|
@@ -752,7 +747,7 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder,
|
|
|
752
747
|
$("include").each((_, elem) => {
|
|
753
748
|
const src = $(elem).attr("src");
|
|
754
749
|
if (src) {
|
|
755
|
-
const includeFullPath =
|
|
750
|
+
const includeFullPath = resolveTemplateDependencyPath(workPath, sourcePath, src);
|
|
756
751
|
let includePath = includeFullPath.replace(workPath, "").replace(buildExtStripRegex(getTemplateExts()), "");
|
|
757
752
|
const includeDiagnosticSource = includeFullPath.startsWith(workPath) ? includeFullPath.slice(workPath.length) : includePath;
|
|
758
753
|
if (!includePath.startsWith("/")) includePath = "/" + includePath;
|
|
@@ -773,13 +768,13 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder,
|
|
|
773
768
|
} else $(elem).remove();
|
|
774
769
|
} else $(elem).remove();
|
|
775
770
|
});
|
|
776
|
-
transTagTemplate($, templateModule,
|
|
777
|
-
transTagWxs($, scriptModule,
|
|
771
|
+
transTagTemplate($, templateModule, sourcePath, components, componentPlaceholder);
|
|
772
|
+
transTagWxs($, scriptModule, sourcePath);
|
|
778
773
|
const importNodes = $("import");
|
|
779
774
|
importNodes.each((_, elem) => {
|
|
780
775
|
const src = $(elem).attr("src");
|
|
781
776
|
if (src) {
|
|
782
|
-
const importFullPath =
|
|
777
|
+
const importFullPath = resolveTemplateDependencyPath(workPath, sourcePath, src);
|
|
783
778
|
let importPath = importFullPath.replace(workPath, "").replace(buildExtStripRegex(getTemplateExts()), "");
|
|
784
779
|
const importDiagnosticSource = importFullPath.startsWith(workPath) ? importFullPath.slice(workPath.length) : importPath;
|
|
785
780
|
if (!importPath.startsWith("/")) importPath = "/" + importPath;
|
|
@@ -790,14 +785,14 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder,
|
|
|
790
785
|
xmlMode: true,
|
|
791
786
|
decodeEntities: false
|
|
792
787
|
});
|
|
793
|
-
transTagTemplate($$, templateModule,
|
|
788
|
+
transTagTemplate($$, templateModule, importPath, components, componentPlaceholder);
|
|
794
789
|
transTagWxs($$, scriptModule, importPath);
|
|
795
790
|
processIncludedFileWxsDependencies(importContent, importPath, scriptModule, components, processedPaths);
|
|
796
791
|
}
|
|
797
792
|
}
|
|
798
793
|
});
|
|
799
794
|
importNodes.remove();
|
|
800
|
-
transAsses($, $("image"),
|
|
795
|
+
transAsses($, $("image"), sourcePath);
|
|
801
796
|
const res = [];
|
|
802
797
|
transHtmlTag($.html(), res, components, componentPlaceholder);
|
|
803
798
|
return {
|
|
@@ -832,6 +827,72 @@ function transAsses($, imageNodes, path) {
|
|
|
832
827
|
if (!imgSrc.startsWith("{{")) $(elem).attr("src", collectAssets(getWorkPath(), path, imgSrc, getTargetPath(), getAppId()));
|
|
833
828
|
});
|
|
834
829
|
}
|
|
830
|
+
var DIMINA_SLOT_GROUP_TAG = "dimina-slot-group";
|
|
831
|
+
var DIMINA_FOR_SCOPE_TAG = "dimina-for-scope";
|
|
832
|
+
function getDirectiveAttributeNames(attrs, suffixes) {
|
|
833
|
+
return Object.keys(attrs || {}).filter((name) => suffixes.some((suffix) => name.endsWith(suffix)));
|
|
834
|
+
}
|
|
835
|
+
function hasForAndIf(attrs) {
|
|
836
|
+
return getDirectiveAttributeNames(attrs, [":for", ":for-items"]).length > 0 && getDirectiveAttributeNames(attrs, [":if"]).length > 0;
|
|
837
|
+
}
|
|
838
|
+
function groupDuplicateNamedSlots($, components) {
|
|
839
|
+
const slotHosts = $("*").toArray().filter((element) => {
|
|
840
|
+
const tag = element.tagName;
|
|
841
|
+
return tag === "component" || Boolean(components?.[tag]);
|
|
842
|
+
});
|
|
843
|
+
for (const host of slotHosts) {
|
|
844
|
+
const groups = /* @__PURE__ */ new Map();
|
|
845
|
+
for (const child of $(host).children().toArray()) {
|
|
846
|
+
const slotName = child.attribs?.slot;
|
|
847
|
+
if (!slotName) continue;
|
|
848
|
+
const group = groups.get(slotName) || [];
|
|
849
|
+
group.push(child);
|
|
850
|
+
groups.set(slotName, group);
|
|
851
|
+
}
|
|
852
|
+
for (const [slotName, nodes] of groups) {
|
|
853
|
+
if (nodes.length === 1 && !hasForAndIf(nodes[0].attribs)) continue;
|
|
854
|
+
const wrapper = $(`<${DIMINA_SLOT_GROUP_TAG}></${DIMINA_SLOT_GROUP_TAG}>`);
|
|
855
|
+
wrapper.attr("name", slotName);
|
|
856
|
+
$(nodes[0]).before(wrapper);
|
|
857
|
+
for (const node of nodes) {
|
|
858
|
+
$(node).removeAttr("slot");
|
|
859
|
+
wrapper.append(node);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
function wrapForIfScopes($) {
|
|
865
|
+
const nodes = $("*").toArray();
|
|
866
|
+
for (const node of nodes) {
|
|
867
|
+
if (node.tagName === DIMINA_FOR_SCOPE_TAG || !hasForAndIf(node.attribs)) continue;
|
|
868
|
+
const attrsToMove = getDirectiveAttributeNames(node.attribs, [
|
|
869
|
+
":for",
|
|
870
|
+
":for-items",
|
|
871
|
+
":for-item",
|
|
872
|
+
":for-index",
|
|
873
|
+
":key"
|
|
874
|
+
]);
|
|
875
|
+
const wrapper = $(`<${DIMINA_FOR_SCOPE_TAG}></${DIMINA_FOR_SCOPE_TAG}>`);
|
|
876
|
+
for (const name of attrsToMove) {
|
|
877
|
+
wrapper.attr(name, node.attribs[name]);
|
|
878
|
+
$(node).removeAttr(name);
|
|
879
|
+
}
|
|
880
|
+
$(node).before(wrapper);
|
|
881
|
+
wrapper.append(node);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function normalizeTemplateSyntax(html, components) {
|
|
885
|
+
const $ = cheerio.load(html, {
|
|
886
|
+
xmlMode: true,
|
|
887
|
+
decodeEntities: false,
|
|
888
|
+
_useHtmlParser2: true,
|
|
889
|
+
lowerCaseTags: false,
|
|
890
|
+
lowerCaseAttributeNames: false
|
|
891
|
+
});
|
|
892
|
+
groupDuplicateNamedSlots($, components);
|
|
893
|
+
wrapForIfScopes($);
|
|
894
|
+
return $.html();
|
|
895
|
+
}
|
|
835
896
|
function transHtmlTag(html, res, components, componentPlaceholder) {
|
|
836
897
|
const attrsList = [];
|
|
837
898
|
const parser = new htmlparser2.Parser({
|
|
@@ -859,7 +920,7 @@ function transHtmlTag(html, res, components, componentPlaceholder) {
|
|
|
859
920
|
console.error(error);
|
|
860
921
|
}
|
|
861
922
|
}, { xmlMode: true });
|
|
862
|
-
parser.write(html);
|
|
923
|
+
parser.write(normalizeTemplateSyntax(html, components));
|
|
863
924
|
parser.end();
|
|
864
925
|
}
|
|
865
926
|
/**
|
|
@@ -869,11 +930,15 @@ function transHtmlTag(html, res, components, componentPlaceholder) {
|
|
|
869
930
|
function transTag(opts) {
|
|
870
931
|
const { isStart, tag, attrs, components } = opts;
|
|
871
932
|
let res;
|
|
872
|
-
if (tag ===
|
|
933
|
+
if (tag === DIMINA_SLOT_GROUP_TAG) {
|
|
934
|
+
if (isStart) return `<template ${generateSlotDirective(attrs.name)}>`;
|
|
935
|
+
return "</template>";
|
|
936
|
+
} else if (tag === DIMINA_FOR_SCOPE_TAG) res = "template";
|
|
937
|
+
else if (tag === "slot") res = tag;
|
|
873
938
|
else if (components && components[tag]) res = `dd-${tag}`;
|
|
874
939
|
else if (tag === "component" || tag === "canvas") res = tag;
|
|
875
|
-
else if (
|
|
876
|
-
else res =
|
|
940
|
+
else if (tagWhiteList.includes(tag)) res = `dd-${tag}`;
|
|
941
|
+
else res = tag;
|
|
877
942
|
let tagRes;
|
|
878
943
|
const propsAry = isStart ? getProps(attrs, tag, components) : [];
|
|
879
944
|
const multipleSlots = attrs?.slot;
|
|
@@ -918,7 +983,17 @@ function generateSlotDirective(slotValue) {
|
|
|
918
983
|
*/
|
|
919
984
|
function getProps(attrs, tag, components) {
|
|
920
985
|
const attrsList = [];
|
|
986
|
+
const isCustomComponent = Boolean(components && components[tag]);
|
|
921
987
|
const propBindings = {};
|
|
988
|
+
const hasEventBindings = Object.keys(attrs).some((name) => /^(?:capture-)?(?:bind|catch)(?::)?.+/.test(name));
|
|
989
|
+
if (tag === "page-meta") attrsList.push({
|
|
990
|
+
name: "dimina-rpx-unit",
|
|
991
|
+
value: "vw"
|
|
992
|
+
});
|
|
993
|
+
if (hasEventBindings) attrsList.push({
|
|
994
|
+
name: "v-c-event-node",
|
|
995
|
+
value: components && components[tag] ? "'component'" : "'node'"
|
|
996
|
+
});
|
|
922
997
|
Object.entries(attrs).forEach(([name, value]) => {
|
|
923
998
|
if (name.endsWith(":if")) attrsList.push({
|
|
924
999
|
name: "v-if",
|
|
@@ -942,11 +1017,20 @@ function getProps(attrs, tag, components) {
|
|
|
942
1017
|
name: ":key",
|
|
943
1018
|
value: tranValue
|
|
944
1019
|
});
|
|
945
|
-
} else if (name === "style")
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1020
|
+
} else if (name === "style") {
|
|
1021
|
+
const parsedStyle = parseSafeBraceExp(value);
|
|
1022
|
+
attrsList.push({
|
|
1023
|
+
name: "v-c-style",
|
|
1024
|
+
value: transformRpx(parsedStyle)
|
|
1025
|
+
});
|
|
1026
|
+
if (isCustomComponent) {
|
|
1027
|
+
attrsList.push({
|
|
1028
|
+
name: ":dimina-wxml-style",
|
|
1029
|
+
value: parsedStyle
|
|
1030
|
+
});
|
|
1031
|
+
if (isWrappedByBraces(value) && parsedStyle) propBindings.style = parsedStyle;
|
|
1032
|
+
}
|
|
1033
|
+
} else if (name === "class") {
|
|
950
1034
|
if (isWrappedByBraces(value)) attrsList.push({
|
|
951
1035
|
name: ":class",
|
|
952
1036
|
value: parseClassRules(value)
|
|
@@ -998,7 +1082,7 @@ function getProps(attrs, tag, components) {
|
|
|
998
1082
|
});
|
|
999
1083
|
else if (isWrappedByBraces(value)) {
|
|
1000
1084
|
const pVal = tag === "template" && name === "data" ? parseTemplateDataExp(value) : parseSafeBraceExp(value);
|
|
1001
|
-
if (
|
|
1085
|
+
if (isCustomComponent) {
|
|
1002
1086
|
if (pVal && typeof pVal === "string") propBindings[name] = pVal;
|
|
1003
1087
|
}
|
|
1004
1088
|
attrsList.push({
|
|
@@ -1017,7 +1101,7 @@ function getProps(attrs, tag, components) {
|
|
|
1017
1101
|
else if (/\$\{[^}]*\}/.test(value)) propsRes.push(`:${name}="\`${value}\`"`);
|
|
1018
1102
|
else propsRes.push(`${name}="${escapeQuotes(value)}"`);
|
|
1019
1103
|
});
|
|
1020
|
-
if (
|
|
1104
|
+
if (isCustomComponent && Object.keys(propBindings).length > 0) try {
|
|
1021
1105
|
const validBindings = {};
|
|
1022
1106
|
for (const [key, value] of Object.entries(propBindings)) if (value !== void 0 && value !== null && typeof value === "string") validBindings[key] = value;
|
|
1023
1107
|
if (Object.keys(validBindings).length > 0) {
|
|
@@ -1089,6 +1173,20 @@ function getViewPath(workPath, src) {
|
|
|
1089
1173
|
}
|
|
1090
1174
|
}
|
|
1091
1175
|
/**
|
|
1176
|
+
* 解析 import/include 的模板文件路径。
|
|
1177
|
+
* 微信允许省略 .wxml;显式扩展名保持原样,无扩展名时按当前模板类型优先级补全。
|
|
1178
|
+
*/
|
|
1179
|
+
function resolveTemplateDependencyPath(workPath, ownerPath, src) {
|
|
1180
|
+
const resolvedPath = getAbsolutePath(workPath, ownerPath, src);
|
|
1181
|
+
if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isFile()) return resolvedPath;
|
|
1182
|
+
if (path.extname(resolvedPath)) return resolvedPath;
|
|
1183
|
+
for (const ext of getTemplateExts()) {
|
|
1184
|
+
const candidate = `${resolvedPath}${ext}`;
|
|
1185
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;
|
|
1186
|
+
}
|
|
1187
|
+
return resolvedPath;
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1092
1190
|
* 将字符串内部的双引号进行替换
|
|
1093
1191
|
* @param {*} input
|
|
1094
1192
|
*/
|
|
@@ -1129,7 +1227,7 @@ function splitWithBraces(str) {
|
|
|
1129
1227
|
function parseClassRules(cssRule) {
|
|
1130
1228
|
let list = splitWithBraces(cssRule);
|
|
1131
1229
|
list = list.map((item) => {
|
|
1132
|
-
return
|
|
1230
|
+
return parseSafeBraceExp(item);
|
|
1133
1231
|
});
|
|
1134
1232
|
if (list.length === 1) return list.pop();
|
|
1135
1233
|
return `[${list.join(",")}]`;
|
|
@@ -1157,11 +1255,16 @@ function getForIndexName(attrs) {
|
|
|
1157
1255
|
* @param {*} attrs
|
|
1158
1256
|
*/
|
|
1159
1257
|
function parseForExp(exp, attrs) {
|
|
1160
|
-
return `(${getForItemName(attrs)}, ${getForIndexName(attrs)}) in ${
|
|
1258
|
+
return `(${getForItemName(attrs)}, ${getForIndexName(attrs)}) in ${parseSafeBraceExp(exp)}`;
|
|
1161
1259
|
}
|
|
1162
1260
|
var braceRegex = /(\{\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}\})|([^{}]+)/g;
|
|
1163
1261
|
var noBraceRegex = /\{\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}\}/;
|
|
1164
1262
|
var ternaryRegex = /[^?]+\?.+:.+/;
|
|
1263
|
+
var RESERVED_TEMPLATE_CONTEXT_ALIASES = /* @__PURE__ */ new Map([["class", "__dimina_reserved_class"]]);
|
|
1264
|
+
var RESERVED_TEMPLATE_CONTEXT_NAMES = new Map([...RESERVED_TEMPLATE_CONTEXT_ALIASES].map(([name, alias]) => [alias, name]));
|
|
1265
|
+
function encodeReservedTemplateContextIdentifier(expression) {
|
|
1266
|
+
return RESERVED_TEMPLATE_CONTEXT_ALIASES.get(expression) || expression;
|
|
1267
|
+
}
|
|
1165
1268
|
/**
|
|
1166
1269
|
* 解析 {{}} 表达式的值
|
|
1167
1270
|
* @param {*} exp
|
|
@@ -1173,7 +1276,7 @@ function parseBraceExp(exp) {
|
|
|
1173
1276
|
if (result[1]) {
|
|
1174
1277
|
const matchResult = result[1].match(noBraceRegex);
|
|
1175
1278
|
if (matchResult) {
|
|
1176
|
-
const statement = matchResult[1].trim();
|
|
1279
|
+
const statement = encodeReservedTemplateContextIdentifier(matchResult[1].trim());
|
|
1177
1280
|
if (ternaryRegex.test(statement)) group.push(`(${statement})`);
|
|
1178
1281
|
else group.push(statement);
|
|
1179
1282
|
}
|
|
@@ -1189,8 +1292,8 @@ function parseBraceExp(exp) {
|
|
|
1189
1292
|
*/
|
|
1190
1293
|
function parseTemplateDataExp(exp) {
|
|
1191
1294
|
const matchResult = exp.trim().match(/^\{\{([\s\S]*)\}\}$/);
|
|
1192
|
-
if (matchResult) return `{${matchResult[1].trim()}}
|
|
1193
|
-
return `{${
|
|
1295
|
+
if (matchResult) return addOptionalChaining(`{${matchResult[1].trim()}}`);
|
|
1296
|
+
return `{${parseSafeBraceExp(exp)}}`;
|
|
1194
1297
|
}
|
|
1195
1298
|
function transTagWxs($, scriptModule, filePath) {
|
|
1196
1299
|
const wxsNodes = $(getViewScriptTags().join(","));
|
|
@@ -1330,8 +1433,7 @@ function insertWxsToRenderCode(code, scriptModule, scriptRes, filename = "render
|
|
|
1330
1433
|
});
|
|
1331
1434
|
declarations.push(`const ${localIdentifier} = require(${JSON.stringify(requireModuleName)});`);
|
|
1332
1435
|
}
|
|
1333
|
-
if (wxsBindings.length
|
|
1334
|
-
if (renderBody?.type === "BlockStatement") codeReplacements.push({
|
|
1436
|
+
if (wxsBindings.length > 0 && renderBody?.type === "BlockStatement") codeReplacements.push({
|
|
1335
1437
|
type: "insert",
|
|
1336
1438
|
start: renderBody.start + 1,
|
|
1337
1439
|
end: renderBody.start + 1,
|
|
@@ -1339,6 +1441,15 @@ function insertWxsToRenderCode(code, scriptModule, scriptRes, filename = "render
|
|
|
1339
1441
|
});
|
|
1340
1442
|
walk(ast, { enter(node) {
|
|
1341
1443
|
if (node.type === "MemberExpression" && node.object?.type === "Identifier" && node.object.name === "_ctx" && !node.computed && node.property?.type === "Identifier") {
|
|
1444
|
+
const reservedName = RESERVED_TEMPLATE_CONTEXT_NAMES.get(node.property.name);
|
|
1445
|
+
if (reservedName) {
|
|
1446
|
+
codeReplacements.push({
|
|
1447
|
+
start: node.property.start,
|
|
1448
|
+
end: node.property.end,
|
|
1449
|
+
value: reservedName
|
|
1450
|
+
});
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1342
1453
|
const replacement = wxsBindings.find((item) => item.templatePropertyName === node.property.name);
|
|
1343
1454
|
if (replacement) codeReplacements.push({
|
|
1344
1455
|
start: node.start,
|
|
@@ -1347,8 +1458,9 @@ function insertWxsToRenderCode(code, scriptModule, scriptRes, filename = "render
|
|
|
1347
1458
|
});
|
|
1348
1459
|
}
|
|
1349
1460
|
} });
|
|
1461
|
+
if (codeReplacements.length === 0) return getProgramCode(code, ast);
|
|
1350
1462
|
const transformed = applyCodeReplacements(code, codeReplacements);
|
|
1351
1463
|
return getProgramCode(transformed, parseJs(transformed, filename));
|
|
1352
1464
|
}
|
|
1353
1465
|
//#endregion
|
|
1354
|
-
export { compileML, generateSlotDirective, generateVModelTemplate, initWxsFilePathMap, loadWxsModule, parseBraceExp, parseClassRules, parseKeyExpression, parseTemplateDataExp, processIncludeConditionalAttrs, processWxsContent, splitWithBraces };
|
|
1466
|
+
export { compileML, generateSlotDirective, generateVModelTemplate, initWxsFilePathMap, loadWxsModule, normalizeTemplateSyntax, parseBraceExp, parseClassRules, parseKeyExpression, parseTemplateDataExp, processIncludeConditionalAttrs, processWxsContent, splitWithBraces };
|