@dimina-kit/compiler 0.0.1-dev.20260702173719

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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +363 -0
  3. package/dist/compile-core.browser.js +281945 -0
  4. package/dist/compile-core.node.js +3702 -0
  5. package/dist/pool.browser.js +99 -0
  6. package/dist/pool.node.js +3743 -0
  7. package/dist/stage-worker.browser.js +291085 -0
  8. package/dist/stage-worker.node.js +3097 -0
  9. package/dist/toolchain.browser.js +30 -0
  10. package/package.json +87 -0
  11. package/scripts/build-compiler.js +207 -0
  12. package/scripts/gen-bench-fixture.js +24 -0
  13. package/scripts/kit-resolve-hook.js +35 -0
  14. package/scripts/register-kit.js +2 -0
  15. package/scripts/test-appid-fallback.js +114 -0
  16. package/scripts/test-decompose.js +90 -0
  17. package/scripts/test-hardening.js +78 -0
  18. package/scripts/test-node.js +69 -0
  19. package/scripts/test-npm-scan.js +164 -0
  20. package/scripts/test-pool-hardening.js +65 -0
  21. package/scripts/test-pool-node.js +117 -0
  22. package/scripts/test-realm-reuse.js +77 -0
  23. package/src/browser-entry.js +25 -0
  24. package/src/compile-core.js +428 -0
  25. package/src/pool-node.js +170 -0
  26. package/src/pool.js +122 -0
  27. package/src/shims/esbuild-wasm.js +19 -0
  28. package/src/shims/fs-promises.js +20 -0
  29. package/src/shims/fs.js +59 -0
  30. package/src/shims/less.js +9 -0
  31. package/src/shims/os.js +11 -0
  32. package/src/shims/oxc-parser.js +21 -0
  33. package/src/shims/oxc-walker.js +29 -0
  34. package/src/shims/postcss-noop-plugin.js +9 -0
  35. package/src/shims/process.js +20 -0
  36. package/src/shims/url.js +4 -0
  37. package/src/shims/worker_threads.js +10 -0
  38. package/src/stage-worker-node.js +41 -0
  39. package/src/stage-worker.js +88 -0
  40. package/src/toolchain.js +49 -0
@@ -0,0 +1,3097 @@
1
+ // src/stage-worker-node.js
2
+ import { createRequire } from "node:module";
3
+
4
+ // src/shims/fs.js
5
+ var current = null;
6
+ var call = (name) => (...args) => {
7
+ if (!current) throw new Error("[compiler] no fs backend injected \u2014 call compileMiniApp({ fs })");
8
+ const fn = current[name];
9
+ if (typeof fn === "function") return fn.apply(current, args);
10
+ throw new Error(`[compiler] injected fs is missing ${name}()`);
11
+ };
12
+ var existsSync = call("existsSync");
13
+ var readFileSync = call("readFileSync");
14
+ var writeFileSync = call("writeFileSync");
15
+ var mkdirSync = call("mkdirSync");
16
+ var rmSync = call("rmSync");
17
+ var rmdirSync = call("rmdirSync");
18
+ var readdirSync = call("readdirSync");
19
+ var copyFileSync = call("copyFileSync");
20
+ var statSync = call("statSync");
21
+ var lstatSync = call("lstatSync");
22
+ var unlinkSync = call("unlinkSync");
23
+ var renameSync = call("renameSync");
24
+ var appendFileSync = call("appendFileSync");
25
+ var realpathSync = call("realpathSync");
26
+ var accessSync = call("accessSync");
27
+ var readlinkSync = call("readlinkSync");
28
+ var watch = call("watch");
29
+ var promises = new Proxy({}, {
30
+ get: (_t, prop) => (...args) => {
31
+ if (!current || !current.promises || typeof current.promises[prop] !== "function") {
32
+ throw new Error(`[compiler] injected fs has no promises.${String(prop)}()`);
33
+ }
34
+ return current.promises[prop](...args);
35
+ }
36
+ });
37
+
38
+ // ../../dimina/fe/packages/compiler/src/env.js
39
+ import fs3 from "node:fs";
40
+
41
+ // ../../dimina/fe/packages/compiler/src/common/path-utils.js
42
+ import path from "node:path";
43
+ var WINDOWS_FS_PATH_RE = /^(?:[a-zA-Z]:[\\/]|\\\\)/;
44
+ function isWindowsFsPath(targetPath) {
45
+ return typeof targetPath === "string" && (WINDOWS_FS_PATH_RE.test(targetPath) || targetPath.includes("\\"));
46
+ }
47
+ function getFsPathApi(targetPath) {
48
+ return isWindowsFsPath(targetPath) ? path.win32 : path.posix;
49
+ }
50
+ function normalizeToPosixPath(targetPath) {
51
+ return targetPath.replace(/\\/g, "/");
52
+ }
53
+ function resolveMiniProgramPath(workPath, importerPath, sourcePath) {
54
+ const pathApi = getFsPathApi(importerPath || workPath);
55
+ return sourcePath.startsWith("/") ? pathApi.join(workPath, sourcePath) : pathApi.resolve(pathApi.dirname(importerPath), sourcePath);
56
+ }
57
+ function toMiniProgramModuleId(resolvedPath, workPath) {
58
+ const normalizedResolvedPath = normalizeToPosixPath(resolvedPath);
59
+ const normalizedWorkPath = normalizeToPosixPath(workPath);
60
+ let moduleId = normalizedResolvedPath.startsWith(normalizedWorkPath) ? normalizedResolvedPath.slice(normalizedWorkPath.length) : normalizedResolvedPath;
61
+ moduleId = moduleId.replace(/\/+/g, "/");
62
+ if (!moduleId.startsWith("/")) {
63
+ moduleId = `/${moduleId}`;
64
+ }
65
+ return moduleId;
66
+ }
67
+ function getRelativePosixPath(targetPath, rootPath) {
68
+ return normalizeToPosixPath(targetPath).replace(normalizeToPosixPath(rootPath), "").replace(/^\//, "");
69
+ }
70
+
71
+ // ../../dimina/fe/packages/compiler/src/common/utils.js
72
+ import fs from "node:fs";
73
+ import path2 from "node:path";
74
+ import process from "node:process";
75
+ function hasCompileInfo(modulePath, list, preList) {
76
+ const mergeList = Array.isArray(preList) ? [...preList, ...list] : list;
77
+ for (const element of mergeList) {
78
+ if (element.path === modulePath) {
79
+ return true;
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+ function getAbsolutePath(workPath, pagePath, src) {
85
+ if (src.startsWith("/")) {
86
+ return path2.join(workPath, src);
87
+ }
88
+ if (pagePath.includes("/miniprogram_npm/")) {
89
+ const componentDir = pagePath.split("/").slice(0, -1).join("/");
90
+ const componentFullPath = workPath + componentDir;
91
+ return path2.resolve(componentFullPath, src);
92
+ }
93
+ const relativePath = pagePath.split("/").filter((part) => part !== "").slice(0, -1).join("/");
94
+ return path2.resolve(workPath, relativePath, src);
95
+ }
96
+ var assetsMap = {};
97
+ function collectAssets(workPath, pagePath, src, targetPath, appId) {
98
+ if (src.startsWith("http") || src.startsWith("//")) {
99
+ return src;
100
+ }
101
+ if (!/\.(?:png|jpe?g|gif|svg)(?:\?.*)?$/.test(src)) {
102
+ return src;
103
+ }
104
+ const relativePath = pagePath.split("/").slice(0, -1).join("/");
105
+ const absolutePath = src.startsWith("/") ? workPath + src : path2.resolve(workPath, relativePath, src);
106
+ if (assetsMap[absolutePath]) {
107
+ return assetsMap[absolutePath];
108
+ }
109
+ try {
110
+ const ext = `.${src.split(".").pop()}`;
111
+ const dirPath = absolutePath.split(path2.sep).slice(0, -1).join("/");
112
+ const prefix = uuid();
113
+ const targetStatic = `${targetPath}/main/static`;
114
+ if (!fs.existsSync(targetStatic)) {
115
+ fs.mkdirSync(targetStatic, { recursive: true });
116
+ }
117
+ getFilesWithExtension(dirPath, ext).forEach((file) => {
118
+ fs.copyFileSync(path2.resolve(dirPath, file), `${targetStatic}/${prefix}_${file}`);
119
+ });
120
+ const filename = src.split("/").pop();
121
+ const pathPrefix = process.env.ASSETS_PATH_PREFIX ? "" : "/";
122
+ assetsMap[absolutePath] = `${pathPrefix}${appId}/main/static/${prefix}_${filename}`;
123
+ } catch (error) {
124
+ console.log(error);
125
+ }
126
+ return assetsMap[absolutePath] || src;
127
+ }
128
+ function getFilesWithExtension(directory, extension) {
129
+ const files = fs.readdirSync(directory);
130
+ const filteredFiles = files.filter((file) => path2.extname(file) === extension);
131
+ return filteredFiles;
132
+ }
133
+ function isString(o) {
134
+ return Object.prototype.toString.call(o) === "[object String]";
135
+ }
136
+ function transformRpx(styleText) {
137
+ if (!isString(styleText)) {
138
+ return styleText;
139
+ }
140
+ return styleText.replace(/([+-]?\d+(?:\.\d+)?)rpx/g, (_, pixel) => {
141
+ return `${Number(pixel)}rem`;
142
+ });
143
+ }
144
+ function uuid() {
145
+ return Math.random().toString(36).slice(2, 7);
146
+ }
147
+ var tagWhiteList = [
148
+ "page",
149
+ "wrapper",
150
+ "block",
151
+ "button",
152
+ "camera",
153
+ "checkbox-group",
154
+ "checkbox",
155
+ "cover-image",
156
+ "cover-view",
157
+ "form",
158
+ "icon",
159
+ "image",
160
+ "input",
161
+ "keyboard-accessory",
162
+ "label",
163
+ "map",
164
+ "movable-area",
165
+ "movable-view",
166
+ "navigation-bar",
167
+ "navigator",
168
+ "open-data",
169
+ "page-meta",
170
+ "picker-view-column",
171
+ "picker-view",
172
+ "picker",
173
+ "progress",
174
+ "radio-group",
175
+ "radio",
176
+ "rich-text",
177
+ "root-portal",
178
+ "scroll-view",
179
+ "slider",
180
+ "swiper-item",
181
+ "swiper",
182
+ "switch",
183
+ "template",
184
+ "text",
185
+ "textarea",
186
+ "video",
187
+ "view",
188
+ "web-view"
189
+ ];
190
+ function __resetAssets() {
191
+ for (const k of Object.keys(assetsMap)) delete assetsMap[k];
192
+ }
193
+
194
+ // ../../dimina/fe/packages/compiler/src/common/npm-resolver.js
195
+ import fs2 from "node:fs";
196
+ import path3 from "node:path";
197
+ var NpmResolver = class {
198
+ constructor(workPath) {
199
+ this.workPath = workPath;
200
+ this.miniprogramNpmCache = /* @__PURE__ */ new Map();
201
+ this.packageCache = /* @__PURE__ */ new Map();
202
+ }
203
+ /**
204
+ * 解析组件路径,支持 npm 包组件
205
+ * @param {string} componentPath 组件路径
206
+ * @param {string} pageFilePath 页面文件路径
207
+ * @returns {string} 解析后的组件路径
208
+ */
209
+ resolveComponentPath(componentPath, pageFilePath) {
210
+ if (componentPath.startsWith("./") || componentPath.startsWith("../") || componentPath.startsWith("/")) {
211
+ return this.resolveRelativePath(componentPath, pageFilePath);
212
+ }
213
+ const npmPath = this.resolveNpmComponent(componentPath, pageFilePath);
214
+ if (npmPath) {
215
+ return npmPath;
216
+ }
217
+ return this.resolveRelativePath(componentPath, pageFilePath);
218
+ }
219
+ /**
220
+ * 解析相对路径组件
221
+ * @param {string} componentPath 组件路径
222
+ * @param {string} pageFilePath 页面文件路径
223
+ * @returns {string} 解析后的路径
224
+ */
225
+ resolveRelativePath(componentPath, pageFilePath) {
226
+ return toMiniProgramModuleId(
227
+ resolveMiniProgramPath(this.workPath, pageFilePath, componentPath),
228
+ this.workPath
229
+ );
230
+ }
231
+ /**
232
+ * 解析 npm 组件
233
+ * @param {string} componentName 组件名称
234
+ * @param {string} pageFilePath 页面文件路径
235
+ * @returns {string|null} 解析后的组件路径,如果找不到返回 null
236
+ */
237
+ resolveNpmComponent(componentName, pageFilePath) {
238
+ const searchPaths = this.generateSearchPaths(pageFilePath);
239
+ for (const searchPath of searchPaths) {
240
+ const componentPath = this.findComponentInMiniprogramNpm(componentName, searchPath);
241
+ if (componentPath) {
242
+ return componentPath;
243
+ }
244
+ }
245
+ return null;
246
+ }
247
+ /**
248
+ * 解析脚本模块路径,支持微信小程序 npm 逐级寻址和 package.json 入口
249
+ * @param {string} specifier 模块导入路径
250
+ * @param {string} modulePath 当前模块绝对文件路径
251
+ * @param {(moduleId: string) => string | null} resolveExistingModuleId 解析真实存在模块的回调
252
+ * @returns {string|null} 解析后的模块 id
253
+ */
254
+ resolveScriptModule(specifier, modulePath, resolveExistingModuleId) {
255
+ if (!specifier || !resolveExistingModuleId) {
256
+ return null;
257
+ }
258
+ for (const searchPath of this.generateSearchPaths(modulePath)) {
259
+ const moduleId = this.normalizeModuleId(`/${searchPath}/${specifier}`);
260
+ const resolvedModuleId = resolveExistingModuleId(moduleId);
261
+ if (resolvedModuleId) {
262
+ return resolvedModuleId;
263
+ }
264
+ }
265
+ return null;
266
+ }
267
+ /**
268
+ * 生成 miniprogram_npm 搜索路径
269
+ * 按照微信小程序的寻址顺序生成搜索路径
270
+ * @param {string} pageFilePath 页面文件路径
271
+ * @returns {string[]} 搜索路径数组
272
+ */
273
+ generateSearchPaths(pageFilePath) {
274
+ const relativePath = getRelativePosixPath(pageFilePath, this.workPath);
275
+ const pathParts = relativePath.split("/").slice(0, -1);
276
+ const searchPaths = [];
277
+ for (let i = pathParts.length; i >= 0; i--) {
278
+ const currentPath = pathParts.slice(0, i).join("/");
279
+ const miniprogramNpmPath = currentPath ? `${currentPath}/miniprogram_npm` : "miniprogram_npm";
280
+ searchPaths.push(miniprogramNpmPath);
281
+ }
282
+ return searchPaths;
283
+ }
284
+ /**
285
+ * 在指定的 miniprogram_npm 目录中查找组件
286
+ * @param {string} componentName 组件名称
287
+ * @param {string} miniprogramNpmPath miniprogram_npm 路径
288
+ * @returns {string|null} 组件路径,如果找不到返回 null
289
+ */
290
+ findComponentInMiniprogramNpm(componentName, miniprogramNpmPath) {
291
+ const fullMiniprogramNpmPath = path3.join(this.workPath, miniprogramNpmPath);
292
+ if (!fs2.existsSync(fullMiniprogramNpmPath)) {
293
+ return null;
294
+ }
295
+ const cacheKey = `${miniprogramNpmPath}/${componentName}`;
296
+ if (this.miniprogramNpmCache.has(cacheKey)) {
297
+ return this.miniprogramNpmCache.get(cacheKey);
298
+ }
299
+ const candidatePaths = [
300
+ componentName,
301
+ `${componentName}/index`
302
+ ];
303
+ for (const candidatePath of candidatePaths) {
304
+ const componentDir = path3.join(fullMiniprogramNpmPath, candidatePath);
305
+ if (this.isValidComponent(componentDir)) {
306
+ const resolvedPath = `/${miniprogramNpmPath}/${candidatePath}`.replace(/\/+/g, "/");
307
+ this.miniprogramNpmCache.set(cacheKey, resolvedPath);
308
+ return resolvedPath;
309
+ }
310
+ }
311
+ this.miniprogramNpmCache.set(cacheKey, null);
312
+ return null;
313
+ }
314
+ normalizeModuleId(moduleId) {
315
+ let normalized = moduleId.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
316
+ if (!normalized.startsWith("/")) {
317
+ normalized = `/${normalized}`;
318
+ }
319
+ return normalized;
320
+ }
321
+ /**
322
+ * 检查是否为有效的组件
323
+ * @param {string} componentPath 组件路径
324
+ * @returns {boolean} 是否为有效组件
325
+ */
326
+ isValidComponent(componentPath) {
327
+ const requiredFiles = [".json", ".js"];
328
+ const hasRequiredFiles = requiredFiles.some((ext) => {
329
+ return fs2.existsSync(`${componentPath}${ext}`);
330
+ });
331
+ if (!hasRequiredFiles) {
332
+ const indexFiles = requiredFiles.some((ext) => {
333
+ return fs2.existsSync(path3.join(componentPath, `index${ext}`));
334
+ });
335
+ if (!indexFiles) {
336
+ return false;
337
+ }
338
+ const indexJsonFile = path3.join(componentPath, "index.json");
339
+ if (fs2.existsSync(indexJsonFile)) {
340
+ try {
341
+ const config = JSON.parse(fs2.readFileSync(indexJsonFile, "utf-8"));
342
+ return config.component === true;
343
+ } catch (e) {
344
+ return false;
345
+ }
346
+ }
347
+ return true;
348
+ }
349
+ const jsonFile = `${componentPath}.json`;
350
+ if (fs2.existsSync(jsonFile)) {
351
+ try {
352
+ const config = JSON.parse(fs2.readFileSync(jsonFile, "utf-8"));
353
+ return config.component === true;
354
+ } catch (e) {
355
+ return false;
356
+ }
357
+ }
358
+ return true;
359
+ }
360
+ /**
361
+ * 获取 npm 包信息
362
+ * @param {string} packageName 包名
363
+ * @param {string} searchPath 搜索路径
364
+ * @returns {object|null} 包信息,如果找不到返回 null
365
+ */
366
+ getPackageInfo(packageName, searchPath) {
367
+ const cacheKey = `${searchPath}/${packageName}`;
368
+ if (this.packageCache.has(cacheKey)) {
369
+ return this.packageCache.get(cacheKey);
370
+ }
371
+ const packageJsonPath = path3.join(this.workPath, searchPath, packageName, "package.json");
372
+ if (!fs2.existsSync(packageJsonPath)) {
373
+ this.packageCache.set(cacheKey, null);
374
+ return null;
375
+ }
376
+ try {
377
+ const packageInfo = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
378
+ this.packageCache.set(cacheKey, packageInfo);
379
+ return packageInfo;
380
+ } catch (e) {
381
+ this.packageCache.set(cacheKey, null);
382
+ return null;
383
+ }
384
+ }
385
+ /**
386
+ * 清除缓存
387
+ */
388
+ clearCache() {
389
+ this.miniprogramNpmCache.clear();
390
+ this.packageCache.clear();
391
+ }
392
+ };
393
+
394
+ // ../../dimina/fe/packages/compiler/src/env.js
395
+ var pathInfo = {};
396
+ var configInfo = {};
397
+ var npmResolver = null;
398
+ var DEFAULT_TEMPLATE_EXTS = [".wxml", ".ddml"];
399
+ var DEFAULT_STYLE_EXTS = [".wxss", ".ddss", ".less", ".scss", ".sass"];
400
+ var DEFAULT_VIEW_SCRIPT_EXTS = [".wxs"];
401
+ var DEFAULT_VIEW_SCRIPT_TAGS = ["wxs", "dds"];
402
+ var RESERVED_EXTS = /* @__PURE__ */ new Set([
403
+ ...DEFAULT_TEMPLATE_EXTS,
404
+ ...DEFAULT_STYLE_EXTS,
405
+ ...DEFAULT_VIEW_SCRIPT_EXTS,
406
+ ".js",
407
+ ".ts",
408
+ ".json"
409
+ ]);
410
+ var compilerOptions = normalizeFileTypes();
411
+ function normalizeExt(raw) {
412
+ if (typeof raw !== "string") {
413
+ return null;
414
+ }
415
+ const v = raw.trim().toLowerCase().replace(/^\.+/, "");
416
+ if (!/^[a-z0-9_-]+$/.test(v)) {
417
+ return null;
418
+ }
419
+ return `.${v}`;
420
+ }
421
+ function normalizeTag(raw) {
422
+ if (typeof raw !== "string") {
423
+ return null;
424
+ }
425
+ const v = raw.trim().toLowerCase().replace(/^\.+/, "");
426
+ if (!/^[a-z][a-z0-9_-]*$/.test(v)) {
427
+ return null;
428
+ }
429
+ return v;
430
+ }
431
+ function mergeUnique(builtins, custom, normalizer, reserved) {
432
+ const out = [...builtins];
433
+ const seen = new Set(builtins);
434
+ if (Array.isArray(custom)) {
435
+ for (const raw of custom) {
436
+ const n = normalizer(raw);
437
+ if (n && !seen.has(n) && !reserved?.has(n)) {
438
+ seen.add(n);
439
+ out.push(n);
440
+ }
441
+ }
442
+ }
443
+ return out;
444
+ }
445
+ function normalizeFileTypes(fileTypes = {}) {
446
+ const ft = fileTypes || {};
447
+ return {
448
+ templateExts: mergeUnique(DEFAULT_TEMPLATE_EXTS, ft.template, normalizeExt, RESERVED_EXTS),
449
+ styleExts: mergeUnique(DEFAULT_STYLE_EXTS, ft.style, normalizeExt, RESERVED_EXTS),
450
+ viewScriptExts: mergeUnique(DEFAULT_VIEW_SCRIPT_EXTS, ft.viewScript, normalizeExt, RESERVED_EXTS),
451
+ viewScriptTags: mergeUnique(DEFAULT_VIEW_SCRIPT_TAGS, ft.viewScript, normalizeTag)
452
+ };
453
+ }
454
+ function resetStoreInfo(opts) {
455
+ pathInfo = opts.pathInfo;
456
+ configInfo = opts.configInfo;
457
+ compilerOptions = opts.compilerOptions || normalizeFileTypes();
458
+ if (pathInfo.workPath) {
459
+ npmResolver = new NpmResolver(pathInfo.workPath);
460
+ }
461
+ }
462
+ function getTemplateExts() {
463
+ return compilerOptions.templateExts;
464
+ }
465
+ function getStyleExts() {
466
+ return compilerOptions.styleExts;
467
+ }
468
+ function getViewScriptExts() {
469
+ return compilerOptions.viewScriptExts;
470
+ }
471
+ function getViewScriptTags() {
472
+ return compilerOptions.viewScriptTags;
473
+ }
474
+ function getContentByPath(path6) {
475
+ return fs3.readFileSync(path6, { encoding: "utf-8" });
476
+ }
477
+ function resolveAppAlias(src) {
478
+ const resolveAlias = configInfo.appInfo?.resolveAlias;
479
+ if (!resolveAlias || typeof src !== "string") {
480
+ return null;
481
+ }
482
+ for (const [alias, target] of Object.entries(resolveAlias)) {
483
+ if (alias.endsWith("/*") && target.endsWith("/*")) {
484
+ const aliasPrefix = alias.slice(0, -1);
485
+ const targetPrefix = target.slice(0, -1);
486
+ if (src.startsWith(aliasPrefix)) {
487
+ return src.replace(aliasPrefix, targetPrefix);
488
+ }
489
+ } else if (src === alias) {
490
+ return target;
491
+ }
492
+ }
493
+ return null;
494
+ }
495
+ function getTargetPath() {
496
+ return pathInfo.targetPath;
497
+ }
498
+ function getComponent(src) {
499
+ return configInfo.componentInfo[src];
500
+ }
501
+ function getAppConfigInfo() {
502
+ return configInfo.appInfo;
503
+ }
504
+ function getWorkPath() {
505
+ return pathInfo.workPath;
506
+ }
507
+ function getNpmResolver() {
508
+ return npmResolver;
509
+ }
510
+ function getAppId() {
511
+ return configInfo.projectInfo.appid;
512
+ }
513
+ function getAppName() {
514
+ if (configInfo.projectInfo.projectname) {
515
+ return decodeURIComponent(configInfo.projectInfo.projectname);
516
+ }
517
+ return getAppId();
518
+ }
519
+
520
+ // ../../dimina/fe/packages/compiler/src/core/logic-compiler.js
521
+ import fs4 from "node:fs";
522
+ import { resolve, sep } from "node:path";
523
+
524
+ // src/shims/worker_threads.js
525
+ var isMainThread = true;
526
+ var parentPort = null;
527
+
528
+ // ../../dimina/fe/packages/compiler/src/core/logic-compiler.js
529
+ import { parseSync } from "oxc-parser";
530
+ import { walk } from "oxc-walker";
531
+ import MagicString from "magic-string";
532
+ import { transform } from "esbuild";
533
+
534
+ // ../../dimina/fe/packages/compiler/src/common/compatibility.js
535
+ import { Parser } from "htmlparser2";
536
+
537
+ // ../../dimina/fe/packages/compiler/src/common/compatibility-reference.js
538
+ var supportedBuiltinComponents = [
539
+ "block",
540
+ "button",
541
+ "canvas",
542
+ "checkbox",
543
+ "checkbox-group",
544
+ "cover-image",
545
+ "cover-view",
546
+ "form",
547
+ "icon",
548
+ "image",
549
+ "input",
550
+ "label",
551
+ "movable-area",
552
+ "movable-view",
553
+ "navigation-bar",
554
+ "navigator",
555
+ "picker",
556
+ "picker-view",
557
+ "picker-view-column",
558
+ "progress",
559
+ "radio",
560
+ "radio-group",
561
+ "rich-text",
562
+ "scroll-view",
563
+ "slider",
564
+ "slot",
565
+ "swiper",
566
+ "swiper-item",
567
+ "switch",
568
+ "template",
569
+ "text",
570
+ "textarea",
571
+ "video",
572
+ "view",
573
+ "web-view",
574
+ "wxs",
575
+ "include",
576
+ "import"
577
+ ];
578
+ var supportedWxApis = [
579
+ "env",
580
+ "canIUse",
581
+ "getUpdateManager",
582
+ "openSystemBluetoothSetting",
583
+ "getWindowInfo",
584
+ "getSystemSetting",
585
+ "getSystemInfoSync",
586
+ "getSystemInfoAsync",
587
+ "getSystemInfo",
588
+ "reLaunch",
589
+ "redirectTo",
590
+ "navigateTo",
591
+ "navigateBack",
592
+ "showToast",
593
+ "showModal",
594
+ "showLoading",
595
+ "showActionSheet",
596
+ "hideToast",
597
+ "hideLoading",
598
+ "setNavigationBarTitle",
599
+ "setNavigationBarColor",
600
+ "pageScrollTo",
601
+ "getMenuButtonBoundingClientRect",
602
+ "createAnimation",
603
+ "createCanvasContext",
604
+ "createOffscreenCanvas",
605
+ "canvasToTempFilePath",
606
+ "createSelectorQuery",
607
+ "createIntersectionObserver",
608
+ "request",
609
+ "downloadFile",
610
+ "uploadFile",
611
+ "setStorageSync",
612
+ "getStorageSync",
613
+ "removeStorageSync",
614
+ "clearStorageSync",
615
+ "setStorage",
616
+ "getStorage",
617
+ "removeStorage",
618
+ "clearStorage",
619
+ "getStorageInfoSync",
620
+ "getStorageInfo",
621
+ "saveImageToPhotosAlbum",
622
+ "previewImage",
623
+ "compressImage",
624
+ "chooseImage",
625
+ "chooseMedia",
626
+ "chooseContact",
627
+ "addPhoneContact",
628
+ "setClipboardData",
629
+ "getClipboardData",
630
+ "vibrateShort",
631
+ "vibrateLong",
632
+ "hideKeyboard",
633
+ "getNetworkType",
634
+ "makePhoneCall",
635
+ "extBridge",
636
+ "extOnBridge",
637
+ "extOffBridge"
638
+ ];
639
+
640
+ // ../../dimina/fe/packages/compiler/src/common/compatibility.js
641
+ var cachedReference = null;
642
+ var warnedItems = /* @__PURE__ */ new Set();
643
+ function loadReference() {
644
+ if (cachedReference) {
645
+ return cachedReference;
646
+ }
647
+ cachedReference = {
648
+ supportedBuiltinComponents: new Set(supportedBuiltinComponents),
649
+ supportedWxApis: new Set(supportedWxApis)
650
+ };
651
+ return cachedReference;
652
+ }
653
+ function getWxMemberName(node) {
654
+ if (node?.type !== "MemberExpression") {
655
+ return null;
656
+ }
657
+ if (node.object?.type !== "Identifier" || node.object.name !== "wx") {
658
+ return null;
659
+ }
660
+ if (!node.computed && node.property?.type === "Identifier") {
661
+ return node.property.name;
662
+ }
663
+ if (node.computed && (node.property?.type === "StringLiteral" || node.property?.type === "Literal") && typeof node.property.value === "string") {
664
+ return node.property.value;
665
+ }
666
+ return null;
667
+ }
668
+ function warnUnsupportedWxApi(apiName, filePath, line) {
669
+ const { supportedWxApis: supportedWxApis2 } = loadReference();
670
+ if (!apiName || supportedWxApis2.has(apiName)) {
671
+ return;
672
+ }
673
+ const location = formatLocation(filePath, line);
674
+ warnOnce("api", apiName, location, `[compat] Unsupported wx API: wx.${apiName}${location}`);
675
+ }
676
+ function warnUnsupportedComponent(tagName, filePath, line) {
677
+ const { supportedBuiltinComponents: supportedBuiltinComponents2 } = loadReference();
678
+ if (!tagName || supportedBuiltinComponents2.has(tagName) || getViewScriptTags().includes(tagName)) {
679
+ return;
680
+ }
681
+ const location = formatLocation(filePath, line);
682
+ warnOnce("component", tagName, location, `[compat] Unsupported or undeclared component: <${tagName}>${location}`);
683
+ }
684
+ function checkTemplateCompatibility(content, filePath, components = {}) {
685
+ let parser;
686
+ parser = new Parser(
687
+ {
688
+ onopentag(tagName) {
689
+ if (components?.[tagName]) {
690
+ return;
691
+ }
692
+ const line = getLineByIndex(content, parser.startIndex);
693
+ warnUnsupportedComponent(tagName, filePath, line);
694
+ },
695
+ onerror(error) {
696
+ console.warn("[compat]", `Failed to parse template for compatibility diagnostics: ${filePath}`, error.message);
697
+ }
698
+ },
699
+ {
700
+ xmlMode: true,
701
+ lowerCaseTags: false,
702
+ lowerCaseAttributeNames: false,
703
+ withStartIndices: true
704
+ }
705
+ );
706
+ parser.write(content);
707
+ parser.end();
708
+ }
709
+ function getLineByIndex(content, index) {
710
+ if (typeof index !== "number" || index < 0) {
711
+ return null;
712
+ }
713
+ let line = 1;
714
+ for (let i = 0; i < index; i++) {
715
+ if (content.charCodeAt(i) === 10) {
716
+ line++;
717
+ }
718
+ }
719
+ return line;
720
+ }
721
+ function formatLocation(filePath, line) {
722
+ if (!filePath) {
723
+ return "";
724
+ }
725
+ return line ? ` (${filePath}:${line})` : ` (${filePath})`;
726
+ }
727
+ function warnOnce(type, name, location, message) {
728
+ const key = `${type}:${name}:${location}`;
729
+ if (warnedItems.has(key)) {
730
+ return;
731
+ }
732
+ warnedItems.add(key);
733
+ console.warn(message);
734
+ }
735
+
736
+ // ../../dimina/fe/packages/compiler/src/core/sourcemap.js
737
+ import { SourceMapConsumer, SourceMapGenerator } from "source-map-js";
738
+ function wrapModDefine(module) {
739
+ const code = module.code.endsWith("\n") ? module.code : module.code + "\n";
740
+ const extraLine = module.extraInfoCode || "";
741
+ const header = `modDefine('${module.path}', function(require, module, exports) {
742
+ ${extraLine}`;
743
+ const footer = "});\n";
744
+ return { header, code, footer };
745
+ }
746
+ function mergeSourcemap(compileRes2) {
747
+ const smg = new SourceMapGenerator({ file: "logic.js" });
748
+ let bundleCode = "";
749
+ let lineOffset = 0;
750
+ for (const module of compileRes2) {
751
+ const { header, code, footer } = wrapModDefine(module);
752
+ bundleCode += header;
753
+ const headerLineCount = header.split("\n").length - 1;
754
+ lineOffset += headerLineCount;
755
+ if (module.map) {
756
+ const moduleMap = JSON.parse(module.map);
757
+ const smc = new SourceMapConsumer(moduleMap);
758
+ smc.eachMapping((mapping) => {
759
+ if (mapping.source == null) return;
760
+ smg.addMapping({
761
+ generated: {
762
+ line: mapping.generatedLine + lineOffset,
763
+ column: mapping.generatedColumn
764
+ },
765
+ original: {
766
+ line: mapping.originalLine,
767
+ column: mapping.originalColumn
768
+ },
769
+ source: mapping.source,
770
+ name: mapping.name
771
+ });
772
+ });
773
+ if (moduleMap.sourcesContent) {
774
+ moduleMap.sources.forEach((src, i) => {
775
+ smg.setSourceContent(src, moduleMap.sourcesContent[i]);
776
+ });
777
+ }
778
+ }
779
+ bundleCode += code;
780
+ lineOffset += code.split("\n").length - 1;
781
+ bundleCode += footer;
782
+ lineOffset += footer.split("\n").length - 1;
783
+ }
784
+ return { bundleCode, sourcemap: smg.toString() };
785
+ }
786
+ function remapSourcemap(nextMap, prevMap) {
787
+ if (!nextMap) {
788
+ return prevMap;
789
+ }
790
+ if (!prevMap) {
791
+ return nextMap;
792
+ }
793
+ const nextMapObj = typeof nextMap === "string" ? JSON.parse(nextMap) : nextMap;
794
+ const prevMapObj = typeof prevMap === "string" ? JSON.parse(prevMap) : prevMap;
795
+ const smg = new SourceMapGenerator({ file: nextMapObj.file || prevMapObj.file || "" });
796
+ const prevSmc = new SourceMapConsumer(prevMapObj);
797
+ const nextSmc = new SourceMapConsumer(nextMapObj);
798
+ nextSmc.eachMapping((mapping) => {
799
+ if (mapping.source == null || mapping.originalLine == null || mapping.originalColumn == null) {
800
+ return;
801
+ }
802
+ const original = prevSmc.originalPositionFor({
803
+ line: mapping.originalLine,
804
+ column: mapping.originalColumn
805
+ });
806
+ if (original.source == null || original.line == null || original.column == null) {
807
+ return;
808
+ }
809
+ smg.addMapping({
810
+ generated: {
811
+ line: mapping.generatedLine,
812
+ column: mapping.generatedColumn
813
+ },
814
+ original: {
815
+ line: original.line,
816
+ column: original.column
817
+ },
818
+ source: original.source,
819
+ name: original.name || mapping.name
820
+ });
821
+ });
822
+ if (prevMapObj.sourcesContent) {
823
+ prevMapObj.sources.forEach((src, i) => {
824
+ smg.setSourceContent(src, prevMapObj.sourcesContent[i]);
825
+ });
826
+ }
827
+ return smg.toString();
828
+ }
829
+
830
+ // ../../dimina/fe/packages/compiler/src/core/logic-compiler.js
831
+ var processedModules = /* @__PURE__ */ new Set();
832
+ var enableSourcemap = false;
833
+ if (!isMainThread) {
834
+ parentPort.on("message", async ({ pages, storeInfo: storeInfo2, sourcemap }) => {
835
+ try {
836
+ resetStoreInfo(storeInfo2);
837
+ enableSourcemap = !!sourcemap;
838
+ const progress = {
839
+ _completedTasks: 0,
840
+ get completedTasks() {
841
+ return this._completedTasks;
842
+ },
843
+ set completedTasks(value) {
844
+ this._completedTasks = value;
845
+ parentPort.postMessage({ completedTasks: this.completedTasks });
846
+ }
847
+ };
848
+ const mainCompileRes = await compileJS(pages.mainPages, null, null, progress);
849
+ for (const [root, subPages] of Object.entries(pages.subPages)) {
850
+ try {
851
+ const subCompileRes = await compileJS(
852
+ subPages.info,
853
+ root,
854
+ subPages.independent ? [] : mainCompileRes,
855
+ progress
856
+ );
857
+ await writeCompileRes(subCompileRes, root);
858
+ } catch (error) {
859
+ throw new Error(`Error processing subpackage ${root}: ${error.message}
860
+ ${error.stack}`);
861
+ }
862
+ }
863
+ await writeCompileRes(mainCompileRes, null);
864
+ processedModules.clear();
865
+ parentPort.postMessage({ success: true });
866
+ } catch (error) {
867
+ processedModules.clear();
868
+ parentPort.postMessage({
869
+ success: false,
870
+ error: {
871
+ message: error.message,
872
+ stack: error.stack,
873
+ name: error.name
874
+ }
875
+ });
876
+ }
877
+ });
878
+ }
879
+ async function writeCompileRes(compileRes2, root) {
880
+ const outputDir = root ? `${getTargetPath()}/${root}` : `${getTargetPath()}/main`;
881
+ if (!fs4.existsSync(outputDir)) {
882
+ fs4.mkdirSync(outputDir, { recursive: true });
883
+ }
884
+ if (enableSourcemap) {
885
+ const { bundleCode, sourcemap } = mergeSourcemap(compileRes2);
886
+ const sourcemapFileName = "logic.js.map";
887
+ fs4.writeFileSync(`${outputDir}/logic.js`, `${bundleCode}//# sourceMappingURL=${sourcemapFileName}
888
+ `);
889
+ fs4.writeFileSync(`${outputDir}/${sourcemapFileName}`, sourcemap);
890
+ } else {
891
+ let mergeCode = "";
892
+ for (const module of compileRes2) {
893
+ const amdFormat = `modDefine('${module.path}', function(require, module, exports) {
894
+ ${module.code}
895
+ });`;
896
+ const { code: minifiedCode } = await transform(amdFormat, {
897
+ minify: true,
898
+ target: ["es2023"],
899
+ // quickjs 支持版本
900
+ platform: "neutral"
901
+ });
902
+ mergeCode += minifiedCode;
903
+ }
904
+ fs4.writeFileSync(`${outputDir}/logic.js`, mergeCode);
905
+ }
906
+ }
907
+ async function compileJS(pages, root, mainCompileRes, progress) {
908
+ const compileRes2 = [];
909
+ if (!root) {
910
+ await buildJSByPath(root, { path: "app" }, compileRes2, mainCompileRes, false);
911
+ }
912
+ for (const page of pages) {
913
+ await buildJSByPath(root, page, compileRes2, mainCompileRes, true);
914
+ progress.completedTasks++;
915
+ }
916
+ return compileRes2;
917
+ }
918
+ async function buildJSByPath(packageName, module, compileRes2, mainCompileRes, addExtra, depthChain = [], putMain = false) {
919
+ const currentPath = module.path;
920
+ if (depthChain.includes(currentPath)) {
921
+ console.warn("[logic]", `\u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
922
+ return;
923
+ }
924
+ if (depthChain.length > 20) {
925
+ console.warn("[logic]", `\u68C0\u6D4B\u5230\u6DF1\u5EA6\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
926
+ return;
927
+ }
928
+ depthChain = [...depthChain, currentPath];
929
+ if (!module.path) {
930
+ return;
931
+ }
932
+ if (hasCompileInfo(module.path, compileRes2, mainCompileRes)) {
933
+ return;
934
+ }
935
+ const compileInfo = {
936
+ path: module.path,
937
+ code: "",
938
+ sourceFile: null
939
+ };
940
+ const src = module.path.startsWith("/") ? module.path : `/${module.path}`;
941
+ const modulePath = getJSAbsolutePath(src);
942
+ if (!modulePath) {
943
+ console.warn("[logic]", `\u627E\u4E0D\u5230\u6A21\u5757\u6587\u4EF6: ${src}`);
944
+ return;
945
+ }
946
+ const diagnosticSource = modulePath.startsWith(getWorkPath()) ? modulePath.slice(getWorkPath().length) : src;
947
+ const sourceCode = getContentByPath(modulePath);
948
+ if (!sourceCode) {
949
+ console.warn("[logic]", `\u65E0\u6CD5\u8BFB\u53D6\u6A21\u5757\u6587\u4EF6: ${modulePath}`);
950
+ return;
951
+ }
952
+ const isTypeScript = modulePath.endsWith(".ts");
953
+ if (enableSourcemap) {
954
+ const workPath = getWorkPath();
955
+ compileInfo.sourceFile = modulePath.startsWith(workPath) ? modulePath.slice(workPath.length) : src;
956
+ }
957
+ const parseResult = parseSync(modulePath, sourceCode, {
958
+ sourceType: "module",
959
+ lang: isTypeScript ? "ts" : "js"
960
+ });
961
+ const ast = parseResult.program;
962
+ const s = new MagicString(sourceCode);
963
+ const extraInfo = {
964
+ path: module.path
965
+ };
966
+ if (module.component) {
967
+ extraInfo.component = true;
968
+ }
969
+ if (module.usingComponents) {
970
+ const componentsObj = {};
971
+ const allSubPackages = getAppConfigInfo().subPackages;
972
+ for (const [name, path6] of Object.entries(module.usingComponents)) {
973
+ let toMainSubPackage = true;
974
+ if (packageName) {
975
+ const normalizedPath = path6.startsWith("/") ? path6.substring(1) : path6;
976
+ for (const subPackage of allSubPackages) {
977
+ if (normalizedPath.startsWith(`${subPackage.root}/`)) {
978
+ toMainSubPackage = false;
979
+ break;
980
+ }
981
+ }
982
+ } else {
983
+ toMainSubPackage = false;
984
+ }
985
+ const componentModule = getComponent(path6);
986
+ if (!componentModule) {
987
+ continue;
988
+ }
989
+ await buildJSByPath(packageName, componentModule, compileRes2, mainCompileRes, true, depthChain, putMain || toMainSubPackage);
990
+ componentsObj[name] = path6;
991
+ }
992
+ extraInfo.usingComponents = componentsObj;
993
+ }
994
+ if (addExtra) {
995
+ const extraInfoCode = `globalThis.__extraInfo = ${JSON.stringify(extraInfo)};
996
+ `;
997
+ if (enableSourcemap) {
998
+ compileInfo.extraInfoCode = extraInfoCode;
999
+ } else {
1000
+ s.prepend(extraInfoCode);
1001
+ }
1002
+ }
1003
+ if (putMain) {
1004
+ mainCompileRes.push(compileInfo);
1005
+ } else {
1006
+ compileRes2.push(compileInfo);
1007
+ }
1008
+ const pathReplacements = [];
1009
+ const dependenciesToProcess = [];
1010
+ walk(ast, {
1011
+ enter(node, parent) {
1012
+ const wxMemberName = getWxMemberName(node);
1013
+ if (wxMemberName) {
1014
+ warnUnsupportedWxApi(
1015
+ wxMemberName,
1016
+ compileInfo.sourceFile || diagnosticSource,
1017
+ node.loc?.start?.line || getLineByIndex2(sourceCode, node.start)
1018
+ );
1019
+ }
1020
+ if ((node.type === "StringLiteral" || node.type === "Literal") && isLocalAssetString(node.value)) {
1021
+ pathReplacements.push({
1022
+ start: node.start,
1023
+ end: node.end,
1024
+ newValue: collectAssets(getWorkPath(), modulePath, node.value, getTargetPath(), getAppId())
1025
+ });
1026
+ }
1027
+ if (node.type === "CallExpression") {
1028
+ const isRequire = node.callee.type === "Identifier" && node.callee.name === "require";
1029
+ const isRequireProperty = node.callee.type === "MemberExpression" && node.callee.object?.type === "Identifier" && node.callee.object?.name === "require";
1030
+ if ((isRequire || isRequireProperty) && node.arguments.length > 0 && (node.arguments[0].type === "StringLiteral" || node.arguments[0].type === "Literal")) {
1031
+ const arg = node.arguments[0];
1032
+ const requirePath = arg.value;
1033
+ if (requirePath) {
1034
+ const { id, shouldProcess } = resolveDependencyId(requirePath, modulePath, false);
1035
+ if (shouldProcess) {
1036
+ pathReplacements.push({
1037
+ start: arg.start,
1038
+ end: arg.end,
1039
+ newValue: id
1040
+ });
1041
+ if (!processedModules.has(packageName + id)) {
1042
+ dependenciesToProcess.push(id);
1043
+ }
1044
+ }
1045
+ }
1046
+ }
1047
+ }
1048
+ if (node.type === "ImportDeclaration") {
1049
+ const importPath = node.source.value;
1050
+ if (importPath) {
1051
+ const { id, shouldProcess } = resolveDependencyId(importPath, modulePath, true);
1052
+ if (shouldProcess) {
1053
+ pathReplacements.push({
1054
+ start: node.source.start,
1055
+ end: node.source.end,
1056
+ newValue: id
1057
+ });
1058
+ if (!processedModules.has(packageName + id)) {
1059
+ dependenciesToProcess.push(id);
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+ if (node.type === "TSImportEqualsDeclaration" && node.moduleReference?.type === "TSExternalModuleReference") {
1065
+ const importPathNode = node.moduleReference.expression;
1066
+ const importPath = importPathNode?.value;
1067
+ if (importPath) {
1068
+ const { id, shouldProcess } = resolveDependencyId(importPath, modulePath, false);
1069
+ if (shouldProcess) {
1070
+ pathReplacements.push({
1071
+ start: importPathNode.start,
1072
+ end: importPathNode.end,
1073
+ newValue: id
1074
+ });
1075
+ if (!processedModules.has(packageName + id)) {
1076
+ dependenciesToProcess.push(id);
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+ if ((node.type === "ExportAllDeclaration" || node.type === "ExportNamedDeclaration") && node.source) {
1082
+ const exportPath = node.source.value;
1083
+ if (exportPath) {
1084
+ const { id, shouldProcess } = resolveDependencyId(exportPath, modulePath, true);
1085
+ if (shouldProcess) {
1086
+ pathReplacements.push({
1087
+ start: node.source.start,
1088
+ end: node.source.end,
1089
+ newValue: id
1090
+ });
1091
+ if (!processedModules.has(packageName + id)) {
1092
+ dependenciesToProcess.push(id);
1093
+ }
1094
+ }
1095
+ }
1096
+ }
1097
+ }
1098
+ });
1099
+ for (const depId of dependenciesToProcess) {
1100
+ await buildJSByPath(packageName, { path: depId }, compileRes2, mainCompileRes, false, depthChain, putMain);
1101
+ }
1102
+ for (const replacement of pathReplacements.reverse()) {
1103
+ s.overwrite(replacement.start, replacement.end, `'${replacement.newValue}'`);
1104
+ }
1105
+ const modifiedCode = s.toString();
1106
+ let preEsbuildMap = null;
1107
+ if (enableSourcemap && compileInfo.sourceFile) {
1108
+ const generatedMap = JSON.parse(s.generateMap({
1109
+ file: compileInfo.sourceFile,
1110
+ source: compileInfo.sourceFile,
1111
+ includeContent: true,
1112
+ hires: true
1113
+ }).toString());
1114
+ generatedMap.file = compileInfo.sourceFile;
1115
+ generatedMap.sources = [compileInfo.sourceFile];
1116
+ generatedMap.sourcesContent = [sourceCode];
1117
+ preEsbuildMap = JSON.stringify(generatedMap);
1118
+ }
1119
+ try {
1120
+ const esbuildOpts = {
1121
+ format: "cjs",
1122
+ target: "es2020",
1123
+ platform: "neutral",
1124
+ loader: isTypeScript ? "ts" : "js"
1125
+ };
1126
+ if (enableSourcemap && compileInfo.sourceFile) {
1127
+ esbuildOpts.sourcemap = true;
1128
+ esbuildOpts.sourcefile = compileInfo.sourceFile;
1129
+ esbuildOpts.sourcesContent = true;
1130
+ }
1131
+ const esbuildResult = await transform(modifiedCode, esbuildOpts);
1132
+ if (enableSourcemap && esbuildResult.map) {
1133
+ compileInfo.map = preEsbuildMap ? remapSourcemap(esbuildResult.map, preEsbuildMap) : esbuildResult.map;
1134
+ }
1135
+ compileInfo.code = esbuildResult.code;
1136
+ } catch (error) {
1137
+ console.error(`[logic] esbuild \u8F6C\u6362\u5931\u8D25 ${modulePath}:`, error.message);
1138
+ compileInfo.code = modifiedCode;
1139
+ }
1140
+ processedModules.add(packageName + currentPath);
1141
+ }
1142
+ function isLocalAssetString(value) {
1143
+ return typeof value === "string" && !value.startsWith("http") && !value.startsWith("//") && (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) && /\.(?:png|jpe?g|gif|svg)(?:\?.*)?$/.test(value);
1144
+ }
1145
+ function getLineByIndex2(content, index) {
1146
+ if (typeof index !== "number" || index < 0) {
1147
+ return null;
1148
+ }
1149
+ let line = 1;
1150
+ for (let i = 0; i < index; i++) {
1151
+ if (content.charCodeAt(i) === 10) {
1152
+ line++;
1153
+ }
1154
+ }
1155
+ return line;
1156
+ }
1157
+ function getJSAbsolutePath(modulePath) {
1158
+ const workPath = getWorkPath();
1159
+ const resolvedModuleId = resolveModuleIdToExistingPath(modulePath);
1160
+ if (!resolvedModuleId) {
1161
+ return null;
1162
+ }
1163
+ const fileTypes = [".js", ".ts"];
1164
+ for (const ext of fileTypes) {
1165
+ const fullPath = `${workPath}${resolvedModuleId}${ext}`;
1166
+ if (fs4.existsSync(fullPath)) {
1167
+ return fullPath;
1168
+ }
1169
+ }
1170
+ return null;
1171
+ }
1172
+ function resolveDependencyId(specifier, modulePath, allowAbsolute) {
1173
+ if (!specifier) {
1174
+ return { id: specifier, shouldProcess: false };
1175
+ }
1176
+ if (specifier.startsWith("miniprogram_npm/")) {
1177
+ const npmModuleId = normalizeModuleId(`/${specifier}`);
1178
+ return {
1179
+ id: resolveModuleIdToExistingPath(npmModuleId) || npmModuleId,
1180
+ shouldProcess: true
1181
+ };
1182
+ }
1183
+ if (specifier.startsWith("./") || specifier.startsWith("../")) {
1184
+ return {
1185
+ id: resolveRelativeModuleId(specifier, modulePath),
1186
+ shouldProcess: true
1187
+ };
1188
+ }
1189
+ if (specifier.startsWith("/")) {
1190
+ return {
1191
+ id: allowAbsolute ? normalizeModuleId(specifier) : resolveRelativeModuleId(specifier, modulePath),
1192
+ shouldProcess: true
1193
+ };
1194
+ }
1195
+ const aliasResolved = resolveAppAlias(specifier);
1196
+ if (aliasResolved) {
1197
+ return {
1198
+ id: normalizeModuleId(aliasResolved),
1199
+ shouldProcess: true
1200
+ };
1201
+ }
1202
+ if (specifier.startsWith("@") || isBareModuleSpecifier(specifier)) {
1203
+ const npmModuleId = resolveNpmModuleId(specifier, modulePath);
1204
+ if (npmModuleId) {
1205
+ return {
1206
+ id: npmModuleId,
1207
+ shouldProcess: true
1208
+ };
1209
+ }
1210
+ const siblingModuleId = resolveBareSiblingModuleId(specifier, modulePath);
1211
+ return {
1212
+ id: siblingModuleId || specifier,
1213
+ shouldProcess: Boolean(siblingModuleId)
1214
+ };
1215
+ }
1216
+ return { id: specifier, shouldProcess: false };
1217
+ }
1218
+ function isBareModuleSpecifier(specifier) {
1219
+ return !specifier.startsWith(".") && !specifier.startsWith("/");
1220
+ }
1221
+ function resolveRelativeModuleId(specifier, modulePath) {
1222
+ const requireFullPath = resolve(modulePath, `../${specifier}`);
1223
+ const relativeId = requireFullPath.split(`${getWorkPath()}${sep}`)[1];
1224
+ return normalizeModuleId(relativeId);
1225
+ }
1226
+ function resolveBareSiblingModuleId(specifier, modulePath) {
1227
+ const siblingModuleId = resolveRelativeModuleId(`./${specifier}`, modulePath);
1228
+ return resolveModuleIdToExistingPath(siblingModuleId);
1229
+ }
1230
+ function normalizeModuleId(moduleId) {
1231
+ let normalized = moduleId.replace(/\.(js|ts)$/, "").replace(/\\/g, "/");
1232
+ if (!normalized.startsWith("/")) {
1233
+ normalized = `/${normalized}`;
1234
+ }
1235
+ return normalized;
1236
+ }
1237
+ function resolveNpmModuleId(specifier, modulePath) {
1238
+ const npmResolver2 = getNpmResolver();
1239
+ if (!npmResolver2) {
1240
+ return null;
1241
+ }
1242
+ return npmResolver2.resolveScriptModule(specifier, modulePath, resolveModuleIdToExistingPath);
1243
+ }
1244
+ function resolveModuleIdToExistingPath(moduleId) {
1245
+ const normalizedModuleId = normalizeModuleId(moduleId);
1246
+ const workPath = getWorkPath();
1247
+ for (const ext of [".js", ".ts"]) {
1248
+ if (fs4.existsSync(`${workPath}${normalizedModuleId}${ext}`)) {
1249
+ return normalizedModuleId;
1250
+ }
1251
+ }
1252
+ for (const ext of [".js", ".ts"]) {
1253
+ if (fs4.existsSync(`${workPath}${normalizedModuleId}/index${ext}`)) {
1254
+ return `${normalizedModuleId}/index`;
1255
+ }
1256
+ }
1257
+ const packageJsonPath = `${workPath}${normalizedModuleId}/package.json`;
1258
+ if (fs4.existsSync(packageJsonPath)) {
1259
+ try {
1260
+ const packageInfo = JSON.parse(fs4.readFileSync(packageJsonPath, "utf-8"));
1261
+ for (const entryField of ["miniprogram", "main"]) {
1262
+ if (typeof packageInfo[entryField] === "string" && packageInfo[entryField]) {
1263
+ const entryModuleId = normalizeModuleId(resolve(normalizedModuleId, packageInfo[entryField]));
1264
+ const resolvedEntry = resolveModuleIdToExistingPath(entryModuleId);
1265
+ if (resolvedEntry) {
1266
+ return resolvedEntry;
1267
+ }
1268
+ }
1269
+ }
1270
+ } catch (error) {
1271
+ console.warn("[logic]", `\u89E3\u6790 package.json \u5931\u8D25: ${packageJsonPath}`, error.message);
1272
+ }
1273
+ }
1274
+ return null;
1275
+ }
1276
+ function __resetLogicState() {
1277
+ processedModules.clear();
1278
+ }
1279
+ function __setEnableSourcemap(v) {
1280
+ enableSourcemap = !!v;
1281
+ }
1282
+
1283
+ // ../../dimina/fe/packages/compiler/src/core/view-compiler.js
1284
+ import fs5 from "node:fs";
1285
+ import path4 from "node:path";
1286
+ import { parseSync as parseSync3 } from "oxc-parser";
1287
+ import { walk as walk2 } from "oxc-walker";
1288
+ import MagicString2 from "magic-string";
1289
+ import { compileTemplate } from "@vue/compiler-sfc";
1290
+ import * as cheerio from "cheerio";
1291
+ import { transform as transform2 } from "esbuild";
1292
+ import * as htmlparser2 from "htmlparser2";
1293
+
1294
+ // ../../dimina/fe/packages/compiler/src/common/expression-parser.js
1295
+ import { parseSync as parseSync2 } from "oxc-parser";
1296
+ var KEYWORDS = /* @__PURE__ */ new Set([
1297
+ "true",
1298
+ "false",
1299
+ "null",
1300
+ "undefined",
1301
+ "NaN",
1302
+ "Infinity",
1303
+ "this",
1304
+ "arguments",
1305
+ "Array",
1306
+ "Object",
1307
+ "String",
1308
+ "Number",
1309
+ "Boolean",
1310
+ "Math",
1311
+ "Date",
1312
+ "RegExp",
1313
+ "Error",
1314
+ "JSON",
1315
+ "console",
1316
+ "window",
1317
+ "document",
1318
+ "parseInt",
1319
+ "parseFloat",
1320
+ "isNaN",
1321
+ "isFinite",
1322
+ "encodeURI",
1323
+ "encodeURIComponent",
1324
+ "decodeURI",
1325
+ "decodeURIComponent"
1326
+ ]);
1327
+ function extractDependencies(expression) {
1328
+ if (!expression || typeof expression !== "string") {
1329
+ return [];
1330
+ }
1331
+ const dependencies = /* @__PURE__ */ new Set();
1332
+ try {
1333
+ const code = `(${expression})`;
1334
+ const ast = parseSync2("expression.js", code, {
1335
+ sourceType: "module",
1336
+ lang: "js"
1337
+ }).program;
1338
+ visitExpressionAst(ast, null, dependencies);
1339
+ } catch (error) {
1340
+ console.warn("[expression-parser] AST \u89E3\u6790\u5931\u8D25\uFF0C\u8868\u8FBE\u5F0F:", expression, "\u9519\u8BEF:", error.message);
1341
+ return [];
1342
+ }
1343
+ return Array.from(dependencies);
1344
+ }
1345
+ function visitExpressionAst(node, parent, dependencies) {
1346
+ if (!node || typeof node !== "object") {
1347
+ return;
1348
+ }
1349
+ if (node.type === "Identifier") {
1350
+ collectIdentifier(node, parent, dependencies);
1351
+ return;
1352
+ }
1353
+ if (node.type === "MemberExpression") {
1354
+ let root = node.object;
1355
+ while (root?.type === "MemberExpression" || root?.type === "ChainExpression") {
1356
+ root = root.type === "ChainExpression" ? root.expression : root.object;
1357
+ }
1358
+ if (root?.type === "Identifier" && !KEYWORDS.has(root.name)) {
1359
+ dependencies.add(root.name);
1360
+ }
1361
+ return;
1362
+ }
1363
+ for (const [key, value] of Object.entries(node)) {
1364
+ if (key === "type" || key === "start" || key === "end" || key === "loc") {
1365
+ continue;
1366
+ }
1367
+ if (Array.isArray(value)) {
1368
+ for (const child of value) {
1369
+ visitExpressionAst(child, node, dependencies);
1370
+ }
1371
+ } else {
1372
+ visitExpressionAst(value, node, dependencies);
1373
+ }
1374
+ }
1375
+ }
1376
+ function collectIdentifier(node, parent, dependencies) {
1377
+ const name = node.name;
1378
+ if (KEYWORDS.has(name)) {
1379
+ return;
1380
+ }
1381
+ if (parent?.type === "MemberExpression" && parent.property === node && !parent.computed) {
1382
+ return;
1383
+ }
1384
+ if (parent?.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand) {
1385
+ return;
1386
+ }
1387
+ dependencies.add(name);
1388
+ }
1389
+ function parseExpression(expression) {
1390
+ if (!expression || typeof expression !== "string") {
1391
+ return {
1392
+ expression: "",
1393
+ dependencies: [],
1394
+ isSimple: true
1395
+ };
1396
+ }
1397
+ const dependencies = extractDependencies(expression);
1398
+ const isSimple = dependencies.length === 1 && expression.trim() === dependencies[0];
1399
+ return {
1400
+ expression: expression.trim(),
1401
+ dependencies,
1402
+ isSimple
1403
+ };
1404
+ }
1405
+ function parseBindings(bindings) {
1406
+ if (!bindings || typeof bindings !== "object") {
1407
+ return {};
1408
+ }
1409
+ const parsed = {};
1410
+ for (const [propName, expression] of Object.entries(bindings)) {
1411
+ parsed[propName] = parseExpression(expression);
1412
+ }
1413
+ return parsed;
1414
+ }
1415
+
1416
+ // ../../dimina/fe/packages/compiler/src/core/view-compiler.js
1417
+ function buildExtStripRegex(exts) {
1418
+ const alt = exts.map((e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
1419
+ return new RegExp(`(${alt})$`);
1420
+ }
1421
+ function stripViewScriptExt(p) {
1422
+ return p.replace(buildExtStripRegex(getViewScriptExts()), "");
1423
+ }
1424
+ function parseJs(code, filename = "view-compiler.js", sourceType = "module") {
1425
+ return parseSync3(filename, code, {
1426
+ sourceType,
1427
+ lang: "js"
1428
+ }).program;
1429
+ }
1430
+ function getProgramCode(code, ast) {
1431
+ const statement = ast.body?.[0];
1432
+ if (ast.body?.length === 1 && statement?.type === "ExpressionStatement") {
1433
+ return code.slice(statement.expression.start, statement.expression.end);
1434
+ }
1435
+ return code;
1436
+ }
1437
+ function isStringLiteral(node) {
1438
+ return node?.type === "StringLiteral" || node?.type === "Literal" && typeof node.value === "string";
1439
+ }
1440
+ function getStringLiteralRawValue(node) {
1441
+ if (!isStringLiteral(node)) {
1442
+ return "";
1443
+ }
1444
+ if (typeof node.raw === "string") {
1445
+ return node.raw.slice(1, -1);
1446
+ }
1447
+ return String(node.value);
1448
+ }
1449
+ function getSource(code, node) {
1450
+ return code.slice(node.start, node.end);
1451
+ }
1452
+ function applyCodeReplacements(source, replacements) {
1453
+ if (replacements.length === 0) {
1454
+ return source;
1455
+ }
1456
+ const selected = [];
1457
+ const byLargestRange = [...replacements].sort((a, b) => {
1458
+ const lengthDiff = b.end - b.start - (a.end - a.start);
1459
+ return lengthDiff || b.start - a.start;
1460
+ });
1461
+ for (const replacement of byLargestRange) {
1462
+ const overlaps = selected.some(
1463
+ (item) => replacement.start < item.end && item.start < replacement.end
1464
+ );
1465
+ if (!overlaps) {
1466
+ selected.push(replacement);
1467
+ }
1468
+ }
1469
+ const s = new MagicString2(source);
1470
+ for (const replacement of selected.sort((a, b) => b.start - a.start)) {
1471
+ if (replacement.type === "insert") {
1472
+ s.appendLeft(replacement.start, replacement.value);
1473
+ } else {
1474
+ s.overwrite(replacement.start, replacement.end, replacement.value);
1475
+ }
1476
+ }
1477
+ return s.toString();
1478
+ }
1479
+ function addOptionalChaining(expression) {
1480
+ if (!expression || typeof expression !== "string") {
1481
+ return expression;
1482
+ }
1483
+ try {
1484
+ const code = `(${expression})`;
1485
+ const ast = parseJs(code);
1486
+ const insertions = [];
1487
+ walk2(ast, {
1488
+ enter(node) {
1489
+ if (node.type !== "MemberExpression" || node.optional) {
1490
+ return;
1491
+ }
1492
+ if (node.computed) {
1493
+ const bracketIndex = code.lastIndexOf("[", node.property.start);
1494
+ if (bracketIndex >= 0) {
1495
+ insertions.push({
1496
+ type: "insert",
1497
+ start: bracketIndex,
1498
+ end: bracketIndex,
1499
+ value: "?."
1500
+ });
1501
+ }
1502
+ } else {
1503
+ const dotIndex = code.lastIndexOf(".", node.property.start);
1504
+ if (dotIndex >= 0) {
1505
+ insertions.push({
1506
+ type: "insert",
1507
+ start: dotIndex,
1508
+ end: dotIndex,
1509
+ value: "?"
1510
+ });
1511
+ }
1512
+ }
1513
+ }
1514
+ });
1515
+ return applyCodeReplacements(code, insertions).slice(1, -1);
1516
+ } catch (error) {
1517
+ return expression;
1518
+ }
1519
+ }
1520
+ function parseSafeBraceExp(exp) {
1521
+ return addOptionalChaining(parseBraceExp(exp));
1522
+ }
1523
+ function transformTextInterpolation(text) {
1524
+ if (!text || typeof text !== "string" || !isWrappedByBraces(text)) {
1525
+ return text;
1526
+ }
1527
+ return text.replace(braceRegex, (match, bracePart) => {
1528
+ if (!bracePart) {
1529
+ return match;
1530
+ }
1531
+ const matchResult = bracePart.match(noBraceRegex);
1532
+ if (!matchResult) {
1533
+ return match;
1534
+ }
1535
+ return `{{${addOptionalChaining(matchResult[1].trim())}}}`;
1536
+ });
1537
+ }
1538
+ var compileResCache = /* @__PURE__ */ new Map();
1539
+ var wxsModuleRegistry = /* @__PURE__ */ new Set();
1540
+ var wxsFilePathMap = /* @__PURE__ */ new Map();
1541
+ if (!isMainThread) {
1542
+ parentPort.on("message", async ({ pages, storeInfo: storeInfo2 }) => {
1543
+ try {
1544
+ resetStoreInfo(storeInfo2);
1545
+ const progress = {
1546
+ _completedTasks: 0,
1547
+ get completedTasks() {
1548
+ return this._completedTasks;
1549
+ },
1550
+ set completedTasks(value) {
1551
+ this._completedTasks = value;
1552
+ parentPort.postMessage({ completedTasks: this._completedTasks });
1553
+ }
1554
+ };
1555
+ await compileML(pages.mainPages, null, progress);
1556
+ for (const [root, subPages] of Object.entries(pages.subPages)) {
1557
+ await compileML(subPages.info, root, progress);
1558
+ }
1559
+ compileResCache.clear();
1560
+ wxsModuleRegistry.clear();
1561
+ wxsFilePathMap.clear();
1562
+ parentPort.postMessage({ success: true });
1563
+ } catch (error) {
1564
+ compileResCache.clear();
1565
+ wxsModuleRegistry.clear();
1566
+ wxsFilePathMap.clear();
1567
+ parentPort.postMessage({
1568
+ success: false,
1569
+ error: {
1570
+ message: error.message,
1571
+ stack: error.stack,
1572
+ name: error.name
1573
+ }
1574
+ });
1575
+ }
1576
+ });
1577
+ }
1578
+ async function compileML(pages, root, progress) {
1579
+ const workPath = getWorkPath();
1580
+ initWxsFilePathMap(workPath);
1581
+ for (const page of pages) {
1582
+ const scriptRes = /* @__PURE__ */ new Map();
1583
+ buildCompileView(page, false, scriptRes, [], /* @__PURE__ */ new Set());
1584
+ let mergeRender = "";
1585
+ for (const [key, value] of scriptRes.entries()) {
1586
+ const amdFormat = `modDefine('${key}', function(require, module, exports) {
1587
+ ${value}
1588
+ });`;
1589
+ const { code: minifiedCode } = await transform2(amdFormat, {
1590
+ minify: true,
1591
+ target: ["es2020"],
1592
+ platform: "browser"
1593
+ });
1594
+ mergeRender += minifiedCode;
1595
+ }
1596
+ scriptRes.clear();
1597
+ const filename = `${page.path.replace(/\//g, "_")}`;
1598
+ if (root) {
1599
+ const subDir = `${getTargetPath()}/${root}`;
1600
+ if (!fs5.existsSync(subDir)) {
1601
+ fs5.mkdirSync(subDir, { recursive: true });
1602
+ }
1603
+ fs5.writeFileSync(`${subDir}/${filename}.js`, mergeRender);
1604
+ } else {
1605
+ const mainDir = `${getTargetPath()}/main`;
1606
+ if (!fs5.existsSync(mainDir)) {
1607
+ fs5.mkdirSync(mainDir, { recursive: true });
1608
+ }
1609
+ fs5.writeFileSync(`${mainDir}/${filename}.js`, mergeRender);
1610
+ }
1611
+ progress.completedTasks++;
1612
+ }
1613
+ }
1614
+ function initWxsFilePathMap(workPath) {
1615
+ wxsFilePathMap.clear();
1616
+ const npmDir = path4.join(workPath, "miniprogram_npm");
1617
+ if (fs5.existsSync(npmDir)) {
1618
+ scanWxsFiles(npmDir, workPath);
1619
+ }
1620
+ }
1621
+ function scanWxsFiles(dir, workPath) {
1622
+ try {
1623
+ const items = fs5.readdirSync(dir);
1624
+ for (const item of items) {
1625
+ const fullPath = path4.join(dir, item);
1626
+ const stat = fs5.statSync(fullPath);
1627
+ if (stat.isDirectory()) {
1628
+ scanWxsFiles(fullPath, workPath);
1629
+ } else if (stat.isFile() && getViewScriptExts().some((ext) => item.endsWith(ext))) {
1630
+ const relativePath = stripViewScriptExt(fullPath.replace(workPath, ""));
1631
+ const moduleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
1632
+ wxsFilePathMap.set(moduleName, fullPath);
1633
+ }
1634
+ }
1635
+ } catch (error) {
1636
+ }
1637
+ }
1638
+ function registerWxsModule(modulePath) {
1639
+ wxsModuleRegistry.add(modulePath);
1640
+ }
1641
+ function isRegisteredWxsModule(modulePath) {
1642
+ return wxsModuleRegistry.has(modulePath);
1643
+ }
1644
+ function buildCompileView(module, isComponent = false, scriptRes, depthChain = [], inheritedTemplatePaths = /* @__PURE__ */ new Set()) {
1645
+ const currentPath = module.path;
1646
+ if (depthChain.includes(currentPath)) {
1647
+ console.warn("[view]", `\u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
1648
+ return;
1649
+ }
1650
+ if (depthChain.length > 20) {
1651
+ console.warn("[view]", `\u68C0\u6D4B\u5230\u6DF1\u5EA6\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
1652
+ return;
1653
+ }
1654
+ depthChain = [...depthChain, currentPath];
1655
+ const allScriptModules = [];
1656
+ const currentInstruction = compileModule(module, isComponent, scriptRes, {
1657
+ skipTemplatePaths: isComponent ? inheritedTemplatePaths : /* @__PURE__ */ new Set()
1658
+ });
1659
+ if (currentInstruction && currentInstruction.scriptModule) {
1660
+ allScriptModules.push(...currentInstruction.scriptModule);
1661
+ }
1662
+ const childInheritedTemplatePaths = new Set(inheritedTemplatePaths);
1663
+ for (const tm of currentInstruction?.templateModule || []) {
1664
+ childInheritedTemplatePaths.add(tm.path);
1665
+ }
1666
+ if (module.usingComponents) {
1667
+ for (const componentInfo of Object.values(module.usingComponents)) {
1668
+ const componentModule = getComponent(componentInfo);
1669
+ if (!componentModule) {
1670
+ continue;
1671
+ }
1672
+ if (componentModule.path === module.path) {
1673
+ console.warn("[view]", `\u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56\uFF0C\u8DF3\u8FC7\u5904\u7406: ${module.path}`);
1674
+ continue;
1675
+ }
1676
+ const componentInstruction = buildCompileView(componentModule, true, scriptRes, depthChain, childInheritedTemplatePaths);
1677
+ if (componentInstruction && componentInstruction.scriptModule) {
1678
+ for (const sm of componentInstruction.scriptModule) {
1679
+ if (!allScriptModules.find((existing) => existing.path === sm.path)) {
1680
+ allScriptModules.push(sm);
1681
+ }
1682
+ }
1683
+ }
1684
+ }
1685
+ }
1686
+ if (!isComponent && allScriptModules.length > 0) {
1687
+ for (const sm of allScriptModules) {
1688
+ if (!scriptRes.has(sm.path)) {
1689
+ scriptRes.set(sm.path, sm.code);
1690
+ }
1691
+ }
1692
+ compileModuleWithAllWxs(module, scriptRes, allScriptModules);
1693
+ }
1694
+ return { scriptModule: allScriptModules, templateModule: currentInstruction?.templateModule || [] };
1695
+ }
1696
+ function compileModule(module, isComponent, scriptRes, options = {}) {
1697
+ const skipTemplatePaths = options.skipTemplatePaths || /* @__PURE__ */ new Set();
1698
+ const { tpl, instruction } = toCompileTemplate(isComponent, module.path, module.usingComponents, module.componentPlaceholder);
1699
+ if (!tpl) {
1700
+ return null;
1701
+ }
1702
+ const templateModule = instruction.templateModule || [];
1703
+ const templateModuleForCompile = templateModule.filter((tm) => !skipTemplatePaths.has(tm.path));
1704
+ const compileInstruction = {
1705
+ ...instruction,
1706
+ templateModule: templateModuleForCompile
1707
+ };
1708
+ let useCache = false;
1709
+ let cachedCode = null;
1710
+ const canUseCache = skipTemplatePaths.size === 0;
1711
+ if (canUseCache && !scriptRes.has(module.path) && compileResCache.has(module.path)) {
1712
+ const cacheData2 = compileResCache.get(module.path);
1713
+ if (cacheData2 && typeof cacheData2 === "object" && cacheData2.code && cacheData2.instruction) {
1714
+ cachedCode = cacheData2.code;
1715
+ useCache = true;
1716
+ for (const sm of cacheData2.instruction.scriptModule) {
1717
+ if (!scriptRes.has(sm.path)) {
1718
+ scriptRes.set(sm.path, sm.code);
1719
+ }
1720
+ }
1721
+ } else if (typeof cacheData2 === "string") {
1722
+ cachedCode = cacheData2;
1723
+ useCache = true;
1724
+ }
1725
+ }
1726
+ if (useCache && cachedCode) {
1727
+ scriptRes.set(module.path, cachedCode);
1728
+ const allWxsModules2 = collectAllWxsModules(scriptRes, /* @__PURE__ */ new Set(), instruction.scriptModule || []);
1729
+ if (allWxsModules2.length > 0) {
1730
+ const existingModules = instruction.scriptModule || [];
1731
+ const mergedModules = [...existingModules];
1732
+ for (const wxsModule of allWxsModules2) {
1733
+ if (!mergedModules.find((existing) => existing.path === wxsModule.path)) {
1734
+ mergedModules.push(wxsModule);
1735
+ }
1736
+ }
1737
+ instruction.scriptModule = mergedModules;
1738
+ }
1739
+ return {
1740
+ ...instruction,
1741
+ scriptModule: allWxsModules2
1742
+ };
1743
+ }
1744
+ const processedTpl = tpl.replace(/\bthis\./g, "_ctx.");
1745
+ const tplCode = compileTemplate({
1746
+ source: processedTpl,
1747
+ filename: module.path,
1748
+ // 用于错误提示
1749
+ id: `data-v-${module.id}`,
1750
+ scoped: true,
1751
+ compilerOptions: {
1752
+ // https://template-explorer.vuejs.org/
1753
+ prefixIdentifiers: true,
1754
+ hoistStatic: false,
1755
+ cacheHandlers: true,
1756
+ scopeId: `data-v-${module.id}`,
1757
+ mode: "function",
1758
+ inline: true
1759
+ }
1760
+ });
1761
+ let tplComponents = "{";
1762
+ for (const tm of compileInstruction.templateModule) {
1763
+ let { code: code2 } = compileTemplate({
1764
+ source: tm.tpl,
1765
+ filename: tm.path,
1766
+ id: `data-v-${module.id}`,
1767
+ scoped: true,
1768
+ compilerOptions: {
1769
+ prefixIdentifiers: true,
1770
+ hoistStatic: false,
1771
+ cacheHandlers: true,
1772
+ scopeId: `data-v-${module.id}`,
1773
+ mode: "function",
1774
+ inline: true
1775
+ }
1776
+ });
1777
+ code2 = insertWxsToRenderCode(code2, compileInstruction.scriptModule, scriptRes, tm.path);
1778
+ tplComponents += `'${tm.path}':${code2},`;
1779
+ }
1780
+ tplComponents += "}";
1781
+ const transCode = insertWxsToRenderCode(tplCode.code, compileInstruction.scriptModule, scriptRes, module.path);
1782
+ const code = `Module({
1783
+ path: '${module.path}',
1784
+ id: '${module.id}',
1785
+ render: ${transCode},
1786
+ usingComponents: ${JSON.stringify(module.usingComponents)},
1787
+ tplComponents: ${tplComponents},
1788
+ });`;
1789
+ const allWxsModules = collectAllWxsModules(scriptRes, /* @__PURE__ */ new Set(), compileInstruction.scriptModule || []);
1790
+ if (allWxsModules.length > 0) {
1791
+ const existingModules = compileInstruction.scriptModule || [];
1792
+ const mergedModules = [...existingModules];
1793
+ for (const wxsModule of allWxsModules) {
1794
+ if (!mergedModules.find((existing) => existing.path === wxsModule.path)) {
1795
+ mergedModules.push(wxsModule);
1796
+ }
1797
+ }
1798
+ compileInstruction.scriptModule = mergedModules;
1799
+ }
1800
+ const cacheData = {
1801
+ code,
1802
+ instruction: compileInstruction
1803
+ };
1804
+ if (canUseCache) {
1805
+ compileResCache.set(module.path, cacheData);
1806
+ }
1807
+ scriptRes.set(module.path, code);
1808
+ return {
1809
+ ...compileInstruction,
1810
+ templateModule
1811
+ };
1812
+ }
1813
+ function processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath) {
1814
+ let wxsAst;
1815
+ try {
1816
+ wxsAst = parseJs(wxsContent, wxsFilePath || "inline.wxs", "script");
1817
+ } catch (error) {
1818
+ console.error(`[view] \u89E3\u6790 wxs \u6587\u4EF6\u5931\u8D25: ${wxsFilePath}`, error.message);
1819
+ return wxsContent;
1820
+ }
1821
+ const replacements = [];
1822
+ walk2(wxsAst, {
1823
+ enter(node) {
1824
+ if (node.type === "CallExpression") {
1825
+ const calleeName = node.callee?.name;
1826
+ if (calleeName === "getRegExp") {
1827
+ const args = node.arguments;
1828
+ if (args.length > 0) {
1829
+ if (isStringLiteral(args[0]) && (!args[1] || isStringLiteral(args[1]))) {
1830
+ const pattern = getStringLiteralRawValue(args[0]);
1831
+ const flags = args.length > 1 ? getStringLiteralRawValue(args[1]) : "";
1832
+ replacements.push({
1833
+ start: node.start,
1834
+ end: node.end,
1835
+ value: `/${pattern}/${flags}`
1836
+ });
1837
+ } else {
1838
+ const newRegExpArgs = args.map((arg) => getSource(wxsContent, arg)).join(", ");
1839
+ replacements.push({
1840
+ start: node.start,
1841
+ end: node.end,
1842
+ value: `new RegExp(${newRegExpArgs})`
1843
+ });
1844
+ }
1845
+ }
1846
+ } else if (calleeName === "getDate") {
1847
+ const args = node.arguments.map((arg) => getSource(wxsContent, arg)).join(", ");
1848
+ replacements.push({
1849
+ start: node.start,
1850
+ end: node.end,
1851
+ value: `new Date(${args})`
1852
+ });
1853
+ } else if (calleeName === "require" && node.arguments.length > 0 && wxsFilePath) {
1854
+ const requirePath = node.arguments[0].value;
1855
+ if (requirePath && typeof requirePath === "string") {
1856
+ let resolvedWxsPath;
1857
+ if (filePath && filePath.includes("/miniprogram_npm/")) {
1858
+ const currentWxsDir = path4.dirname(wxsFilePath);
1859
+ resolvedWxsPath = path4.resolve(currentWxsDir, requirePath);
1860
+ const relativePath = stripViewScriptExt(resolvedWxsPath.replace(workPath, ""));
1861
+ const moduleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
1862
+ processWxsDependency(resolvedWxsPath, moduleName, scriptModule, workPath, filePath);
1863
+ replacements.push({
1864
+ start: node.arguments[0].start,
1865
+ end: node.arguments[0].end,
1866
+ value: JSON.stringify(moduleName)
1867
+ });
1868
+ } else {
1869
+ const currentWxsDir = path4.dirname(wxsFilePath);
1870
+ resolvedWxsPath = path4.resolve(currentWxsDir, requirePath);
1871
+ const relativePath = stripViewScriptExt(resolvedWxsPath.replace(workPath, ""));
1872
+ const depModuleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
1873
+ processWxsDependency(resolvedWxsPath, depModuleName, scriptModule, workPath, filePath);
1874
+ replacements.push({
1875
+ start: node.arguments[0].start,
1876
+ end: node.arguments[0].end,
1877
+ value: JSON.stringify(depModuleName)
1878
+ });
1879
+ }
1880
+ }
1881
+ }
1882
+ }
1883
+ if (node.type === "MemberExpression") {
1884
+ if (node.property?.name === "constructor" && !node.computed) {
1885
+ const objectCode = getSource(wxsContent, node.object);
1886
+ replacements.push({
1887
+ start: node.start,
1888
+ end: node.end,
1889
+ value: `Object.prototype.toString.call(${objectCode}).slice(8, -1)`
1890
+ });
1891
+ }
1892
+ }
1893
+ }
1894
+ });
1895
+ return applyCodeReplacements(wxsContent, replacements);
1896
+ }
1897
+ function isWxsModuleByContent(moduleCode, modulePath = "") {
1898
+ if (!moduleCode || typeof moduleCode !== "string") {
1899
+ return false;
1900
+ }
1901
+ if (modulePath && isRegisteredWxsModule(modulePath)) {
1902
+ return true;
1903
+ }
1904
+ return false;
1905
+ }
1906
+ function processWxsDependency(wxsFilePath, moduleName, scriptModule, workPath, filePath) {
1907
+ if (!fs5.existsSync(wxsFilePath)) {
1908
+ console.warn(`[view] wxs \u4F9D\u8D56\u6587\u4EF6\u4E0D\u5B58\u5728: ${wxsFilePath}`);
1909
+ return;
1910
+ }
1911
+ if (scriptModule.find((sm) => sm.path === moduleName)) {
1912
+ return;
1913
+ }
1914
+ const wxsContent = getContentByPath(wxsFilePath).trim();
1915
+ if (!wxsContent) {
1916
+ return;
1917
+ }
1918
+ const wxsCode = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath);
1919
+ registerWxsModule(moduleName);
1920
+ scriptModule.push({
1921
+ path: moduleName,
1922
+ code: wxsCode
1923
+ });
1924
+ }
1925
+ function compileModuleWithAllWxs(module, scriptRes, allScriptModules) {
1926
+ const { tpl, instruction } = toCompileTemplate(false, module.path, module.usingComponents, module.componentPlaceholder);
1927
+ if (!tpl) {
1928
+ return;
1929
+ }
1930
+ const mergedInstruction = {
1931
+ ...instruction,
1932
+ scriptModule: allScriptModules
1933
+ };
1934
+ const processedTpl = tpl.replace(/\bthis\./g, "_ctx.");
1935
+ const tplCode = compileTemplate({
1936
+ source: processedTpl,
1937
+ filename: module.path,
1938
+ id: `data-v-${module.id}`,
1939
+ scoped: true,
1940
+ compilerOptions: {
1941
+ prefixIdentifiers: true,
1942
+ hoistStatic: false,
1943
+ cacheHandlers: true,
1944
+ scopeId: `data-v-${module.id}`,
1945
+ mode: "function",
1946
+ inline: true
1947
+ }
1948
+ });
1949
+ let tplComponents = "{";
1950
+ for (const tm of mergedInstruction.templateModule) {
1951
+ let { code: code2 } = compileTemplate({
1952
+ source: tm.tpl,
1953
+ filename: tm.path,
1954
+ id: `data-v-${module.id}`,
1955
+ scoped: true,
1956
+ compilerOptions: {
1957
+ prefixIdentifiers: true,
1958
+ hoistStatic: false,
1959
+ cacheHandlers: true,
1960
+ scopeId: `data-v-${module.id}`,
1961
+ mode: "function",
1962
+ inline: true
1963
+ }
1964
+ });
1965
+ code2 = insertWxsToRenderCode(code2, allScriptModules, scriptRes, tm.path);
1966
+ tplComponents += `'${tm.path}':${code2},`;
1967
+ }
1968
+ tplComponents += "}";
1969
+ const transCode = insertWxsToRenderCode(tplCode.code, allScriptModules, scriptRes, module.path);
1970
+ const code = `Module({
1971
+ path: '${module.path}',
1972
+ id: '${module.id}',
1973
+ render: ${transCode},
1974
+ usingComponents: ${JSON.stringify(module.usingComponents)},
1975
+ tplComponents: ${tplComponents},
1976
+ });`;
1977
+ const cacheData = {
1978
+ code,
1979
+ instruction: mergedInstruction
1980
+ };
1981
+ compileResCache.set(module.path, cacheData);
1982
+ scriptRes.set(module.path, code);
1983
+ }
1984
+ function processIncludeConditionalAttrs($, elem, includeContent) {
1985
+ const allAttrs = $(elem).attr();
1986
+ const conditionAttrs = {};
1987
+ let hasCondition = false;
1988
+ for (const attrName in allAttrs) {
1989
+ if (attrName.endsWith(":if") || attrName.endsWith(":elif") || attrName.endsWith(":else")) {
1990
+ conditionAttrs[attrName] = allAttrs[attrName];
1991
+ hasCondition = true;
1992
+ }
1993
+ }
1994
+ if (hasCondition) {
1995
+ let blockAttrs = "";
1996
+ for (const attrName in conditionAttrs) {
1997
+ const attrValue = conditionAttrs[attrName];
1998
+ if (attrValue !== void 0 && attrValue !== "") {
1999
+ blockAttrs += ` ${attrName}="${attrValue}"`;
2000
+ } else {
2001
+ blockAttrs += ` ${attrName}`;
2002
+ }
2003
+ }
2004
+ return `<block${blockAttrs}>${includeContent}</block>`;
2005
+ } else {
2006
+ return includeContent;
2007
+ }
2008
+ }
2009
+ function processIncludedFileWxsDependencies(content, includePath, scriptModule, components, processedPaths = /* @__PURE__ */ new Set()) {
2010
+ if (processedPaths.has(includePath)) {
2011
+ return;
2012
+ }
2013
+ processedPaths.add(includePath);
2014
+ const $ = cheerio.load(content, {
2015
+ xmlMode: true,
2016
+ decodeEntities: false,
2017
+ _useHtmlParser2: true,
2018
+ // 减少内存占用的配置
2019
+ lowerCaseTags: false,
2020
+ lowerCaseAttributeNames: false
2021
+ });
2022
+ const componentTags = /* @__PURE__ */ new Set();
2023
+ $("*").each((_, elem) => {
2024
+ const tagName = elem.tagName;
2025
+ if (components && components[tagName]) {
2026
+ componentTags.add(tagName);
2027
+ }
2028
+ });
2029
+ for (const tagName of componentTags) {
2030
+ const componentPath = components[tagName];
2031
+ const componentModule = getComponent(componentPath);
2032
+ if (componentModule) {
2033
+ if (processedPaths.has(componentModule.path)) {
2034
+ continue;
2035
+ }
2036
+ const componentTemplate = toCompileTemplate(true, componentModule.path, componentModule.usingComponents, componentModule.componentPlaceholder, processedPaths);
2037
+ if (componentTemplate && componentTemplate.instruction && componentTemplate.instruction.scriptModule) {
2038
+ for (const sm of componentTemplate.instruction.scriptModule) {
2039
+ if (!scriptModule.find((existing) => existing.path === sm.path)) {
2040
+ scriptModule.push(sm);
2041
+ }
2042
+ }
2043
+ }
2044
+ }
2045
+ }
2046
+ }
2047
+ function toCompileTemplate(isComponent, path6, components, componentPlaceholder, processedPaths = /* @__PURE__ */ new Set()) {
2048
+ const workPath = getWorkPath();
2049
+ const fullPath = getViewPath(workPath, path6);
2050
+ if (!fullPath) {
2051
+ return { tpl: void 0 };
2052
+ }
2053
+ const diagnosticSource = fullPath.startsWith(workPath) ? fullPath.slice(workPath.length) : path6;
2054
+ let content = getContentByPath(fullPath).trim();
2055
+ if (!content) {
2056
+ content = "<block></block>";
2057
+ } else {
2058
+ checkTemplateCompatibility(content, diagnosticSource, components);
2059
+ if (isComponent) {
2060
+ content = `<wrapper name="${path6}">${content}</wrapper>`;
2061
+ } else {
2062
+ const tempRoot = cheerio.load(content, {
2063
+ xmlMode: true,
2064
+ decodeEntities: false
2065
+ });
2066
+ const rootNodes = tempRoot.root().children().toArray().filter((node) => node.type !== "comment");
2067
+ if (rootNodes.length > 1) {
2068
+ content = `<view>${content}</view>`;
2069
+ }
2070
+ }
2071
+ }
2072
+ const templateModule = [];
2073
+ const scriptModule = [];
2074
+ const $ = cheerio.load(content, {
2075
+ xmlMode: true,
2076
+ decodeEntities: false,
2077
+ _useHtmlParser2: true,
2078
+ // 减少内存占用的配置
2079
+ lowerCaseTags: false,
2080
+ lowerCaseAttributeNames: false
2081
+ });
2082
+ const includeNodes = $("include");
2083
+ includeNodes.each((_, elem) => {
2084
+ const src = $(elem).attr("src");
2085
+ if (src) {
2086
+ const includeFullPath = getAbsolutePath(workPath, path6, src);
2087
+ let includePath = includeFullPath.replace(workPath, "").replace(buildExtStripRegex(getTemplateExts()), "");
2088
+ const includeDiagnosticSource = includeFullPath.startsWith(workPath) ? includeFullPath.slice(workPath.length) : includePath;
2089
+ if (!includePath.startsWith("/")) {
2090
+ includePath = "/" + includePath;
2091
+ }
2092
+ const includeContent = getContentByPath(includeFullPath).trim();
2093
+ if (includeContent) {
2094
+ checkTemplateCompatibility(includeContent, includeDiagnosticSource, components);
2095
+ const $includeContent = cheerio.load(includeContent, {
2096
+ xmlMode: true,
2097
+ decodeEntities: false
2098
+ });
2099
+ transTagTemplate(
2100
+ $includeContent,
2101
+ templateModule,
2102
+ includePath,
2103
+ components,
2104
+ componentPlaceholder
2105
+ );
2106
+ transTagWxs(
2107
+ $includeContent,
2108
+ scriptModule,
2109
+ includePath
2110
+ );
2111
+ processIncludedFileWxsDependencies(includeContent, includePath, scriptModule, components, processedPaths);
2112
+ $includeContent("template").remove();
2113
+ $includeContent(getViewScriptTags().join(",")).remove();
2114
+ const processedContent = processIncludeConditionalAttrs($, elem, $includeContent.html());
2115
+ $(elem).replaceWith(processedContent);
2116
+ } else {
2117
+ $(elem).remove();
2118
+ }
2119
+ } else {
2120
+ $(elem).remove();
2121
+ }
2122
+ });
2123
+ transTagTemplate($, templateModule, path6, components, componentPlaceholder);
2124
+ transTagWxs($, scriptModule, path6);
2125
+ const importNodes = $("import");
2126
+ importNodes.each((_, elem) => {
2127
+ const src = $(elem).attr("src");
2128
+ if (src) {
2129
+ const importFullPath = getAbsolutePath(workPath, path6, src);
2130
+ let importPath = importFullPath.replace(workPath, "").replace(buildExtStripRegex(getTemplateExts()), "");
2131
+ const importDiagnosticSource = importFullPath.startsWith(workPath) ? importFullPath.slice(workPath.length) : importPath;
2132
+ if (!importPath.startsWith("/")) {
2133
+ importPath = "/" + importPath;
2134
+ }
2135
+ const importContent = getContentByPath(importFullPath).trim();
2136
+ if (importContent) {
2137
+ checkTemplateCompatibility(importContent, importDiagnosticSource, components);
2138
+ const $$ = cheerio.load(importContent, {
2139
+ xmlMode: true,
2140
+ decodeEntities: false
2141
+ });
2142
+ transTagTemplate(
2143
+ $$,
2144
+ templateModule,
2145
+ path6,
2146
+ components,
2147
+ componentPlaceholder
2148
+ );
2149
+ transTagWxs(
2150
+ $$,
2151
+ scriptModule,
2152
+ importPath
2153
+ );
2154
+ processIncludedFileWxsDependencies(importContent, importPath, scriptModule, components, processedPaths);
2155
+ }
2156
+ }
2157
+ });
2158
+ importNodes.remove();
2159
+ transAsses($, $("image"), path6);
2160
+ const res = [];
2161
+ transHtmlTag($.html(), res, components, componentPlaceholder);
2162
+ return {
2163
+ tpl: res.join(""),
2164
+ instruction: {
2165
+ templateModule,
2166
+ scriptModule
2167
+ }
2168
+ };
2169
+ }
2170
+ function transTagTemplate($, templateModule, path6, components, componentPlaceholder) {
2171
+ const templateNodes = $("template[name]");
2172
+ templateNodes.each((_, elem) => {
2173
+ const name = $(elem).attr("name");
2174
+ const templateContent = $(elem);
2175
+ templateContent.find("import").remove();
2176
+ templateContent.find("include").remove();
2177
+ templateContent.find(getViewScriptTags().join(",")).remove();
2178
+ transAsses($, templateContent.find("image"), path6);
2179
+ const res = [];
2180
+ transHtmlTag(templateContent.html(), res, components, componentPlaceholder);
2181
+ templateModule.push({
2182
+ path: `tpl-${name}`,
2183
+ tpl: res.join("")
2184
+ });
2185
+ });
2186
+ templateNodes.remove();
2187
+ }
2188
+ function transAsses($, imageNodes, path6) {
2189
+ imageNodes.each((_, elem) => {
2190
+ const imgSrc = $(elem).attr("src").trim();
2191
+ if (!imgSrc.startsWith("{{")) {
2192
+ $(elem).attr("src", collectAssets(getWorkPath(), path6, imgSrc, getTargetPath(), getAppId()));
2193
+ }
2194
+ });
2195
+ }
2196
+ function transHtmlTag(html, res, components, componentPlaceholder) {
2197
+ const attrsList = [];
2198
+ const parser = new htmlparser2.Parser(
2199
+ {
2200
+ onopentag(tag, attrs) {
2201
+ attrsList.push(attrs);
2202
+ res.push(transTag({ isStart: true, tag, attrs, components, componentPlaceholder }));
2203
+ },
2204
+ ontext(text) {
2205
+ res.push(transformTextInterpolation(text));
2206
+ },
2207
+ onclosetag(tag) {
2208
+ res.push(transTag({ tag, attrs: attrsList.pop(), components }));
2209
+ },
2210
+ onerror(error) {
2211
+ console.error(error);
2212
+ }
2213
+ },
2214
+ { xmlMode: true }
2215
+ );
2216
+ parser.write(html);
2217
+ parser.end();
2218
+ }
2219
+ function transTag(opts) {
2220
+ const { isStart, tag, attrs, components } = opts;
2221
+ let res;
2222
+ if (tag === "slot") {
2223
+ res = tag;
2224
+ } else if (components && components[tag]) {
2225
+ res = `dd-${tag}`;
2226
+ } else if (tag === "component" || tag === "canvas") {
2227
+ res = tag;
2228
+ } else if (!tagWhiteList.includes(tag)) {
2229
+ res = "dd-text";
2230
+ } else {
2231
+ res = `dd-${tag}`;
2232
+ }
2233
+ let tagRes;
2234
+ const propsAry = isStart ? getProps(attrs, tag, components) : [];
2235
+ const multipleSlots = attrs?.slot;
2236
+ if (attrs?.slot) {
2237
+ const isDynamicSlot = isWrappedByBraces(multipleSlots);
2238
+ if (isStart) {
2239
+ const withVIf = [];
2240
+ const withoutVIf = [];
2241
+ for (let i = 0; i < propsAry.length; i++) {
2242
+ const prop = propsAry[i];
2243
+ if (prop.includes("v-if") || prop.includes("v-else-if") || prop.includes("v-else")) {
2244
+ withVIf.push(prop);
2245
+ } else if (!prop.includes("slot")) {
2246
+ withoutVIf.push(prop);
2247
+ }
2248
+ }
2249
+ const vIfProps = withVIf.length > 0 ? `${withVIf.join(" ")} ` : "";
2250
+ const vOtherProps = withoutVIf.length > 0 ? ` ${withoutVIf.join(" ")}` : "";
2251
+ const templateContent = `<template ${vIfProps}${generateSlotDirective(multipleSlots)}><${res}${vOtherProps}>`;
2252
+ if (isDynamicSlot) {
2253
+ tagRes = `<dd-block>${templateContent}`;
2254
+ } else {
2255
+ tagRes = templateContent;
2256
+ }
2257
+ } else {
2258
+ if (isDynamicSlot) {
2259
+ tagRes = `</${res}></template></dd-block>`;
2260
+ } else {
2261
+ tagRes = `</${res}></template>`;
2262
+ }
2263
+ }
2264
+ } else {
2265
+ if (isStart) {
2266
+ const props = propsAry.join(" ");
2267
+ tagRes = props ? `<${res} ${props}>` : `<${res}>`;
2268
+ } else {
2269
+ tagRes = `</${res}>`;
2270
+ }
2271
+ }
2272
+ return tagRes;
2273
+ }
2274
+ function generateSlotDirective(slotValue) {
2275
+ if (isWrappedByBraces(slotValue)) {
2276
+ const slotExpression = parseBraceExp(slotValue);
2277
+ return `#[${slotExpression}]`;
2278
+ } else {
2279
+ return `#${slotValue}`;
2280
+ }
2281
+ }
2282
+ function getProps(attrs, tag, components) {
2283
+ const attrsList = [];
2284
+ const propBindings = {};
2285
+ Object.entries(attrs).forEach(([name, value]) => {
2286
+ if (name.endsWith(":if")) {
2287
+ attrsList.push({
2288
+ name: "v-if",
2289
+ value: parseSafeBraceExp(value)
2290
+ });
2291
+ } else if (name.endsWith(":elif")) {
2292
+ attrsList.push({
2293
+ name: "v-else-if",
2294
+ value: parseSafeBraceExp(value)
2295
+ });
2296
+ } else if (name.endsWith(":else")) {
2297
+ attrsList.push({
2298
+ name: "v-else",
2299
+ value: ""
2300
+ });
2301
+ } else if (name.endsWith(":for") || name.endsWith(":for-items")) {
2302
+ attrsList.push({
2303
+ name: "v-for",
2304
+ value: parseForExp(value, attrs)
2305
+ });
2306
+ } else if (name.endsWith(":for-item") || name.endsWith(":for-index")) {
2307
+ } else if (name.endsWith(":key")) {
2308
+ const tranValue = parseKeyExpression(value, getForItemName(attrs), getForIndexName(attrs));
2309
+ attrsList.push({
2310
+ name: ":key",
2311
+ value: tranValue
2312
+ });
2313
+ } else if (name === "style") {
2314
+ attrsList.push({
2315
+ name: "v-c-style",
2316
+ value: transformRpx(parseSafeBraceExp(value))
2317
+ });
2318
+ } else if (name === "class") {
2319
+ if (isWrappedByBraces(value)) {
2320
+ attrsList.push({
2321
+ name: ":class",
2322
+ value: parseClassRules(value)
2323
+ });
2324
+ } else {
2325
+ attrsList.push({
2326
+ name: "class",
2327
+ value
2328
+ });
2329
+ }
2330
+ attrsList.push({
2331
+ name: "v-c-class",
2332
+ value: ""
2333
+ });
2334
+ } else if (name === "is" && tag === "component") {
2335
+ attrsList.push({
2336
+ name: ":is",
2337
+ value: `'dd-'+${parseSafeBraceExp(value)}`
2338
+ });
2339
+ } else if (name === "animation" && (tag !== "movable-view" && tagWhiteList.includes(tag))) {
2340
+ attrsList.push({
2341
+ name: "v-c-animation",
2342
+ value: parseSafeBraceExp(value)
2343
+ });
2344
+ } else if (name === "value" && (tag === "input" || tag === "textarea") || (name === "x" || name === "y") && tag === "movable-view") {
2345
+ const parsedValue = parseSafeBraceExp(value);
2346
+ const conditionExp = generateVModelTemplate(parsedValue);
2347
+ if (conditionExp) {
2348
+ attrsList.push({
2349
+ name: `:${name}`,
2350
+ value: parsedValue
2351
+ });
2352
+ attrsList.push({
2353
+ name: `update:${name}`,
2354
+ value: conditionExp
2355
+ });
2356
+ } else {
2357
+ attrsList.push({
2358
+ name: `v-model:${name}`,
2359
+ value: parsedValue
2360
+ });
2361
+ }
2362
+ } else if (name.startsWith("data-")) {
2363
+ if (isWrappedByBraces(value)) {
2364
+ attrsList.push({
2365
+ name: "v-c-data",
2366
+ value: ""
2367
+ });
2368
+ attrsList.push({
2369
+ name: `:${name}`,
2370
+ value: parseSafeBraceExp(value)
2371
+ });
2372
+ } else {
2373
+ attrsList.push({
2374
+ name,
2375
+ value
2376
+ });
2377
+ }
2378
+ } else if (isWrappedByBraces(value)) {
2379
+ const pVal = tag === "template" && name === "data" ? parseTemplateDataExp(value) : parseSafeBraceExp(value);
2380
+ if (components && components[tag]) {
2381
+ if (pVal && typeof pVal === "string") {
2382
+ propBindings[name] = pVal;
2383
+ }
2384
+ }
2385
+ attrsList.push({
2386
+ name: `:${name}`,
2387
+ value: pVal
2388
+ });
2389
+ } else if (name !== "slot") {
2390
+ attrsList.push({
2391
+ name,
2392
+ value
2393
+ });
2394
+ }
2395
+ });
2396
+ const propsRes = [];
2397
+ attrsList.forEach((attr) => {
2398
+ const { name, value } = attr;
2399
+ if (value === "") {
2400
+ propsRes.push(`${name}`);
2401
+ } else if (/\$\{[^}]*\}/.test(value)) {
2402
+ propsRes.push(`:${name}="\`${value}\`"`);
2403
+ } else {
2404
+ propsRes.push(`${name}="${escapeQuotes(value)}"`);
2405
+ }
2406
+ });
2407
+ if (components && components[tag] && Object.keys(propBindings).length > 0) {
2408
+ try {
2409
+ const validBindings = {};
2410
+ for (const [key, value] of Object.entries(propBindings)) {
2411
+ if (value !== void 0 && value !== null && typeof value === "string") {
2412
+ validBindings[key] = value;
2413
+ }
2414
+ }
2415
+ if (Object.keys(validBindings).length > 0) {
2416
+ const parsedBindings = parseBindings(validBindings);
2417
+ const bindingsJson = JSON.stringify(parsedBindings);
2418
+ const escapedJson = bindingsJson.replace(/"/g, "&quot;");
2419
+ propsRes.push(`v-c-prop-bindings="${escapedJson}"`);
2420
+ }
2421
+ } catch (error) {
2422
+ console.warn("[compiler] \u5E8F\u5217\u5316 propBindings \u5931\u8D25:", error.message, "\u6807\u7B7E:", tag, "\u7ED1\u5B9A\u6570\u636E:", propBindings);
2423
+ }
2424
+ }
2425
+ return propsRes;
2426
+ }
2427
+ function generateVModelTemplate(expression) {
2428
+ let var1, var2, updateExpression;
2429
+ if (expression.includes("&&")) {
2430
+ [var1, var2] = expression.split("&&").map((v) => v.trim());
2431
+ updateExpression = `${var1} ? (${var2} = $event) : (${var1} = $event)`;
2432
+ } else if (expression.includes("||")) {
2433
+ [var1, var2] = expression.split("||").map((v) => v.trim());
2434
+ updateExpression = `${var1} ? (${var1} = $event) : (${var2} = $event)`;
2435
+ } else if (expression.includes("?")) {
2436
+ const parts = expression.split(/[?:]/).map((v) => v.trim());
2437
+ var1 = parts[0];
2438
+ var2 = parts[2];
2439
+ updateExpression = `${var1} ? (${var1} = $event) : (${var2} = $event)`;
2440
+ } else {
2441
+ return false;
2442
+ }
2443
+ return updateExpression;
2444
+ }
2445
+ function parseKeyExpression(exp, itemName = "item", indexName = "index") {
2446
+ exp = exp.trim();
2447
+ if (/\*this/.test(exp) || /\*item/.test(exp)) {
2448
+ return `${itemName}.toString()`;
2449
+ }
2450
+ if (!exp.includes("{{")) {
2451
+ if (/^-?\d+(\.\d+)?$/.test(exp)) {
2452
+ return exp;
2453
+ }
2454
+ if (exp === indexName) {
2455
+ return indexName;
2456
+ }
2457
+ return exp.startsWith(itemName) ? `${exp}` : `${itemName}.${exp}`;
2458
+ }
2459
+ if (exp.startsWith("{{") && exp.endsWith("}}")) {
2460
+ const content = exp.slice(2, -2).trim();
2461
+ if (content === "this") {
2462
+ return `${itemName}.toString()`;
2463
+ } else if (content === indexName) {
2464
+ return indexName;
2465
+ } else {
2466
+ return content.startsWith(itemName) ? `${content}` : `${itemName}.${content}`;
2467
+ }
2468
+ }
2469
+ const parts = exp.split(/(\{\{.*?\}\})/);
2470
+ const result = parts.map((part) => {
2471
+ if (part.startsWith("{{") && part.endsWith("}}")) {
2472
+ const content = part.slice(2, -2).trim();
2473
+ if (content === indexName) {
2474
+ return indexName;
2475
+ }
2476
+ return content.startsWith(itemName) ? content : `${itemName}.${content}`;
2477
+ }
2478
+ return `'${part}'`;
2479
+ }).join("+");
2480
+ return result.endsWith("+''") ? result.slice(0, -3) : result;
2481
+ }
2482
+ function getViewPath(workPath, src) {
2483
+ const aSrc = src.startsWith("/") ? src : `/${src}`;
2484
+ for (const mlType of getTemplateExts()) {
2485
+ const mlFullPath = `${workPath}${aSrc}${mlType}`;
2486
+ if (fs5.existsSync(mlFullPath)) {
2487
+ return mlFullPath;
2488
+ }
2489
+ const indexMlFullPath = `${workPath}${aSrc}/index${mlType}`;
2490
+ if (fs5.existsSync(indexMlFullPath)) {
2491
+ return indexMlFullPath;
2492
+ }
2493
+ }
2494
+ }
2495
+ function escapeQuotes(input) {
2496
+ return input.replace(/"/g, "'");
2497
+ }
2498
+ function isWrappedByBraces(str) {
2499
+ return /\{\{.*\}\}/.test(str);
2500
+ }
2501
+ function splitWithBraces(str) {
2502
+ const result = [];
2503
+ let temp = "";
2504
+ let inBraces = false;
2505
+ for (let i = 0; i < str.length; i++) {
2506
+ const char = str[i];
2507
+ if (char === "{" && i + 1 < str.length && str[i + 1] === "{") {
2508
+ inBraces = true;
2509
+ temp += "{{";
2510
+ i++;
2511
+ } else if (char === "}" && i + 1 < str.length && str[i + 1] === "}") {
2512
+ inBraces = false;
2513
+ temp += "}}";
2514
+ i++;
2515
+ } else if (!inBraces && char === " ") {
2516
+ if (temp) {
2517
+ result.push(temp);
2518
+ temp = "";
2519
+ }
2520
+ } else {
2521
+ temp += char;
2522
+ }
2523
+ }
2524
+ if (temp) {
2525
+ result.push(temp);
2526
+ }
2527
+ return result;
2528
+ }
2529
+ function parseClassRules(cssRule) {
2530
+ let list = splitWithBraces(cssRule);
2531
+ list = list.map((item) => {
2532
+ return parseBraceExp(item);
2533
+ });
2534
+ if (list.length === 1) {
2535
+ return list.pop();
2536
+ }
2537
+ return `[${list.join(",")}]`;
2538
+ }
2539
+ function getForItemName(attrs) {
2540
+ for (const key in attrs) {
2541
+ if (key.endsWith(":for-item")) {
2542
+ return attrs[key];
2543
+ }
2544
+ }
2545
+ return "item";
2546
+ }
2547
+ function getForIndexName(attrs) {
2548
+ for (const key in attrs) {
2549
+ if (key.endsWith(":for-index")) {
2550
+ return attrs[key];
2551
+ }
2552
+ }
2553
+ return "index";
2554
+ }
2555
+ function parseForExp(exp, attrs) {
2556
+ const item = getForItemName(attrs);
2557
+ const index = getForIndexName(attrs);
2558
+ const listVariableName = parseBraceExp(exp);
2559
+ return `(${item}, ${index}) in ${listVariableName}`;
2560
+ }
2561
+ var braceRegex = /(\{\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}\})|([^{}]+)/g;
2562
+ var noBraceRegex = /\{\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}\}/;
2563
+ var ternaryRegex = /[^?]+\?.+:.+/;
2564
+ function parseBraceExp(exp) {
2565
+ let result;
2566
+ const group = [];
2567
+ while (result = braceRegex.exec(exp)) {
2568
+ if (result[1]) {
2569
+ const matchResult = result[1].match(noBraceRegex);
2570
+ if (matchResult) {
2571
+ const statement = matchResult[1].trim();
2572
+ if (ternaryRegex.test(statement)) {
2573
+ group.push(`(${statement})`);
2574
+ } else {
2575
+ group.push(statement);
2576
+ }
2577
+ }
2578
+ }
2579
+ if (result[2]) {
2580
+ group.push(`+'${result[2].replace(/'/g, "\\'")}'+`);
2581
+ }
2582
+ }
2583
+ return group.join("").replace(/^\+|\+$/g, "");
2584
+ }
2585
+ function parseTemplateDataExp(exp) {
2586
+ const matchResult = exp.trim().match(/^\{\{([\s\S]*)\}\}$/);
2587
+ if (matchResult) {
2588
+ return `{${matchResult[1].trim()}}`;
2589
+ }
2590
+ return `{${parseBraceExp(exp)}}`;
2591
+ }
2592
+ function transTagWxs($, scriptModule, filePath) {
2593
+ const wxsNodes = $(getViewScriptTags().join(","));
2594
+ wxsNodes.each((_, elem) => {
2595
+ const smName = $(elem).attr("module");
2596
+ if (smName) {
2597
+ let wxsContent;
2598
+ let uniqueModuleName = smName;
2599
+ let cacheKey = smName;
2600
+ const src = $(elem).attr("src");
2601
+ let wxsFilePath = null;
2602
+ const workPath = getWorkPath();
2603
+ if (src) {
2604
+ if (filePath.includes("/miniprogram_npm/")) {
2605
+ const componentDir = filePath.split("/").slice(0, -1).join("/");
2606
+ const componentFullPath = workPath + componentDir;
2607
+ wxsFilePath = path4.resolve(componentFullPath, src);
2608
+ } else {
2609
+ wxsFilePath = getAbsolutePath(workPath, filePath, src);
2610
+ }
2611
+ if (wxsFilePath) {
2612
+ const relativePath = stripViewScriptExt(wxsFilePath.replace(workPath, ""));
2613
+ uniqueModuleName = relativePath.replace(/[\/\\@\-]/g, "_").replace(/^_/, "");
2614
+ cacheKey = wxsFilePath;
2615
+ }
2616
+ }
2617
+ if (compileResCache.has(cacheKey)) {
2618
+ wxsContent = compileResCache.get(cacheKey);
2619
+ } else {
2620
+ if (src && wxsFilePath) {
2621
+ if (fs5.existsSync(wxsFilePath)) {
2622
+ wxsContent = getContentByPath(wxsFilePath).trim();
2623
+ } else {
2624
+ console.warn(`[view] wxs \u6587\u4EF6\u4E0D\u5B58\u5728: ${wxsFilePath}`);
2625
+ return;
2626
+ }
2627
+ } else {
2628
+ wxsContent = $(elem).html();
2629
+ }
2630
+ if (!wxsContent) {
2631
+ return;
2632
+ }
2633
+ wxsContent = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, filePath);
2634
+ compileResCache.set(cacheKey, wxsContent);
2635
+ }
2636
+ if (wxsContent) {
2637
+ registerWxsModule(uniqueModuleName);
2638
+ scriptModule.push({
2639
+ path: uniqueModuleName,
2640
+ code: wxsContent,
2641
+ originalName: smName
2642
+ // 保存原始模块名用于模板中的引用
2643
+ });
2644
+ }
2645
+ }
2646
+ });
2647
+ wxsNodes.remove();
2648
+ }
2649
+ function collectAllWxsModules(scriptRes, collectedPaths = /* @__PURE__ */ new Set(), scriptModule = []) {
2650
+ const allWxsModules = [];
2651
+ const workPath = getWorkPath();
2652
+ for (const [modulePath, moduleCode] of scriptRes.entries()) {
2653
+ if (collectedPaths.has(modulePath)) {
2654
+ continue;
2655
+ }
2656
+ if (isWxsModuleByContent(moduleCode, modulePath)) {
2657
+ collectedPaths.add(modulePath);
2658
+ allWxsModules.push({
2659
+ path: modulePath,
2660
+ code: moduleCode
2661
+ });
2662
+ const dependencies = extractWxsDependencies(moduleCode);
2663
+ for (const depPath of dependencies) {
2664
+ if (!collectedPaths.has(depPath)) {
2665
+ if (scriptRes.has(depPath)) {
2666
+ const depModules = collectAllWxsModules(/* @__PURE__ */ new Map([[depPath, scriptRes.get(depPath)]]), collectedPaths, scriptModule);
2667
+ allWxsModules.push(...depModules);
2668
+ } else {
2669
+ const loaded = loadWxsModule(depPath, workPath, scriptModule);
2670
+ if (loaded) {
2671
+ scriptRes.set(depPath, loaded.code);
2672
+ allWxsModules.push(loaded);
2673
+ collectedPaths.add(depPath);
2674
+ const depModules = collectAllWxsModules(/* @__PURE__ */ new Map([[depPath, loaded.code]]), collectedPaths, scriptModule);
2675
+ allWxsModules.push(...depModules);
2676
+ }
2677
+ }
2678
+ }
2679
+ }
2680
+ }
2681
+ }
2682
+ return allWxsModules;
2683
+ }
2684
+ function loadWxsModule(modulePath, workPath, scriptModule) {
2685
+ const wxsFilePath = wxsFilePathMap.get(modulePath);
2686
+ if (!wxsFilePath) {
2687
+ return null;
2688
+ }
2689
+ try {
2690
+ const wxsContent = getContentByPath(wxsFilePath).trim();
2691
+ if (!wxsContent) {
2692
+ return null;
2693
+ }
2694
+ const processedContent = processWxsContent(wxsContent, wxsFilePath, scriptModule, workPath, "");
2695
+ registerWxsModule(modulePath);
2696
+ return {
2697
+ path: modulePath,
2698
+ code: processedContent
2699
+ };
2700
+ } catch (error) {
2701
+ console.warn(`[view] \u52A0\u8F7D wxs \u6A21\u5757\u5931\u8D25: ${modulePath}`, error.message);
2702
+ return null;
2703
+ }
2704
+ }
2705
+ function extractWxsDependencies(moduleCode) {
2706
+ const dependencies = [];
2707
+ const requirePattern = /(?:require|_)\s*\(\s*["']([^"']+)["']\s*\)/g;
2708
+ let match;
2709
+ while ((match = requirePattern.exec(moduleCode)) !== null) {
2710
+ const depPath = match[1];
2711
+ if (depPath && !dependencies.includes(depPath)) {
2712
+ dependencies.push(depPath);
2713
+ }
2714
+ }
2715
+ return dependencies;
2716
+ }
2717
+ function insertWxsToRenderCode(code, scriptModule, scriptRes, filename = "render.js") {
2718
+ const wxsBindings = [];
2719
+ const codeReplacements = [];
2720
+ const ast = parseJs(code, filename);
2721
+ const statement = ast.body?.[0];
2722
+ const renderExpression = statement?.type === "ExpressionStatement" ? statement.expression : null;
2723
+ const renderBody = renderExpression?.body;
2724
+ const declarations = [];
2725
+ for (const [index, sm] of scriptModule.entries()) {
2726
+ if (!scriptRes.has(sm.path)) {
2727
+ scriptRes.set(sm.path, sm.code);
2728
+ }
2729
+ const templatePropertyName = sm.originalName || sm.path;
2730
+ const requireModuleName = sm.path;
2731
+ const localIdentifier = `__wxs_${index}`;
2732
+ wxsBindings.push({
2733
+ localIdentifier,
2734
+ templatePropertyName
2735
+ });
2736
+ declarations.push(`const ${localIdentifier} = require(${JSON.stringify(requireModuleName)});`);
2737
+ }
2738
+ if (wxsBindings.length === 0) {
2739
+ return getProgramCode(code, ast);
2740
+ }
2741
+ if (renderBody?.type === "BlockStatement") {
2742
+ codeReplacements.push({
2743
+ type: "insert",
2744
+ start: renderBody.start + 1,
2745
+ end: renderBody.start + 1,
2746
+ value: `
2747
+ ${declarations.join("\n")}`
2748
+ });
2749
+ }
2750
+ walk2(ast, {
2751
+ enter(node) {
2752
+ if (node.type === "MemberExpression" && node.object?.type === "Identifier" && node.object.name === "_ctx" && !node.computed && node.property?.type === "Identifier") {
2753
+ const replacement = wxsBindings.find((item) => item.templatePropertyName === node.property.name);
2754
+ if (replacement) {
2755
+ codeReplacements.push({
2756
+ start: node.start,
2757
+ end: node.end,
2758
+ value: replacement.localIdentifier
2759
+ });
2760
+ }
2761
+ }
2762
+ }
2763
+ });
2764
+ const transformed = applyCodeReplacements(code, codeReplacements);
2765
+ const transformedAst = parseJs(transformed, filename);
2766
+ return getProgramCode(transformed, transformedAst);
2767
+ }
2768
+ function __resetViewState() {
2769
+ compileResCache.clear();
2770
+ wxsModuleRegistry.clear();
2771
+ wxsFilePathMap.clear();
2772
+ }
2773
+
2774
+ // ../../dimina/fe/packages/compiler/src/core/style-compiler.js
2775
+ import fs6 from "node:fs";
2776
+ import path5 from "node:path";
2777
+ import { compileStyle } from "@vue/compiler-sfc";
2778
+ import autoprefixer from "autoprefixer";
2779
+ import cssnano from "cssnano";
2780
+ import less from "less";
2781
+ import postcss from "postcss";
2782
+ import selectorParser from "postcss-selector-parser";
2783
+ import * as sass from "sass";
2784
+ var compileRes = /* @__PURE__ */ new Map();
2785
+ if (!isMainThread) {
2786
+ parentPort.on("message", async ({ pages, storeInfo: storeInfo2 }) => {
2787
+ try {
2788
+ resetStoreInfo(storeInfo2);
2789
+ const progress = {
2790
+ _completedTasks: 0,
2791
+ get completedTasks() {
2792
+ return this._completedTasks;
2793
+ },
2794
+ set completedTasks(value) {
2795
+ this._completedTasks = value;
2796
+ parentPort.postMessage({ completedTasks: this._completedTasks });
2797
+ }
2798
+ };
2799
+ await compileSS(pages.mainPages, null, progress);
2800
+ for (const [root, subPages] of Object.entries(pages.subPages)) {
2801
+ await compileSS(subPages.info, root, progress);
2802
+ }
2803
+ compileRes.clear();
2804
+ parentPort.postMessage({ success: true });
2805
+ } catch (error) {
2806
+ compileRes.clear();
2807
+ parentPort.postMessage({
2808
+ success: false,
2809
+ error: {
2810
+ message: error.message,
2811
+ stack: error.stack,
2812
+ name: error.name
2813
+ }
2814
+ });
2815
+ }
2816
+ });
2817
+ }
2818
+ async function compileSS(pages, root, progress) {
2819
+ for (const page of pages) {
2820
+ const code = await buildCompileCss(page, [], /* @__PURE__ */ new Set()) || "";
2821
+ const filename = `${page.path.replace(/\//g, "_")}`;
2822
+ if (root) {
2823
+ const subDir = `${getTargetPath()}/${root}`;
2824
+ if (!fs6.existsSync(subDir)) {
2825
+ fs6.mkdirSync(subDir, { recursive: true });
2826
+ }
2827
+ fs6.writeFileSync(`${subDir}/${filename}.css`, code);
2828
+ } else {
2829
+ const mainDir = `${getTargetPath()}/main`;
2830
+ if (!fs6.existsSync(mainDir)) {
2831
+ fs6.mkdirSync(mainDir, { recursive: true });
2832
+ }
2833
+ fs6.writeFileSync(`${mainDir}/${filename}.css`, code);
2834
+ }
2835
+ progress.completedTasks++;
2836
+ }
2837
+ }
2838
+ async function buildCompileCss(module, depthChain = [], compiledPaths = /* @__PURE__ */ new Set()) {
2839
+ const currentPath = module.path || module.absolutePath;
2840
+ if (depthChain.includes(currentPath)) {
2841
+ console.warn("[style]", `\u68C0\u6D4B\u5230\u5FAA\u73AF\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
2842
+ return "";
2843
+ }
2844
+ if (depthChain.length > 20) {
2845
+ console.warn("[style]", `\u68C0\u6D4B\u5230\u6DF1\u5EA6\u4F9D\u8D56: ${[...depthChain, currentPath].join(" -> ")}`);
2846
+ return "";
2847
+ }
2848
+ if (compiledPaths.has(currentPath)) {
2849
+ return "";
2850
+ }
2851
+ compiledPaths.add(currentPath);
2852
+ depthChain = [...depthChain, currentPath];
2853
+ let result = await enhanceCSS(module) || "";
2854
+ if (module.usingComponents) {
2855
+ for (const componentInfo of Object.values(module.usingComponents)) {
2856
+ const componentModule = getComponent(componentInfo);
2857
+ if (!componentModule) {
2858
+ continue;
2859
+ }
2860
+ result += await buildCompileCss(componentModule, depthChain, compiledPaths) || "";
2861
+ }
2862
+ }
2863
+ return result;
2864
+ }
2865
+ async function enhanceCSS(module) {
2866
+ const absolutePath = module.absolutePath ? module.absolutePath : getAbsolutePath2(module.path);
2867
+ if (!absolutePath) {
2868
+ return "";
2869
+ }
2870
+ const cacheKey = `${absolutePath}::${module.id || ""}`;
2871
+ const inputCSS = getContentByPath(absolutePath);
2872
+ if (!inputCSS) {
2873
+ return "";
2874
+ }
2875
+ if (compileRes.has(cacheKey)) {
2876
+ return compileRes.get(cacheKey);
2877
+ }
2878
+ let processedCSS = normalizeRootStyleImports(inputCSS);
2879
+ const ext = path5.extname(absolutePath).toLowerCase();
2880
+ try {
2881
+ if (ext === ".less") {
2882
+ const result2 = await less.render(processedCSS, {
2883
+ filename: absolutePath,
2884
+ paths: [path5.dirname(absolutePath), getWorkPath()]
2885
+ });
2886
+ processedCSS = result2.css;
2887
+ } else if (ext === ".scss" || ext === ".sass") {
2888
+ const result2 = sass.compileString(processedCSS, {
2889
+ loadPaths: [path5.dirname(absolutePath), getWorkPath()],
2890
+ syntax: ext === ".sass" ? "indented" : "scss"
2891
+ });
2892
+ processedCSS = result2.css;
2893
+ }
2894
+ } catch (error) {
2895
+ console.error(`[style] \u9884\u5904\u7406\u5668\u7F16\u8BD1\u5931\u8D25 ${absolutePath}:`, error.message);
2896
+ processedCSS = inputCSS;
2897
+ }
2898
+ const fixedCSS = ensureImportSemicolons(processedCSS);
2899
+ let ast;
2900
+ try {
2901
+ ast = postcss.parse(fixedCSS);
2902
+ } catch (error) {
2903
+ console.error(`[style] PostCSS \u89E3\u6790\u5931\u8D25 ${absolutePath}:`, error.message);
2904
+ return "";
2905
+ }
2906
+ const promises2 = [];
2907
+ ast.walk(async (node) => {
2908
+ if (node.type === "atrule" && node.name === "import") {
2909
+ const str = node.params.replace(/^['"]|['"]$/g, "");
2910
+ const importFullPath = resolveStyleImportPath(absolutePath, str);
2911
+ node.remove();
2912
+ promises2.push(buildCompileCss({ absolutePath: importFullPath, id: module.id }, [], /* @__PURE__ */ new Set()));
2913
+ } else if (node.type === "rule") {
2914
+ if (node.selector.includes("::v-deep")) {
2915
+ node.selector = node.selector.replace(/::v-deep\s+(\S[^{]*)/g, ":deep($1)");
2916
+ }
2917
+ if (node.selector.includes(":host")) {
2918
+ node.selector = processHostSelector(node.selector, module.id);
2919
+ }
2920
+ node.selector = selectorParser((selectors) => {
2921
+ selectors.walkTags((tag) => {
2922
+ if (tagWhiteList.includes(tag.value)) {
2923
+ tag.value = `.dd-${tag.value}`;
2924
+ }
2925
+ });
2926
+ }).processSync(node.selector);
2927
+ } else if (node.type === "comment") {
2928
+ node.remove();
2929
+ }
2930
+ });
2931
+ ast.walkDecls((decl) => {
2932
+ decl.value = normalizeCssUrlValue(decl.value, absolutePath);
2933
+ decl.value = transformRpx(decl.value);
2934
+ });
2935
+ const cssCode = ast.toResult().css;
2936
+ const moduleId = module.id;
2937
+ const scopedCode = compileStyle({
2938
+ source: cssCode,
2939
+ id: moduleId,
2940
+ scoped: !!moduleId
2941
+ }).code;
2942
+ const cleanedCode = await removeBaseComponentScope(scopedCode, moduleId);
2943
+ const res = await postcss([
2944
+ autoprefixer({ overrideBrowserslist: ["cover 99.5%"] }),
2945
+ cssnano()
2946
+ ]).process(cleanedCode, { from: void 0 });
2947
+ const importCss = (await Promise.all(promises2)).filter(Boolean).join("");
2948
+ const result = importCss + res.css;
2949
+ compileRes.set(cacheKey, result);
2950
+ return result;
2951
+ }
2952
+ function normalizeCssUrlValue(value, absolutePath) {
2953
+ return value.replace(/url\(([^)]+)\)/g, (fullMatch, rawUrl) => {
2954
+ const cleanedUrl = rawUrl.trim().replace(/^['"]|['"]$/g, "");
2955
+ if (!cleanedUrl || cleanedUrl.startsWith("data:image")) {
2956
+ return fullMatch;
2957
+ }
2958
+ if (cleanedUrl.startsWith("//")) {
2959
+ return `url(https:${cleanedUrl})`;
2960
+ }
2961
+ if (/^(https?:|blob:|data:)/.test(cleanedUrl)) {
2962
+ return fullMatch;
2963
+ }
2964
+ const realSrc = collectAssets(getWorkPath(), absolutePath, cleanedUrl, getTargetPath(), getAppId());
2965
+ return `url(${realSrc})`;
2966
+ });
2967
+ }
2968
+ function getAbsolutePath2(modulePath) {
2969
+ const workPath = getWorkPath();
2970
+ const src = modulePath.startsWith("/") ? modulePath : `/${modulePath}`;
2971
+ for (const ssType of getStyleExts()) {
2972
+ const ssFullPath = `${workPath}${src}${ssType}`;
2973
+ if (fs6.existsSync(ssFullPath)) {
2974
+ return ssFullPath;
2975
+ }
2976
+ const indexSsFullPath = `${workPath}${src}/index${ssType}`;
2977
+ if (fs6.existsSync(indexSsFullPath)) {
2978
+ return indexSsFullPath;
2979
+ }
2980
+ }
2981
+ }
2982
+ function resolveStyleImportPath(absolutePath, importPath, workPath = getWorkPath()) {
2983
+ if (importPath.startsWith("/")) {
2984
+ return path5.join(workPath, importPath);
2985
+ }
2986
+ return path5.resolve(path5.dirname(absolutePath), importPath);
2987
+ }
2988
+ function normalizeRootStyleImports(source, workPath = getWorkPath()) {
2989
+ return source.replace(/(@import\s+(?:\(.*?\)\s*)?(?:url\()?['"])(\/[^'")]+)(['"]\)?)/g, (_, prefix, importPath, suffix) => {
2990
+ return `${prefix}${path5.join(workPath, importPath)}${suffix}`;
2991
+ });
2992
+ }
2993
+ async function removeBaseComponentScope(css, moduleId) {
2994
+ if (!moduleId) return css;
2995
+ const ast = postcss.parse(css);
2996
+ const scopeAttrName = `data-v-${moduleId}`;
2997
+ ast.walkRules((rule) => {
2998
+ const hasBaseComponent = tagWhiteList.some(
2999
+ (tag) => rule.selector.includes(`.dd-${tag}`)
3000
+ );
3001
+ if (hasBaseComponent && rule.selector.includes(scopeAttrName)) {
3002
+ rule.selector = selectorParser((selectors) => {
3003
+ selectors.walkAttributes((attr) => {
3004
+ if (attr.attribute === scopeAttrName) {
3005
+ attr.remove();
3006
+ }
3007
+ });
3008
+ }).processSync(rule.selector);
3009
+ }
3010
+ });
3011
+ return ast.toResult().css;
3012
+ }
3013
+ function ensureImportSemicolons(css) {
3014
+ return css.replace(/@import[^;\n]*$/gm, (match) => {
3015
+ return match.endsWith(";") ? match : `${match};`;
3016
+ });
3017
+ }
3018
+ function processHostSelector(selector, moduleId) {
3019
+ return selector.replace(/^:host$/, `[data-v-${moduleId}]`).replace(/:host\(([^)]+)\)/g, `[data-v-${moduleId}]$1`).replace(/:host\s+/g, `[data-v-${moduleId}] `).replace(/:host(?=\.|#|:)/g, `[data-v-${moduleId}]`);
3020
+ }
3021
+ function __resetStyleState() {
3022
+ compileRes.clear();
3023
+ }
3024
+
3025
+ // src/compile-core.js
3026
+ function makeProgress() {
3027
+ let c = 0;
3028
+ return {
3029
+ get completedTasks() {
3030
+ return c;
3031
+ },
3032
+ set completedTasks(v) {
3033
+ c = v;
3034
+ }
3035
+ };
3036
+ }
3037
+ async function runLogicStage(pages, progress) {
3038
+ const mainRes = await compileJS(pages.mainPages, null, null, progress);
3039
+ for (const [root, sub] of Object.entries(pages.subPages)) {
3040
+ const subRes = await compileJS(sub.info, root, sub.independent ? [] : mainRes, progress);
3041
+ await writeCompileRes(subRes, root);
3042
+ }
3043
+ await writeCompileRes(mainRes, null);
3044
+ }
3045
+ async function runViewStage(pages, progress) {
3046
+ await compileML(pages.mainPages, null, progress);
3047
+ for (const [root, sub] of Object.entries(pages.subPages)) {
3048
+ await compileML(sub.info, root, progress);
3049
+ }
3050
+ }
3051
+ async function runStyleStage(pages, progress) {
3052
+ const styleMain = [{ path: "app", id: "" }, ...pages.mainPages];
3053
+ await compileSS(styleMain, null, progress);
3054
+ for (const [root, sub] of Object.entries(pages.subPages)) {
3055
+ await compileSS(sub.info, root, progress);
3056
+ }
3057
+ }
3058
+ var STAGES = {
3059
+ logic: runLogicStage,
3060
+ view: runViewStage,
3061
+ style: runStyleStage
3062
+ };
3063
+ var STAGE_NAMES = Object.keys(STAGES);
3064
+ async function runStage(stage, pages, { sourcemap = false } = {}) {
3065
+ const run = STAGES[stage];
3066
+ if (!run) throw new Error(`[compiler] unknown compile stage "${stage}" (expected ${STAGE_NAMES.join("/")})`);
3067
+ if (stage === "logic") __setEnableSourcemap(!!sourcemap);
3068
+ await run(pages, makeProgress());
3069
+ }
3070
+ function resetCompilerState() {
3071
+ __resetLogicState();
3072
+ __resetStyleState();
3073
+ __resetViewState();
3074
+ __resetAssets();
3075
+ }
3076
+ var compileChain = Promise.resolve();
3077
+
3078
+ // src/stage-worker-node.js
3079
+ var { parentPort: parentPort2 } = createRequire(import.meta.url)("node:worker_threads");
3080
+ if (!parentPort2) {
3081
+ throw new Error("[compiler] stage-worker-node.js must run inside a worker_threads Worker");
3082
+ }
3083
+ parentPort2.on("message", async (msg) => {
3084
+ const { stage, pages, storeInfo: storeInfo2, sourcemap } = msg || {};
3085
+ try {
3086
+ resetCompilerState();
3087
+ resetStoreInfo(storeInfo2);
3088
+ await runStage(stage, pages, { sourcemap });
3089
+ parentPort2.postMessage({ type: "done", stage, appId: getAppId(), name: getAppName() });
3090
+ } catch (error) {
3091
+ parentPort2.postMessage({
3092
+ type: "error",
3093
+ stage,
3094
+ error: { message: error && error.message, stack: error && error.stack, name: error && error.name }
3095
+ });
3096
+ }
3097
+ });