@dimina/compiler 1.0.13 → 1.0.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/index.cjs +8 -8
- package/dist/bin/index.js +3 -2
- package/dist/core/logic-compiler.cjs +4 -4
- package/dist/core/logic-compiler.js +1 -1
- package/dist/core/style-compiler.cjs +9 -9
- package/dist/core/style-compiler.js +1 -1
- package/dist/core/view-compiler.cjs +11 -6077
- package/dist/core/view-compiler.js +3 -6094
- package/dist/{env-COaZNCzL.js → env-DgCLbrQb.js} +30 -7
- package/dist/{env-lm96AacS.cjs → env-M-7lpbHL.cjs} +34 -18
- package/dist/index.cjs +435 -2
- package/dist/index.js +430 -1
- package/package.json +1 -1
- package/dist/src-D9P-SZeX.js +0 -431
- package/dist/src-DycLk1BL.cjs +0 -440
|
@@ -2,6 +2,33 @@ import path from "node:path";
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import os from "node:os";
|
|
5
|
+
//#region src/common/path-utils.js
|
|
6
|
+
var WINDOWS_FS_PATH_RE = /^(?:[a-zA-Z]:[\\/]|\\\\)/;
|
|
7
|
+
function isWindowsFsPath(targetPath) {
|
|
8
|
+
return typeof targetPath === "string" && (WINDOWS_FS_PATH_RE.test(targetPath) || targetPath.includes("\\"));
|
|
9
|
+
}
|
|
10
|
+
function getFsPathApi(targetPath) {
|
|
11
|
+
return isWindowsFsPath(targetPath) ? path.win32 : path.posix;
|
|
12
|
+
}
|
|
13
|
+
function normalizeToPosixPath(targetPath) {
|
|
14
|
+
return targetPath.replace(/\\/g, "/");
|
|
15
|
+
}
|
|
16
|
+
function resolveMiniProgramPath(workPath, importerPath, sourcePath) {
|
|
17
|
+
const pathApi = getFsPathApi(importerPath || workPath);
|
|
18
|
+
return sourcePath.startsWith("/") ? pathApi.join(workPath, sourcePath) : pathApi.resolve(pathApi.dirname(importerPath), sourcePath);
|
|
19
|
+
}
|
|
20
|
+
function toMiniProgramModuleId(resolvedPath, workPath) {
|
|
21
|
+
const normalizedResolvedPath = normalizeToPosixPath(resolvedPath);
|
|
22
|
+
const normalizedWorkPath = normalizeToPosixPath(workPath);
|
|
23
|
+
let moduleId = normalizedResolvedPath.startsWith(normalizedWorkPath) ? normalizedResolvedPath.slice(normalizedWorkPath.length) : normalizedResolvedPath;
|
|
24
|
+
moduleId = moduleId.replace(/\/+/g, "/");
|
|
25
|
+
if (!moduleId.startsWith("/")) moduleId = `/${moduleId}`;
|
|
26
|
+
return moduleId;
|
|
27
|
+
}
|
|
28
|
+
function getRelativePosixPath(targetPath, rootPath) {
|
|
29
|
+
return normalizeToPosixPath(targetPath).replace(normalizeToPosixPath(rootPath), "").replace(/^\//, "");
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
5
32
|
//#region src/common/art.js
|
|
6
33
|
var artCode = `
|
|
7
34
|
██████╗ ██╗███╗ ███╗██╗███╗ ██╗ █████╗
|
|
@@ -150,9 +177,7 @@ var NpmResolver = class {
|
|
|
150
177
|
* @returns {string} 解析后的路径
|
|
151
178
|
*/
|
|
152
179
|
resolveRelativePath(componentPath, pageFilePath) {
|
|
153
|
-
|
|
154
|
-
const newPath = pageFilePath.slice(0, lastIndex);
|
|
155
|
-
return path.resolve(newPath, componentPath).replace(this.workPath, "");
|
|
180
|
+
return toMiniProgramModuleId(resolveMiniProgramPath(this.workPath, pageFilePath, componentPath), this.workPath);
|
|
156
181
|
}
|
|
157
182
|
/**
|
|
158
183
|
* 解析 npm 组件
|
|
@@ -190,7 +215,7 @@ var NpmResolver = class {
|
|
|
190
215
|
* @returns {string[]} 搜索路径数组
|
|
191
216
|
*/
|
|
192
217
|
generateSearchPaths(pageFilePath) {
|
|
193
|
-
const pathParts = pageFilePath
|
|
218
|
+
const pathParts = getRelativePosixPath(pageFilePath, this.workPath).split("/").slice(0, -1);
|
|
194
219
|
const searchPaths = [];
|
|
195
220
|
for (let i = pathParts.length; i >= 0; i--) {
|
|
196
221
|
const currentPath = pathParts.slice(0, i).join("/");
|
|
@@ -444,10 +469,8 @@ function getModuleId(src, pageFilePath) {
|
|
|
444
469
|
const resolvedAlias = resolveAppAlias(src);
|
|
445
470
|
if (resolvedAlias) return resolvedAlias;
|
|
446
471
|
if (!npmResolver) {
|
|
447
|
-
const lastIndex = pageFilePath.lastIndexOf("/");
|
|
448
|
-
const newPath = pageFilePath.slice(0, lastIndex);
|
|
449
472
|
const workPath = getWorkPath();
|
|
450
|
-
return
|
|
473
|
+
return toMiniProgramModuleId(resolveMiniProgramPath(workPath, pageFilePath, src), workPath);
|
|
451
474
|
}
|
|
452
475
|
return npmResolver.resolveComponentPath(src, pageFilePath);
|
|
453
476
|
}
|
|
@@ -5,7 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
9
8
|
var __copyProps = (to, from, except, desc) => {
|
|
10
9
|
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
10
|
key = keys[i];
|
|
@@ -22,13 +21,40 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
21
|
}) : target, mod));
|
|
23
22
|
//#endregion
|
|
24
23
|
let node_path = require("node:path");
|
|
25
|
-
node_path = __toESM(node_path);
|
|
24
|
+
node_path = __toESM(node_path, 1);
|
|
26
25
|
let node_process = require("node:process");
|
|
27
|
-
node_process = __toESM(node_process);
|
|
26
|
+
node_process = __toESM(node_process, 1);
|
|
28
27
|
let node_fs = require("node:fs");
|
|
29
|
-
node_fs = __toESM(node_fs);
|
|
28
|
+
node_fs = __toESM(node_fs, 1);
|
|
30
29
|
let node_os = require("node:os");
|
|
31
|
-
node_os = __toESM(node_os);
|
|
30
|
+
node_os = __toESM(node_os, 1);
|
|
31
|
+
//#region src/common/path-utils.js
|
|
32
|
+
var WINDOWS_FS_PATH_RE = /^(?:[a-zA-Z]:[\\/]|\\\\)/;
|
|
33
|
+
function isWindowsFsPath(targetPath) {
|
|
34
|
+
return typeof targetPath === "string" && (WINDOWS_FS_PATH_RE.test(targetPath) || targetPath.includes("\\"));
|
|
35
|
+
}
|
|
36
|
+
function getFsPathApi(targetPath) {
|
|
37
|
+
return isWindowsFsPath(targetPath) ? node_path.default.win32 : node_path.default.posix;
|
|
38
|
+
}
|
|
39
|
+
function normalizeToPosixPath(targetPath) {
|
|
40
|
+
return targetPath.replace(/\\/g, "/");
|
|
41
|
+
}
|
|
42
|
+
function resolveMiniProgramPath(workPath, importerPath, sourcePath) {
|
|
43
|
+
const pathApi = getFsPathApi(importerPath || workPath);
|
|
44
|
+
return sourcePath.startsWith("/") ? pathApi.join(workPath, sourcePath) : pathApi.resolve(pathApi.dirname(importerPath), sourcePath);
|
|
45
|
+
}
|
|
46
|
+
function toMiniProgramModuleId(resolvedPath, workPath) {
|
|
47
|
+
const normalizedResolvedPath = normalizeToPosixPath(resolvedPath);
|
|
48
|
+
const normalizedWorkPath = normalizeToPosixPath(workPath);
|
|
49
|
+
let moduleId = normalizedResolvedPath.startsWith(normalizedWorkPath) ? normalizedResolvedPath.slice(normalizedWorkPath.length) : normalizedResolvedPath;
|
|
50
|
+
moduleId = moduleId.replace(/\/+/g, "/");
|
|
51
|
+
if (!moduleId.startsWith("/")) moduleId = `/${moduleId}`;
|
|
52
|
+
return moduleId;
|
|
53
|
+
}
|
|
54
|
+
function getRelativePosixPath(targetPath, rootPath) {
|
|
55
|
+
return normalizeToPosixPath(targetPath).replace(normalizeToPosixPath(rootPath), "").replace(/^\//, "");
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
32
58
|
//#region src/common/art.js
|
|
33
59
|
var artCode = `
|
|
34
60
|
██████╗ ██╗███╗ ███╗██╗███╗ ██╗ █████╗
|
|
@@ -177,9 +203,7 @@ var NpmResolver = class {
|
|
|
177
203
|
* @returns {string} 解析后的路径
|
|
178
204
|
*/
|
|
179
205
|
resolveRelativePath(componentPath, pageFilePath) {
|
|
180
|
-
|
|
181
|
-
const newPath = pageFilePath.slice(0, lastIndex);
|
|
182
|
-
return node_path.default.resolve(newPath, componentPath).replace(this.workPath, "");
|
|
206
|
+
return toMiniProgramModuleId(resolveMiniProgramPath(this.workPath, pageFilePath, componentPath), this.workPath);
|
|
183
207
|
}
|
|
184
208
|
/**
|
|
185
209
|
* 解析 npm 组件
|
|
@@ -217,7 +241,7 @@ var NpmResolver = class {
|
|
|
217
241
|
* @returns {string[]} 搜索路径数组
|
|
218
242
|
*/
|
|
219
243
|
generateSearchPaths(pageFilePath) {
|
|
220
|
-
const pathParts = pageFilePath
|
|
244
|
+
const pathParts = getRelativePosixPath(pageFilePath, this.workPath).split("/").slice(0, -1);
|
|
221
245
|
const searchPaths = [];
|
|
222
246
|
for (let i = pathParts.length; i >= 0; i--) {
|
|
223
247
|
const currentPath = pathParts.slice(0, i).join("/");
|
|
@@ -471,10 +495,8 @@ function getModuleId(src, pageFilePath) {
|
|
|
471
495
|
const resolvedAlias = resolveAppAlias(src);
|
|
472
496
|
if (resolvedAlias) return resolvedAlias;
|
|
473
497
|
if (!npmResolver) {
|
|
474
|
-
const lastIndex = pageFilePath.lastIndexOf("/");
|
|
475
|
-
const newPath = pageFilePath.slice(0, lastIndex);
|
|
476
498
|
const workPath = getWorkPath();
|
|
477
|
-
return
|
|
499
|
+
return toMiniProgramModuleId(resolveMiniProgramPath(workPath, pageFilePath, src), workPath);
|
|
478
500
|
}
|
|
479
501
|
return npmResolver.resolveComponentPath(src, pageFilePath);
|
|
480
502
|
}
|
|
@@ -561,12 +583,6 @@ function getPages() {
|
|
|
561
583
|
};
|
|
562
584
|
}
|
|
563
585
|
//#endregion
|
|
564
|
-
Object.defineProperty(exports, "__commonJSMin", {
|
|
565
|
-
enumerable: true,
|
|
566
|
-
get: function() {
|
|
567
|
-
return __commonJSMin;
|
|
568
|
-
}
|
|
569
|
-
});
|
|
570
586
|
Object.defineProperty(exports, "__toESM", {
|
|
571
587
|
enumerable: true,
|
|
572
588
|
get: function() {
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,435 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const require_env = require("./env-M-7lpbHL.cjs");
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
node_path = require_env.__toESM(node_path, 1);
|
|
4
|
+
let node_url = require("node:url");
|
|
5
|
+
let node_worker_threads = require("node:worker_threads");
|
|
6
|
+
let listr2 = require("listr2");
|
|
7
|
+
let node_process = require("node:process");
|
|
8
|
+
node_process = require_env.__toESM(node_process, 1);
|
|
9
|
+
let node_fs = require("node:fs");
|
|
10
|
+
node_fs = require_env.__toESM(node_fs, 1);
|
|
11
|
+
let node_os = require("node:os");
|
|
12
|
+
node_os = require_env.__toESM(node_os, 1);
|
|
13
|
+
//#region src/common/publish.js
|
|
14
|
+
function createDist() {
|
|
15
|
+
const distPath = require_env.getTargetPath();
|
|
16
|
+
if (node_fs.default.existsSync(distPath)) node_fs.default.rmSync(distPath, {
|
|
17
|
+
recursive: true,
|
|
18
|
+
force: true
|
|
19
|
+
});
|
|
20
|
+
node_fs.default.mkdirSync(distPath, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 发布到指定目录
|
|
24
|
+
* @param {string} dist 目标路径
|
|
25
|
+
* @param {boolean} useAppIdDir 是否在路径中包含appId
|
|
26
|
+
*/
|
|
27
|
+
function publishToDist(dist, useAppIdDir = true) {
|
|
28
|
+
const distPath = require_env.getTargetPath();
|
|
29
|
+
const appId = require_env.getAppId();
|
|
30
|
+
const absolutePath = useAppIdDir ? `${node_path.default.resolve(node_process.default.cwd(), dist)}${node_path.default.sep}${appId}` : `${node_path.default.resolve(node_process.default.cwd(), dist)}`;
|
|
31
|
+
if (node_fs.default.existsSync(absolutePath)) node_fs.default.rmSync(absolutePath, {
|
|
32
|
+
recursive: true,
|
|
33
|
+
force: true
|
|
34
|
+
});
|
|
35
|
+
node_fs.default.mkdirSync(absolutePath, { recursive: true });
|
|
36
|
+
function copyDir(src, dest) {
|
|
37
|
+
node_fs.default.mkdirSync(dest, { recursive: true });
|
|
38
|
+
const entries = node_fs.default.readdirSync(src, { withFileTypes: true });
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const srcPath = node_path.default.join(src, entry.name);
|
|
41
|
+
const destPath = node_path.default.join(dest, entry.name);
|
|
42
|
+
if (entry.isDirectory()) copyDir(srcPath, destPath);
|
|
43
|
+
else node_fs.default.copyFileSync(srcPath, destPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
copyDir(distPath, absolutePath);
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/common/worker-pool.js
|
|
50
|
+
function getCGroupCPUCount() {
|
|
51
|
+
try {
|
|
52
|
+
const quotaPath = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us";
|
|
53
|
+
const periodPath = "/sys/fs/cgroup/cpu/cpu.cfs_period_us";
|
|
54
|
+
if (node_fs.default.existsSync(quotaPath) && node_fs.default.existsSync(periodPath)) {
|
|
55
|
+
const quota = Number.parseInt(node_fs.default.readFileSync(quotaPath, "utf8"));
|
|
56
|
+
const period = Number.parseInt(node_fs.default.readFileSync(periodPath, "utf8"));
|
|
57
|
+
if (quota > 0) return Math.max(1, Math.floor(quota / period));
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.warn("Failed to read CPU limits from cgroup:", e.message);
|
|
61
|
+
}
|
|
62
|
+
return node_os.default.cpus().length;
|
|
63
|
+
}
|
|
64
|
+
function getCGroupMemoryLimit() {
|
|
65
|
+
try {
|
|
66
|
+
const memLimitPath = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
|
|
67
|
+
if (node_fs.default.existsSync(memLimitPath)) {
|
|
68
|
+
const memLimit = Number.parseInt(node_fs.default.readFileSync(memLimitPath, "utf8"));
|
|
69
|
+
if (memLimit < Number.Infinity && memLimit > 0) return memLimit;
|
|
70
|
+
}
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.warn("Failed to read memory limits from cgroup:", e.message);
|
|
73
|
+
}
|
|
74
|
+
return node_os.default.totalmem();
|
|
75
|
+
}
|
|
76
|
+
var MAX_WORKERS = Math.max(1, Math.min(4, Math.floor(getCGroupCPUCount() / 4)));
|
|
77
|
+
var WorkerPool = class {
|
|
78
|
+
constructor(maxWorkers = MAX_WORKERS) {
|
|
79
|
+
this.maxWorkers = maxWorkers;
|
|
80
|
+
this.activeWorkers = 0;
|
|
81
|
+
this.queue = [];
|
|
82
|
+
this.memoryLimit = Math.floor(getCGroupMemoryLimit() * .6 / maxWorkers);
|
|
83
|
+
}
|
|
84
|
+
async runWorker(workerCreator) {
|
|
85
|
+
if (this.activeWorkers >= this.maxWorkers) await new Promise((resolve) => this.queue.push(resolve));
|
|
86
|
+
this.activeWorkers++;
|
|
87
|
+
try {
|
|
88
|
+
return await workerCreator();
|
|
89
|
+
} finally {
|
|
90
|
+
this.activeWorkers--;
|
|
91
|
+
if (this.queue.length > 0) this.queue.shift()();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
getWorkerOptions() {
|
|
95
|
+
const memoryMb = Math.floor(this.memoryLimit / (1024 * 1024));
|
|
96
|
+
return { resourceLimits: {
|
|
97
|
+
maxOldGenerationSizeMb: Math.max(256, memoryMb),
|
|
98
|
+
maxYoungGenerationSizeMb: Math.max(64, Math.floor(memoryMb / 4)),
|
|
99
|
+
codeRangeSizeMb: 64
|
|
100
|
+
} };
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var workerPool = new WorkerPool();
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/common/npm-builder.js
|
|
106
|
+
/**
|
|
107
|
+
* npm 构建工具
|
|
108
|
+
* 用于处理小程序 npm 包的构建和管理
|
|
109
|
+
*/
|
|
110
|
+
var NpmBuilder = class {
|
|
111
|
+
constructor(workPath, targetPath) {
|
|
112
|
+
this.workPath = workPath;
|
|
113
|
+
this.targetPath = targetPath;
|
|
114
|
+
this.builtPackages = /* @__PURE__ */ new Set();
|
|
115
|
+
this.packageDependencies = /* @__PURE__ */ new Map();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 构建 npm 包
|
|
119
|
+
* 扫描 miniprogram_npm 目录并构建相关包
|
|
120
|
+
*/
|
|
121
|
+
async buildNpmPackages() {
|
|
122
|
+
const miniprogramNpmPaths = this.findMiniprogramNpmDirs();
|
|
123
|
+
for (const npmPath of miniprogramNpmPaths) await this.buildNpmDir(npmPath);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 查找所有 miniprogram_npm 目录
|
|
127
|
+
* @returns {string[]} miniprogram_npm 目录路径数组
|
|
128
|
+
*/
|
|
129
|
+
findMiniprogramNpmDirs() {
|
|
130
|
+
const npmDirs = [];
|
|
131
|
+
const scanDir = (dir, relativePath = "") => {
|
|
132
|
+
if (!node_fs.default.existsSync(dir)) return;
|
|
133
|
+
const items = node_fs.default.readdirSync(dir, { withFileTypes: true });
|
|
134
|
+
for (const item of items) if (item.isDirectory()) {
|
|
135
|
+
const itemPath = node_path.default.join(dir, item.name);
|
|
136
|
+
const itemRelativePath = relativePath ? `${relativePath}/${item.name}` : item.name;
|
|
137
|
+
if (item.name === "miniprogram_npm") npmDirs.push(itemRelativePath);
|
|
138
|
+
else scanDir(itemPath, itemRelativePath);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
scanDir(this.workPath);
|
|
142
|
+
return npmDirs;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 构建指定的 miniprogram_npm 目录
|
|
146
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
147
|
+
*/
|
|
148
|
+
async buildNpmDir(npmDirPath) {
|
|
149
|
+
const fullNpmPath = node_path.default.join(this.workPath, npmDirPath);
|
|
150
|
+
if (!node_fs.default.existsSync(fullNpmPath)) return;
|
|
151
|
+
const packages = node_fs.default.readdirSync(fullNpmPath, { withFileTypes: true }).filter((item) => item.isDirectory()).map((item) => item.name);
|
|
152
|
+
for (const packageName of packages) await this.buildPackage(packageName, npmDirPath);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 构建单个 npm 包
|
|
156
|
+
* @param {string} packageName 包名
|
|
157
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
158
|
+
*/
|
|
159
|
+
async buildPackage(packageName, npmDirPath) {
|
|
160
|
+
const packageKey = `${npmDirPath}/${packageName}`;
|
|
161
|
+
if (this.builtPackages.has(packageKey)) return;
|
|
162
|
+
const packagePath = node_path.default.join(this.workPath, npmDirPath, packageName);
|
|
163
|
+
const targetPackagePath = node_path.default.join(this.targetPath, npmDirPath, packageName);
|
|
164
|
+
if (!node_fs.default.existsSync(node_path.default.dirname(targetPackagePath))) node_fs.default.mkdirSync(node_path.default.dirname(targetPackagePath), { recursive: true });
|
|
165
|
+
await this.copyPackageFiles(packagePath, targetPackagePath);
|
|
166
|
+
await this.processDependencies(packageName, packagePath, npmDirPath);
|
|
167
|
+
this.builtPackages.add(packageKey);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 复制包文件
|
|
171
|
+
* @param {string} sourcePath 源路径
|
|
172
|
+
* @param {string} targetPath 目标路径
|
|
173
|
+
*/
|
|
174
|
+
async copyPackageFiles(sourcePath, targetPath) {
|
|
175
|
+
if (!node_fs.default.existsSync(sourcePath)) return;
|
|
176
|
+
if (!node_fs.default.existsSync(targetPath)) node_fs.default.mkdirSync(targetPath, { recursive: true });
|
|
177
|
+
const items = node_fs.default.readdirSync(sourcePath, { withFileTypes: true });
|
|
178
|
+
for (const item of items) {
|
|
179
|
+
const sourceItemPath = node_path.default.join(sourcePath, item.name);
|
|
180
|
+
const targetItemPath = node_path.default.join(targetPath, item.name);
|
|
181
|
+
if (item.isDirectory()) await this.copyPackageFiles(sourceItemPath, targetItemPath);
|
|
182
|
+
else if (this.isMiniprogramFile(item.name)) node_fs.default.copyFileSync(sourceItemPath, targetItemPath);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* 检查是否为小程序相关文件
|
|
187
|
+
* @param {string} filename 文件名
|
|
188
|
+
* @returns {boolean} 是否为小程序文件
|
|
189
|
+
*/
|
|
190
|
+
isMiniprogramFile(filename) {
|
|
191
|
+
const miniprogramExts = [
|
|
192
|
+
".js",
|
|
193
|
+
".json",
|
|
194
|
+
".wxml",
|
|
195
|
+
".wxss",
|
|
196
|
+
".wxs",
|
|
197
|
+
".ts",
|
|
198
|
+
".less",
|
|
199
|
+
".scss",
|
|
200
|
+
".styl"
|
|
201
|
+
];
|
|
202
|
+
const ext = node_path.default.extname(filename).toLowerCase();
|
|
203
|
+
return miniprogramExts.includes(ext) || filename === "package.json" || filename === "README.md" || filename.startsWith(".");
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* 处理包依赖
|
|
207
|
+
* @param {string} packageName 包名
|
|
208
|
+
* @param {string} packagePath 包路径
|
|
209
|
+
* @param {string} npmDirPath npm 目录路径
|
|
210
|
+
*/
|
|
211
|
+
async processDependencies(packageName, packagePath, npmDirPath) {
|
|
212
|
+
const packageJsonPath = node_path.default.join(packagePath, "package.json");
|
|
213
|
+
if (!node_fs.default.existsSync(packageJsonPath)) return;
|
|
214
|
+
try {
|
|
215
|
+
const packageJson = JSON.parse(node_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
216
|
+
const dependencies = {
|
|
217
|
+
...packageJson.dependencies,
|
|
218
|
+
...packageJson.peerDependencies
|
|
219
|
+
};
|
|
220
|
+
if (dependencies && Object.keys(dependencies).length > 0) {
|
|
221
|
+
this.packageDependencies.set(packageName, dependencies);
|
|
222
|
+
for (const depName of Object.keys(dependencies)) await this.buildPackage(depName, npmDirPath);
|
|
223
|
+
}
|
|
224
|
+
} catch (e) {
|
|
225
|
+
console.warn(`[npm-builder] 解析 package.json 失败: ${packageJsonPath}`, e.message);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 验证 npm 包的完整性
|
|
230
|
+
* @param {string} packageName 包名
|
|
231
|
+
* @param {string} packagePath 包路径
|
|
232
|
+
* @returns {boolean} 是否有效
|
|
233
|
+
*/
|
|
234
|
+
validatePackage(packageName, packagePath) {
|
|
235
|
+
for (const file of ["package.json"]) if (!node_fs.default.existsSync(node_path.default.join(packagePath, file))) {
|
|
236
|
+
console.warn(`[npm-builder] 包 ${packageName} 缺少必要文件: ${file}`);
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const packageJsonPath = node_path.default.join(packagePath, "package.json");
|
|
241
|
+
const packageJson = JSON.parse(node_fs.default.readFileSync(packageJsonPath, "utf-8"));
|
|
242
|
+
if (!packageJson.name || !packageJson.version) {
|
|
243
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 格式不正确`);
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
} catch (e) {
|
|
247
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 解析失败:`, e.message);
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 获取已构建的包列表
|
|
254
|
+
* @returns {string[]} 已构建的包列表
|
|
255
|
+
*/
|
|
256
|
+
getBuiltPackages() {
|
|
257
|
+
return Array.from(this.builtPackages);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 获取包依赖关系
|
|
261
|
+
* @returns {Map} 包依赖关系映射
|
|
262
|
+
*/
|
|
263
|
+
getPackageDependencies() {
|
|
264
|
+
return this.packageDependencies;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 清理构建缓存
|
|
268
|
+
*/
|
|
269
|
+
clearCache() {
|
|
270
|
+
this.builtPackages.clear();
|
|
271
|
+
this.packageDependencies.clear();
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
//#endregion
|
|
275
|
+
//#region src/core/config-compiler.js
|
|
276
|
+
/**
|
|
277
|
+
*
|
|
278
|
+
* 编译项目配置文件 app-config.json
|
|
279
|
+
*/
|
|
280
|
+
function compileConfig() {
|
|
281
|
+
const compileResInfo = {
|
|
282
|
+
app: require_env.getAppConfigInfo(),
|
|
283
|
+
modules: require_env.getPageConfigInfo(),
|
|
284
|
+
projectName: require_env.getAppName()
|
|
285
|
+
};
|
|
286
|
+
const json = JSON.stringify(compileResInfo, null, 4);
|
|
287
|
+
const mainDir = `${require_env.getTargetPath()}/main`;
|
|
288
|
+
if (!node_fs.default.existsSync(mainDir)) node_fs.default.mkdirSync(mainDir, { recursive: true });
|
|
289
|
+
node_fs.default.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/index.js
|
|
293
|
+
var isPrinted = false;
|
|
294
|
+
/**
|
|
295
|
+
* 构建命令入口
|
|
296
|
+
* @param {string} targetPath 编译产物目标路径
|
|
297
|
+
* @param {string} workPath 编译工作目录
|
|
298
|
+
* @param {boolean} useAppIdDir 产物根目录是否包含appId
|
|
299
|
+
*/
|
|
300
|
+
async function build(targetPath, workPath, useAppIdDir = true) {
|
|
301
|
+
if (!isPrinted) {
|
|
302
|
+
require_env.art_default();
|
|
303
|
+
isPrinted = true;
|
|
304
|
+
}
|
|
305
|
+
const tasks = new listr2.Listr([
|
|
306
|
+
{
|
|
307
|
+
title: "准备项目编译环境",
|
|
308
|
+
task: (_, task) => task.newListr([
|
|
309
|
+
{
|
|
310
|
+
title: "收集配置信息",
|
|
311
|
+
task: (ctx) => {
|
|
312
|
+
ctx.storeInfo = require_env.storeInfo(workPath);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
title: "准备产物目录",
|
|
317
|
+
task: () => {
|
|
318
|
+
createDist();
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
title: "编译配置信息",
|
|
323
|
+
task: () => {
|
|
324
|
+
compileConfig();
|
|
325
|
+
}
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
title: "构建 npm 包",
|
|
329
|
+
task: async () => {
|
|
330
|
+
await new NpmBuilder(require_env.getWorkPath(), require_env.getTargetPath()).buildNpmPackages();
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
], { concurrent: false })
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
title: `开始编译:${workPath.split("/").pop()}`,
|
|
337
|
+
task: (ctx, task) => {
|
|
338
|
+
const pages = require_env.getPages();
|
|
339
|
+
ctx.pages = pages;
|
|
340
|
+
return task.newListr([
|
|
341
|
+
{
|
|
342
|
+
title: "编译页面文件",
|
|
343
|
+
task: async (ctx, task) => {
|
|
344
|
+
return runCompileInWorker("view", ctx, task);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
title: "编译页面逻辑",
|
|
349
|
+
task: async (ctx, task) => {
|
|
350
|
+
return runCompileInWorker("logic", ctx, task);
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
title: "编译样式文件",
|
|
355
|
+
task: async (ctx, task) => {
|
|
356
|
+
pages.mainPages.unshift({
|
|
357
|
+
path: "app",
|
|
358
|
+
id: ""
|
|
359
|
+
});
|
|
360
|
+
return runCompileInWorker("style", ctx, task);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
], { concurrent: true });
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
title: "输出编译产物",
|
|
368
|
+
task: () => {
|
|
369
|
+
publishToDist(targetPath, useAppIdDir);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
], { concurrent: false });
|
|
373
|
+
try {
|
|
374
|
+
const context = await tasks.run();
|
|
375
|
+
return {
|
|
376
|
+
appId: require_env.getAppId(),
|
|
377
|
+
name: require_env.getAppName(),
|
|
378
|
+
path: require_env.getAppConfigInfo().entryPagePath || context.pages.mainPages[1].path
|
|
379
|
+
};
|
|
380
|
+
} catch (e) {
|
|
381
|
+
console.error(`${workPath} 编译出错: ${e.message}\n${e.stack}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function runCompileInWorker(script, ctx, task) {
|
|
385
|
+
return workerPool.runWorker(() => new Promise((resolve, reject) => {
|
|
386
|
+
const worker = new node_worker_threads.Worker(node_path.default.join(node_path.default.dirname((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href)), `core/${script}-compiler.js`), workerPool.getWorkerOptions());
|
|
387
|
+
const totalTasks = Object.keys(ctx.pages.mainPages).length + Object.values(ctx.pages.subPages).reduce((sum, item) => sum + item.info.length, 0);
|
|
388
|
+
let isResolved = false;
|
|
389
|
+
let workerError = null;
|
|
390
|
+
const handleError = (error) => {
|
|
391
|
+
if (isResolved) return;
|
|
392
|
+
isResolved = true;
|
|
393
|
+
worker.terminate();
|
|
394
|
+
reject(error);
|
|
395
|
+
};
|
|
396
|
+
worker.postMessage({
|
|
397
|
+
pages: ctx.pages,
|
|
398
|
+
storeInfo: ctx.storeInfo
|
|
399
|
+
});
|
|
400
|
+
worker.on("message", (message) => {
|
|
401
|
+
try {
|
|
402
|
+
if (message.completedTasks) {
|
|
403
|
+
const progress = message.completedTasks / totalTasks;
|
|
404
|
+
const percentage = progress * 100;
|
|
405
|
+
const barLength = 30;
|
|
406
|
+
const filledLength = Math.ceil(barLength * progress);
|
|
407
|
+
task.output = `[${"█".repeat(filledLength) + "░".repeat(barLength - filledLength)}] ${percentage.toFixed(2)}%`;
|
|
408
|
+
}
|
|
409
|
+
if (message.success) {
|
|
410
|
+
if (isResolved) return;
|
|
411
|
+
isResolved = true;
|
|
412
|
+
worker.terminate();
|
|
413
|
+
resolve();
|
|
414
|
+
} else if (message.error) {
|
|
415
|
+
const error = new Error(message.error.message || message.error);
|
|
416
|
+
if (message.error.stack) error.stack = message.error.stack;
|
|
417
|
+
if (message.error.file) error.file = message.error.file;
|
|
418
|
+
if (message.error.line) error.line = message.error.line;
|
|
419
|
+
handleError(error);
|
|
420
|
+
}
|
|
421
|
+
} catch (err) {
|
|
422
|
+
handleError(/* @__PURE__ */ new Error(`Error processing worker message: ${err.message}\n${err.stack}`));
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
worker.on("error", (err) => {
|
|
426
|
+
workerError = err;
|
|
427
|
+
handleError(err);
|
|
428
|
+
});
|
|
429
|
+
worker.on("exit", (code) => {
|
|
430
|
+
if (code !== 0 && !isResolved) handleError(workerError || /* @__PURE__ */ new Error(code === 1 ? "Worker terminated due to reaching memory limit: JS heap out of memory" : `Worker stopped with exit code ${code}`));
|
|
431
|
+
});
|
|
432
|
+
}));
|
|
433
|
+
}
|
|
434
|
+
//#endregion
|
|
435
|
+
module.exports = build;
|