@dimina/compiler 1.0.7 → 1.0.9

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const fs = require("node:fs");
4
+ const path = require("node:path");
4
5
  const node_worker_threads = require("node:worker_threads");
5
6
  const babel = require("@babel/core");
6
7
  const _traverse = require("@babel/traverse");
@@ -9,7 +10,7 @@ const compilerSfc = require("@vue/compiler-sfc");
9
10
  const cheerio = require("cheerio");
10
11
  const esbuild = require("esbuild");
11
12
  const htmlparser2 = require("htmlparser2");
12
- const env = require("../env-CGYKCSjT.cjs");
13
+ const env = require("../env-Cmen1qwy.cjs");
13
14
  function _interopNamespaceDefault(e) {
14
15
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
15
16
  if (e) {
@@ -31,6 +32,10 @@ const htmlparser2__namespace = /* @__PURE__ */ _interopNamespaceDefault(htmlpars
31
32
  const traverse = _traverse.default ? _traverse.default : _traverse;
32
33
  const fileType = [".wxml", ".ddml"];
33
34
  const compileResCache = /* @__PURE__ */ new Map();
35
+ const wxsModuleRegistry = /* @__PURE__ */ new Set();
36
+ const wxsFilePathMap = /* @__PURE__ */ new Map();
37
+ const moduleCompileStatus = /* @__PURE__ */ new Map();
38
+ const moduleCompileResults = /* @__PURE__ */ new Map();
34
39
  if (!node_worker_threads.isMainThread) {
35
40
  node_worker_threads.parentPort.on("message", async ({ pages, storeInfo }) => {
36
41
  try {
@@ -55,7 +60,17 @@ if (!node_worker_threads.isMainThread) {
55
60
  }
56
61
  });
57
62
  }
63
+ function clearCompileState() {
64
+ moduleCompileStatus.clear();
65
+ moduleCompileResults.clear();
66
+ compileResCache.clear();
67
+ wxsModuleRegistry.clear();
68
+ wxsFilePathMap.clear();
69
+ }
58
70
  async function compileML(pages, root, progress) {
71
+ const workPath = env.getWorkPath();
72
+ clearCompileState();
73
+ initWxsFilePathMap(workPath);
59
74
  for (const page of pages) {
60
75
  const scriptRes = /* @__PURE__ */ new Map();
61
76
  buildCompileView(page, false, scriptRes, []);
@@ -88,46 +103,143 @@ async function compileML(pages, root, progress) {
88
103
  progress.completedTasks++;
89
104
  }
90
105
  }
106
+ function initWxsFilePathMap(workPath) {
107
+ wxsFilePathMap.clear();
108
+ const npmDir = path.join(workPath, "miniprogram_npm");
109
+ if (fs.existsSync(npmDir)) {
110
+ scanWxsFiles(npmDir, workPath);
111
+ }
112
+ }
113
+ function scanWxsFiles(dir, workPath) {
114
+ try {
115
+ const items = fs.readdirSync(dir);
116
+ for (const item of items) {
117
+ const fullPath = path.join(dir, item);
118
+ const stat = fs.statSync(fullPath);
119
+ if (stat.isDirectory()) {
120
+ scanWxsFiles(fullPath, workPath);
121
+ } else if (stat.isFile() && item.endsWith(".wxs")) {
122
+ const relativePath = fullPath.replace(workPath, "").replace(/\.wxs$/, "");
123
+ const moduleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
124
+ wxsFilePathMap.set(moduleName, fullPath);
125
+ }
126
+ }
127
+ } catch (error) {
128
+ }
129
+ }
130
+ function registerWxsModule(modulePath) {
131
+ wxsModuleRegistry.add(modulePath);
132
+ }
133
+ function isRegisteredWxsModule(modulePath) {
134
+ return wxsModuleRegistry.has(modulePath);
135
+ }
91
136
  function buildCompileView(module2, isComponent = false, scriptRes, depthChain = []) {
92
137
  const currentPath = module2.path;
138
+ if (moduleCompileStatus.has(currentPath)) {
139
+ const status = moduleCompileStatus.get(currentPath);
140
+ if (status === "pending") {
141
+ console.warn("[view]", `检测到循环依赖: ${[...depthChain, currentPath].join(" -> ")}`);
142
+ return { scriptModule: [] };
143
+ } else if (status === "completed") {
144
+ return moduleCompileResults.get(currentPath) || { scriptModule: [] };
145
+ } else if (status === "failed") {
146
+ console.warn("[view]", `模块编译失败,跳过: ${currentPath}`);
147
+ return { scriptModule: [] };
148
+ }
149
+ }
93
150
  if (depthChain.includes(currentPath)) {
94
151
  console.warn("[view]", `检测到循环依赖: ${[...depthChain, currentPath].join(" -> ")}`);
95
- return;
152
+ return { scriptModule: [] };
96
153
  }
97
- if (depthChain.length > 20) {
98
- console.warn("[view]", `检测到深度依赖: ${[...depthChain, currentPath].join(" -> ")}`);
99
- return;
154
+ if (depthChain.length > 5) {
155
+ console.warn("[view]", `检测到深度依赖,中断编译: ${[...depthChain, currentPath].join(" -> ")}`);
156
+ return { scriptModule: [] };
100
157
  }
158
+ moduleCompileStatus.set(currentPath, "pending");
101
159
  depthChain = [...depthChain, currentPath];
102
- compileModule(module2, isComponent, scriptRes);
103
- if (module2.usingComponents) {
104
- for (const componentInfo of Object.values(module2.usingComponents)) {
105
- const componentModule = env.getComponent(componentInfo);
106
- if (!componentModule) {
107
- continue;
160
+ try {
161
+ const allScriptModules = [];
162
+ const currentInstruction = compileModule(module2, isComponent, scriptRes);
163
+ if (currentInstruction && currentInstruction.scriptModule) {
164
+ allScriptModules.push(...currentInstruction.scriptModule);
165
+ }
166
+ if (module2.usingComponents) {
167
+ for (const componentInfo of Object.values(module2.usingComponents)) {
168
+ const componentModule = env.getComponent(componentInfo);
169
+ if (!componentModule) {
170
+ continue;
171
+ }
172
+ if (componentModule.path === module2.path) {
173
+ console.warn("[view]", `检测到自依赖,跳过处理: ${module2.path}`);
174
+ continue;
175
+ }
176
+ const componentInstruction = buildCompileView(componentModule, true, scriptRes, depthChain);
177
+ if (componentInstruction && componentInstruction.scriptModule) {
178
+ for (const sm of componentInstruction.scriptModule) {
179
+ if (!allScriptModules.find((existing) => existing.path === sm.path)) {
180
+ allScriptModules.push(sm);
181
+ }
182
+ }
183
+ }
108
184
  }
109
- if (componentModule.path === module2.path) {
110
- console.warn("[view]", `检测到自依赖,跳过处理: ${module2.path}`);
111
- continue;
185
+ }
186
+ if (!isComponent && allScriptModules.length > 0) {
187
+ for (const sm of allScriptModules) {
188
+ if (!scriptRes.has(sm.path)) {
189
+ scriptRes.set(sm.path, sm.code);
190
+ }
112
191
  }
113
- buildCompileView(componentModule, true, scriptRes, depthChain);
192
+ compileModuleWithAllWxs(module2, scriptRes, allScriptModules);
114
193
  }
194
+ const result = { scriptModule: allScriptModules };
195
+ moduleCompileStatus.set(currentPath, "completed");
196
+ moduleCompileResults.set(currentPath, result);
197
+ return result;
198
+ } catch (error) {
199
+ moduleCompileStatus.set(currentPath, "failed");
200
+ console.error("[view]", `模块编译失败: ${currentPath}`, error.message);
201
+ return { scriptModule: [] };
115
202
  }
116
203
  }
117
204
  function compileModule(module2, isComponent, scriptRes) {
118
205
  const { tpl, instruction } = toCompileTemplate(isComponent, module2.path, module2.usingComponents, module2.componentPlaceholder);
119
206
  if (!tpl) {
120
- return;
207
+ return null;
121
208
  }
209
+ let useCache = false;
210
+ let cachedCode = null;
122
211
  if (!scriptRes.has(module2.path) && compileResCache.has(module2.path)) {
123
- const res = compileResCache.get(module2.path);
124
- scriptRes.set(module2.path, res);
125
- for (const sm of instruction.scriptModule) {
126
- if (!scriptRes.has(sm.path)) {
127
- scriptRes.set(sm.path, sm.code);
212
+ const cacheData2 = compileResCache.get(module2.path);
213
+ if (cacheData2 && typeof cacheData2 === "object" && cacheData2.code && cacheData2.instruction) {
214
+ cachedCode = cacheData2.code;
215
+ useCache = true;
216
+ for (const sm of cacheData2.instruction.scriptModule) {
217
+ if (!scriptRes.has(sm.path)) {
218
+ scriptRes.set(sm.path, sm.code);
219
+ }
128
220
  }
221
+ } else if (typeof cacheData2 === "string") {
222
+ cachedCode = cacheData2;
223
+ useCache = true;
129
224
  }
130
- return;
225
+ }
226
+ if (useCache && cachedCode) {
227
+ scriptRes.set(module2.path, cachedCode);
228
+ const allWxsModules2 = collectAllWxsModules(scriptRes, /* @__PURE__ */ new Set(), instruction.scriptModule || []);
229
+ if (allWxsModules2.length > 0) {
230
+ const existingModules = instruction.scriptModule || [];
231
+ const mergedModules = [...existingModules];
232
+ for (const wxsModule of allWxsModules2) {
233
+ if (!mergedModules.find((existing) => existing.path === wxsModule.path)) {
234
+ mergedModules.push(wxsModule);
235
+ }
236
+ }
237
+ instruction.scriptModule = mergedModules;
238
+ }
239
+ return {
240
+ ...instruction,
241
+ scriptModule: allWxsModules2
242
+ };
131
243
  }
132
244
  const processedTpl = tpl.replace(/\bthis\./g, "_ctx.");
133
245
  const tplCode = compilerSfc.compileTemplate({
@@ -182,12 +294,233 @@ function compileModule(module2, isComponent, scriptRes) {
182
294
  usingComponents: ${JSON.stringify(module2.usingComponents)},
183
295
  tplComponents: ${tplComponents},
184
296
  });`;
185
- compileResCache.set(module2.path, code);
297
+ const allWxsModules = collectAllWxsModules(scriptRes, /* @__PURE__ */ new Set(), instruction.scriptModule || []);
298
+ if (allWxsModules.length > 0) {
299
+ const existingModules = instruction.scriptModule || [];
300
+ const mergedModules = [...existingModules];
301
+ for (const wxsModule of allWxsModules) {
302
+ if (!mergedModules.find((existing) => existing.path === wxsModule.path)) {
303
+ mergedModules.push(wxsModule);
304
+ }
305
+ }
306
+ instruction.scriptModule = mergedModules;
307
+ }
308
+ const cacheData = {
309
+ code,
310
+ instruction
311
+ };
312
+ compileResCache.set(module2.path, cacheData);
186
313
  scriptRes.set(module2.path, code);
314
+ return instruction;
187
315
  }
188
- function toCompileTemplate(isComponent, path, components, componentPlaceholder) {
316
+ function processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath) {
317
+ let wxsAst;
318
+ try {
319
+ wxsAst = babel.parseSync(wxsContent);
320
+ } catch (error) {
321
+ console.error(`[view] 解析 wxs 文件失败: ${wxsFilePath}`, error.message);
322
+ return wxsContent;
323
+ }
324
+ traverse(wxsAst, {
325
+ CallExpression(astPath) {
326
+ const calleeName = astPath.node.callee.name;
327
+ if (calleeName === "getRegExp") {
328
+ const args = astPath.node.arguments;
329
+ if (args.length > 0) {
330
+ if (args[0].type === "StringLiteral" && (!args[1] || args[1].type === "StringLiteral")) {
331
+ let pattern = "";
332
+ let flags = "";
333
+ const arg = args[0];
334
+ if (arg.extra && arg.extra.raw) {
335
+ pattern = arg.extra.raw.slice(1, -1);
336
+ } else if (arg.value !== void 0) {
337
+ pattern = arg.value;
338
+ } else {
339
+ pattern = "";
340
+ }
341
+ if (args.length > 1) {
342
+ const flagArg = args[1];
343
+ if (flagArg.extra && flagArg.extra.raw) {
344
+ flags = flagArg.extra.raw.slice(1, -1);
345
+ } else if (flagArg.value !== void 0) {
346
+ flags = flagArg.value;
347
+ } else {
348
+ flags = "";
349
+ }
350
+ }
351
+ const regexLiteral = types.regExpLiteral(pattern, flags);
352
+ astPath.replaceWith(regexLiteral);
353
+ } else {
354
+ const newRegExpArgs = [args[0]];
355
+ if (args.length > 1) {
356
+ newRegExpArgs.push(args[1]);
357
+ }
358
+ const newRegExpCall = types.newExpression(
359
+ types.identifier("RegExp"),
360
+ newRegExpArgs
361
+ );
362
+ astPath.replaceWith(newRegExpCall);
363
+ }
364
+ }
365
+ } else if (calleeName === "getDate") {
366
+ const args = [];
367
+ for (let i = 0; i < astPath.node.arguments.length; i++) {
368
+ args.push(astPath.node.arguments[i]);
369
+ }
370
+ const newExpr = types.newExpression(types.identifier("Date"), args);
371
+ astPath.replaceWith(newExpr);
372
+ } else if (calleeName === "require" && astPath.node.arguments.length > 0 && wxsFilePath) {
373
+ const requirePath = astPath.node.arguments[0].value;
374
+ if (requirePath && typeof requirePath === "string") {
375
+ let resolvedWxsPath;
376
+ if (filePath && filePath.includes("/miniprogram_npm/")) {
377
+ const currentWxsDir = path.dirname(wxsFilePath);
378
+ resolvedWxsPath = path.resolve(currentWxsDir, requirePath);
379
+ const relativePath = resolvedWxsPath.replace(workPath, "").replace(/\.wxs$/, "");
380
+ const moduleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
381
+ processWxsDependency(resolvedWxsPath, moduleName, scriptModule, workPath, filePath);
382
+ astPath.node.arguments[0] = types.stringLiteral(moduleName);
383
+ } else {
384
+ const currentWxsDir = path.dirname(wxsFilePath);
385
+ resolvedWxsPath = path.resolve(currentWxsDir, requirePath);
386
+ const relativePath = resolvedWxsPath.replace(workPath, "").replace(/\.wxs$/, "");
387
+ const depModuleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
388
+ processWxsDependency(resolvedWxsPath, depModuleName, scriptModule, workPath, filePath);
389
+ astPath.node.arguments[0] = types.stringLiteral(depModuleName);
390
+ }
391
+ }
392
+ }
393
+ },
394
+ MemberExpression(astPath) {
395
+ if (astPath.node.property.name === "constructor" && !astPath.node.computed) {
396
+ const getTypeString = types.callExpression(
397
+ types.memberExpression(
398
+ types.callExpression(
399
+ types.memberExpression(
400
+ types.memberExpression(
401
+ types.memberExpression(
402
+ types.identifier("Object"),
403
+ types.identifier("prototype")
404
+ ),
405
+ types.identifier("toString")
406
+ ),
407
+ types.identifier("call")
408
+ ),
409
+ [astPath.node.object]
410
+ ),
411
+ types.identifier("slice")
412
+ ),
413
+ [types.numericLiteral(8), types.numericLiteral(-1)]
414
+ );
415
+ astPath.replaceWith(getTypeString);
416
+ }
417
+ }
418
+ });
419
+ return babel.transformFromAstSync(wxsAst, "", {
420
+ comments: false
421
+ }).code;
422
+ }
423
+ function isWxsModuleByContent(moduleCode, modulePath = "") {
424
+ if (!moduleCode || typeof moduleCode !== "string") {
425
+ return false;
426
+ }
427
+ if (modulePath && isRegisteredWxsModule(modulePath)) {
428
+ return true;
429
+ }
430
+ return false;
431
+ }
432
+ function processWxsDependency(wxsFilePath, moduleName, scriptModule, workPath, filePath) {
433
+ if (!fs.existsSync(wxsFilePath)) {
434
+ console.warn(`[view] wxs 依赖文件不存在: ${wxsFilePath}`);
435
+ return;
436
+ }
437
+ if (scriptModule.find((sm) => sm.path === moduleName)) {
438
+ return;
439
+ }
440
+ const wxsContent = env.getContentByPath(wxsFilePath).trim();
441
+ if (!wxsContent) {
442
+ return;
443
+ }
444
+ const wxsCode = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath);
445
+ registerWxsModule(moduleName);
446
+ scriptModule.push({
447
+ path: moduleName,
448
+ code: wxsCode
449
+ });
450
+ }
451
+ function compileModuleWithAllWxs(module2, scriptRes, allScriptModules) {
452
+ const { tpl, instruction } = toCompileTemplate(false, module2.path, module2.usingComponents, module2.componentPlaceholder);
453
+ if (!tpl) {
454
+ return;
455
+ }
456
+ const mergedInstruction = {
457
+ ...instruction,
458
+ scriptModule: allScriptModules
459
+ };
460
+ const processedTpl = tpl.replace(/\bthis\./g, "_ctx.");
461
+ const tplCode = compilerSfc.compileTemplate({
462
+ source: processedTpl,
463
+ filename: module2.path,
464
+ id: `data-v-${module2.id}`,
465
+ scoped: true,
466
+ compilerOptions: {
467
+ prefixIdentifiers: true,
468
+ hoistStatic: false,
469
+ cacheHandlers: true,
470
+ scopeId: `data-v-${module2.id}`,
471
+ mode: "function",
472
+ inline: true
473
+ }
474
+ });
475
+ let tplComponents = "{";
476
+ for (const tm of mergedInstruction.templateModule) {
477
+ let { code: code2 } = compilerSfc.compileTemplate({
478
+ source: tm.tpl,
479
+ filename: tm.path,
480
+ id: `data-v-${module2.id}`,
481
+ scoped: true,
482
+ compilerOptions: {
483
+ prefixIdentifiers: true,
484
+ hoistStatic: false,
485
+ cacheHandlers: true,
486
+ scopeId: `data-v-${module2.id}`,
487
+ mode: "function",
488
+ inline: true
489
+ }
490
+ });
491
+ const ast = babel.parseSync(code2);
492
+ insertWxsToRenderAst(ast, allScriptModules, scriptRes);
493
+ code2 = babel.transformFromAstSync(ast, "", {
494
+ comments: false
495
+ }).code;
496
+ tplComponents += `'${tm.path}':${code2.replace(/;$/, "").replace(/^"use strict";\s*/, "")},`;
497
+ }
498
+ tplComponents += "}";
499
+ const tplAst = babel.parseSync(tplCode.code);
500
+ insertWxsToRenderAst(tplAst, allScriptModules, scriptRes);
501
+ const { code: transCode } = babel.transformFromAstSync(tplAst, "", {
502
+ comments: false
503
+ });
504
+ const code = `Module({
505
+ path: '${module2.path}',
506
+ id: '${module2.id}',
507
+ render: ${transCode.replace(/;$/, "").replace(/^"use strict";\s*/, "")},
508
+ usingComponents: ${JSON.stringify(module2.usingComponents)},
509
+ tplComponents: ${tplComponents},
510
+ });`;
511
+ const cacheData = {
512
+ code,
513
+ instruction: mergedInstruction
514
+ };
515
+ compileResCache.set(module2.path, cacheData);
516
+ scriptRes.set(module2.path, code);
517
+ }
518
+ function processIncludedFileWxsDependencies(content, includePath, scriptModule, components) {
519
+ console.warn("[view]", `跳过被引入文件的组件 wxs 依赖处理: ${includePath}`);
520
+ }
521
+ function toCompileTemplate(isComponent, path2, components, componentPlaceholder) {
189
522
  const workPath = env.getWorkPath();
190
- const fullPath = getViewPath(workPath, path);
523
+ const fullPath = getViewPath(workPath, path2);
191
524
  if (!fullPath) {
192
525
  return { tpl: void 0 };
193
526
  }
@@ -196,7 +529,7 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder)
196
529
  content = "<block></block>";
197
530
  } else {
198
531
  if (isComponent) {
199
- content = `<wrapper>${content}</wrapper>`;
532
+ content = `<wrapper name="${path2}">${content}</wrapper>`;
200
533
  } else {
201
534
  const tempRoot = cheerio__namespace.load(content, {
202
535
  xmlMode: true,
@@ -218,27 +551,51 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder)
218
551
  includeNodes.each((_, elem) => {
219
552
  const src = $(elem).attr("src");
220
553
  if (src) {
221
- const includeContent = env.getContentByPath(env.getAbsolutePath(workPath, path, src)).trim();
554
+ const includeFullPath = env.getAbsolutePath(workPath, path2, src);
555
+ let includePath = includeFullPath.replace(workPath, "").replace(/\.(wxml|ddml)$/, "");
556
+ if (!includePath.startsWith("/")) {
557
+ includePath = "/" + includePath;
558
+ }
559
+ const includeContent = env.getContentByPath(includeFullPath).trim();
222
560
  if (includeContent) {
223
561
  const $includeContent = cheerio__namespace.load(includeContent, {
224
562
  xmlMode: true,
225
563
  decodeEntities: false
226
564
  });
565
+ transTagTemplate(
566
+ $includeContent,
567
+ templateModule,
568
+ includePath,
569
+ components
570
+ );
571
+ transTagWxs(
572
+ $includeContent,
573
+ scriptModule,
574
+ includePath
575
+ );
576
+ processIncludedFileWxsDependencies(includeContent, includePath);
227
577
  $includeContent("template").remove();
228
578
  $includeContent("wxs").remove();
229
579
  $includeContent("dds").remove();
230
- $(elem).html($includeContent.html());
580
+ $(elem).replaceWith($includeContent.html());
581
+ } else {
582
+ $(elem).remove();
231
583
  }
584
+ } else {
585
+ $(elem).remove();
232
586
  }
233
587
  });
234
- transTagTemplate($, templateModule, path, components);
235
- transTagWxs($, scriptModule, path);
588
+ transTagTemplate($, templateModule, path2, components);
589
+ transTagWxs($, scriptModule, path2);
236
590
  const importNodes = $("import");
237
591
  importNodes.each((_, elem) => {
238
592
  const src = $(elem).attr("src");
239
593
  if (src) {
240
- const importFullPath = env.getAbsolutePath(workPath, path, src);
241
- const importPath = importFullPath.replace(workPath, "").split("/").slice(0, -1).join("/");
594
+ const importFullPath = env.getAbsolutePath(workPath, path2, src);
595
+ let importPath = importFullPath.replace(workPath, "").replace(/\.(wxml|ddml)$/, "");
596
+ if (!importPath.startsWith("/")) {
597
+ importPath = "/" + importPath;
598
+ }
242
599
  const importContent = env.getContentByPath(importFullPath).trim();
243
600
  if (importContent) {
244
601
  const $$ = cheerio__namespace.load(importContent, {
@@ -248,7 +605,7 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder)
248
605
  transTagTemplate(
249
606
  $$,
250
607
  templateModule,
251
- path,
608
+ path2,
252
609
  components
253
610
  );
254
611
  transTagWxs(
@@ -256,11 +613,12 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder)
256
613
  scriptModule,
257
614
  importPath
258
615
  );
616
+ processIncludedFileWxsDependencies(importContent, importPath);
259
617
  }
260
618
  }
261
619
  });
262
620
  importNodes.remove();
263
- transAsses($, $("image"), path);
621
+ transAsses($, $("image"), path2);
264
622
  const res = [];
265
623
  transHtmlTag($.html(), res, components);
266
624
  return {
@@ -271,7 +629,7 @@ function toCompileTemplate(isComponent, path, components, componentPlaceholder)
271
629
  }
272
630
  };
273
631
  }
274
- function transTagTemplate($, templateModule, path, components, componentPlaceholder) {
632
+ function transTagTemplate($, templateModule, path2, components, componentPlaceholder) {
275
633
  const templateNodes = $("template[name]");
276
634
  templateNodes.each((_, elem) => {
277
635
  const name = $(elem).attr("name");
@@ -280,7 +638,7 @@ function transTagTemplate($, templateModule, path, components, componentPlacehol
280
638
  templateContent.find("include").remove();
281
639
  templateContent.find("wxs").remove();
282
640
  templateContent.find("dds").remove();
283
- transAsses($, templateContent.find("image"), path);
641
+ transAsses($, templateContent.find("image"), path2);
284
642
  const res = [];
285
643
  transHtmlTag(templateContent.html(), res, components);
286
644
  templateModule.push({
@@ -290,11 +648,11 @@ function transTagTemplate($, templateModule, path, components, componentPlacehol
290
648
  });
291
649
  templateNodes.remove();
292
650
  }
293
- function transAsses($, imageNodes, path) {
651
+ function transAsses($, imageNodes, path2) {
294
652
  imageNodes.each((_, elem) => {
295
653
  const imgSrc = $(elem).attr("src").trim();
296
654
  if (!imgSrc.startsWith("{{")) {
297
- $(elem).attr("src", env.collectAssets(env.getWorkPath(), path, imgSrc, env.getTargetPath(), env.getAppId()));
655
+ $(elem).attr("src", env.collectAssets(env.getWorkPath(), path2, imgSrc, env.getTargetPath(), env.getAppId()));
298
656
  }
299
657
  });
300
658
  }
@@ -389,7 +747,7 @@ function getProps(attrs, tag) {
389
747
  });
390
748
  } else if (name.endsWith(":for-item") || name.endsWith(":for-index")) ;
391
749
  else if (name.endsWith(":key")) {
392
- const tranValue = parseKeyExpression(value, getForItemName(attrs));
750
+ const tranValue = parseKeyExpression(value, getForItemName(attrs), getForIndexName(attrs));
393
751
  attrsList.push({
394
752
  name: ":key",
395
753
  value: tranValue
@@ -506,7 +864,7 @@ function generateVModelTemplate(expression) {
506
864
  }
507
865
  return updateExpression;
508
866
  }
509
- function parseKeyExpression(exp, itemName = "item") {
867
+ function parseKeyExpression(exp, itemName = "item", indexName = "index") {
510
868
  exp = exp.trim();
511
869
  if (/\*this/.test(exp) || /\*item/.test(exp)) {
512
870
  return `${itemName}.toString()`;
@@ -515,12 +873,17 @@ function parseKeyExpression(exp, itemName = "item") {
515
873
  if (/^-?\d+(\.\d+)?$/.test(exp)) {
516
874
  return exp;
517
875
  }
876
+ if (exp === indexName) {
877
+ return indexName;
878
+ }
518
879
  return exp.startsWith(itemName) ? `${exp}` : `${itemName}.${exp}`;
519
880
  }
520
881
  if (exp.startsWith("{{") && exp.endsWith("}}")) {
521
882
  const content = exp.slice(2, -2).trim();
522
883
  if (content === "this") {
523
884
  return `${itemName}.toString()`;
885
+ } else if (content === indexName) {
886
+ return indexName;
524
887
  } else {
525
888
  return content.startsWith(itemName) ? `${content}` : `${itemName}.${content}`;
526
889
  }
@@ -529,6 +892,9 @@ function parseKeyExpression(exp, itemName = "item") {
529
892
  const result = parts.map((part) => {
530
893
  if (part.startsWith("{{") && part.endsWith("}}")) {
531
894
  const content = part.slice(2, -2).trim();
895
+ if (content === indexName) {
896
+ return indexName;
897
+ }
532
898
  return content.startsWith(itemName) ? content : `${itemName}.${content}`;
533
899
  }
534
900
  return `'${part}'`;
@@ -634,7 +1000,7 @@ function parseBraceExp(exp) {
634
1000
  }
635
1001
  return group.join("").replace(/^\+|\+$/g, "");
636
1002
  }
637
- function transTagWxs($, scriptModule, path) {
1003
+ function transTagWxs($, scriptModule, filePath) {
638
1004
  let wxsNodes = $("wxs");
639
1005
  if (wxsNodes.length === 0) {
640
1006
  wxsNodes = $("dds");
@@ -643,56 +1009,158 @@ function transTagWxs($, scriptModule, path) {
643
1009
  const smName = $(elem).attr("module");
644
1010
  if (smName) {
645
1011
  let wxsContent;
646
- if (compileResCache.has(smName)) {
647
- wxsContent = compileResCache.get(smName);
1012
+ let uniqueModuleName = smName;
1013
+ let cacheKey = smName;
1014
+ const src = $(elem).attr("src");
1015
+ let wxsFilePath = null;
1016
+ const workPath = env.getWorkPath();
1017
+ if (src) {
1018
+ if (filePath.includes("/miniprogram_npm/")) {
1019
+ const componentDir = filePath.split("/").slice(0, -1).join("/");
1020
+ const componentFullPath = workPath + componentDir;
1021
+ wxsFilePath = path.resolve(componentFullPath, src);
1022
+ } else {
1023
+ wxsFilePath = env.getAbsolutePath(workPath, filePath, src);
1024
+ }
1025
+ if (wxsFilePath) {
1026
+ const relativePath = wxsFilePath.replace(workPath, "").replace(/\.wxs$/, "");
1027
+ uniqueModuleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
1028
+ cacheKey = wxsFilePath;
1029
+ }
1030
+ }
1031
+ if (compileResCache.has(cacheKey)) {
1032
+ wxsContent = compileResCache.get(cacheKey);
648
1033
  } else {
649
- const src = $(elem).attr("src");
650
- if (src) {
651
- wxsContent = env.getContentByPath(env.getAbsolutePath(env.getWorkPath(), path, src)).trim();
1034
+ if (src && wxsFilePath) {
1035
+ if (fs.existsSync(wxsFilePath)) {
1036
+ wxsContent = env.getContentByPath(wxsFilePath).trim();
1037
+ } else {
1038
+ console.warn(`[view] wxs 文件不存在: ${wxsFilePath}`);
1039
+ return;
1040
+ }
652
1041
  } else {
653
1042
  wxsContent = $(elem).html();
654
1043
  }
655
- const wxsAst = babel.parseSync(wxsContent);
656
- traverse(wxsAst, {
657
- CallExpression(path2) {
658
- if (path2.node.callee.name === "getRegExp" || path2.node.callee.name === "getDate") {
659
- const args = [];
660
- for (let i = 0; i < path2.node.arguments.length; i++) {
661
- args.push(path2.node.arguments[i]);
662
- }
663
- const newExpr = types.newExpression(types.identifier(path2.node.callee.name.substring(3)), args);
664
- path2.replaceWith(newExpr);
665
- }
666
- }
667
- });
668
- wxsContent = babel.transformFromAstSync(wxsAst, "", {
669
- comments: false
670
- }).code;
671
- compileResCache.set(smName, wxsContent);
1044
+ if (!wxsContent) {
1045
+ return;
1046
+ }
1047
+ wxsContent = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath);
1048
+ compileResCache.set(cacheKey, wxsContent);
672
1049
  }
673
1050
  if (wxsContent) {
1051
+ registerWxsModule(uniqueModuleName);
674
1052
  scriptModule.push({
675
- path: smName,
676
- code: wxsContent
1053
+ path: uniqueModuleName,
1054
+ code: wxsContent,
1055
+ originalName: smName
1056
+ // 保存原始模块名用于模板中的引用
677
1057
  });
678
1058
  }
679
1059
  }
680
1060
  });
681
1061
  wxsNodes.remove();
682
1062
  }
1063
+ function collectAllWxsModules(scriptRes, collectedPaths = /* @__PURE__ */ new Set(), scriptModule = [], maxDepth = 5) {
1064
+ if (maxDepth <= 0) {
1065
+ console.warn("[view]", "collectAllWxsModules 达到最大递归深度,停止处理");
1066
+ return [];
1067
+ }
1068
+ const allWxsModules = [];
1069
+ const workPath = env.getWorkPath();
1070
+ for (const [modulePath, moduleCode] of scriptRes.entries()) {
1071
+ if (collectedPaths.has(modulePath)) {
1072
+ continue;
1073
+ }
1074
+ if (isWxsModuleByContent(moduleCode, modulePath)) {
1075
+ collectedPaths.add(modulePath);
1076
+ allWxsModules.push({
1077
+ path: modulePath,
1078
+ code: moduleCode
1079
+ });
1080
+ const dependencies = extractWxsDependencies(moduleCode);
1081
+ for (const depPath of dependencies) {
1082
+ if (!collectedPaths.has(depPath)) {
1083
+ if (scriptRes.has(depPath)) {
1084
+ const depModules = collectAllWxsModules(
1085
+ /* @__PURE__ */ new Map([[depPath, scriptRes.get(depPath)]]),
1086
+ collectedPaths,
1087
+ scriptModule,
1088
+ maxDepth - 1
1089
+ );
1090
+ allWxsModules.push(...depModules);
1091
+ } else {
1092
+ const loaded = loadWxsModule(depPath, workPath, scriptModule);
1093
+ if (loaded) {
1094
+ scriptRes.set(depPath, loaded.code);
1095
+ allWxsModules.push(loaded);
1096
+ collectedPaths.add(depPath);
1097
+ const depModules = collectAllWxsModules(
1098
+ /* @__PURE__ */ new Map([[depPath, loaded.code]]),
1099
+ collectedPaths,
1100
+ scriptModule,
1101
+ maxDepth - 1
1102
+ );
1103
+ allWxsModules.push(...depModules);
1104
+ }
1105
+ }
1106
+ }
1107
+ }
1108
+ }
1109
+ }
1110
+ return allWxsModules;
1111
+ }
1112
+ function loadWxsModule(modulePath, workPath, scriptModule) {
1113
+ if (!modulePath.startsWith("miniprogram_npm__") || !modulePath.includes("_wxs_")) {
1114
+ return null;
1115
+ }
1116
+ const wxsFilePath = wxsFilePathMap.get(modulePath);
1117
+ if (!wxsFilePath) {
1118
+ console.warn(`[view] 无法找到 wxs 模块文件: ${modulePath}`);
1119
+ return null;
1120
+ }
1121
+ try {
1122
+ const wxsContent = env.getContentByPath(wxsFilePath).trim();
1123
+ if (!wxsContent) {
1124
+ return null;
1125
+ }
1126
+ const processedContent = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, "");
1127
+ registerWxsModule(modulePath);
1128
+ return {
1129
+ path: modulePath,
1130
+ code: processedContent
1131
+ };
1132
+ } catch (error) {
1133
+ console.warn(`[view] 加载 wxs 模块失败: ${modulePath}`, error.message);
1134
+ return null;
1135
+ }
1136
+ }
1137
+ function extractWxsDependencies(moduleCode) {
1138
+ const dependencies = [];
1139
+ const requirePattern = /(?:require|_)\s*\(\s*["']([^"']+)["']\s*\)/g;
1140
+ let match;
1141
+ while ((match = requirePattern.exec(moduleCode)) !== null) {
1142
+ const depPath = match[1];
1143
+ if (depPath && !dependencies.includes(depPath)) {
1144
+ dependencies.push(depPath);
1145
+ }
1146
+ }
1147
+ return dependencies;
1148
+ }
683
1149
  function insertWxsToRenderAst(ast, scriptModule, scriptRes) {
684
1150
  for (const sm of scriptModule) {
685
1151
  if (!scriptRes.has(sm.path)) {
686
1152
  scriptRes.set(sm.path, sm.code);
687
1153
  }
1154
+ const templatePropertyName = sm.originalName || sm.path;
1155
+ const requireModuleName = sm.path;
688
1156
  const assignmentExpression = types.assignmentExpression(
689
1157
  "=",
690
1158
  // 创建赋值表达式
691
1159
  types.memberExpression(
692
1160
  types.identifier("_ctx"),
693
1161
  // 对象标识符
694
- types.identifier(sm.path),
695
- // 属性标识符
1162
+ types.identifier(templatePropertyName),
1163
+ // 使用原始模块名作为属性名
696
1164
  false
697
1165
  // 是否是计算属性
698
1166
  ),
@@ -700,8 +1168,8 @@ function insertWxsToRenderAst(ast, scriptModule, scriptRes) {
700
1168
  types.callExpression(
701
1169
  types.identifier("require"),
702
1170
  // 函数标识符
703
- [types.stringLiteral(sm.path)]
704
- // 参数列表,这里传入字符串字面量'foo'
1171
+ [types.stringLiteral(requireModuleName)]
1172
+ // 使用唯一模块名作为 require 参数
705
1173
  )
706
1174
  );
707
1175
  const expressionStatement = types.expressionStatement(assignmentExpression);
@@ -713,4 +1181,5 @@ exports.generateVModelTemplate = generateVModelTemplate;
713
1181
  exports.parseBraceExp = parseBraceExp;
714
1182
  exports.parseClassRules = parseClassRules;
715
1183
  exports.parseKeyExpression = parseKeyExpression;
1184
+ exports.processWxsContent = processWxsContent;
716
1185
  exports.splitWithBraces = splitWithBraces;