@dimina/compiler 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -0
- package/dist/bin/index.cjs +3 -3
- package/dist/bin/index.js +3 -3
- package/dist/core/logic-compiler.cjs +125 -35
- package/dist/core/logic-compiler.js +125 -36
- package/dist/core/style-compiler.cjs +77 -19
- package/dist/core/style-compiler.js +59 -19
- package/dist/core/view-compiler.cjs +647 -145
- package/dist/core/view-compiler.js +645 -144
- package/dist/env-Cmen1qwy.cjs +543 -0
- package/dist/env-Csj3AHY4.js +544 -0
- package/dist/index.cjs +259 -37
- package/dist/index.js +259 -37
- package/package.json +14 -11
- package/dist/env-CezfCSQz.js +0 -299
- package/dist/env-Chow6VXH.cjs +0 -298
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const path = require("node:path");
|
|
3
|
-
const node_worker_threads = require("node:worker_threads");
|
|
4
3
|
const node_url = require("node:url");
|
|
4
|
+
const node_worker_threads = require("node:worker_threads");
|
|
5
5
|
const listr2 = require("listr2");
|
|
6
|
-
const env = require("./env-Chow6VXH.cjs");
|
|
7
|
-
const fs = require("node:fs");
|
|
8
6
|
const process = require("node:process");
|
|
9
|
-
const
|
|
7
|
+
const fs = require("node:fs");
|
|
8
|
+
const env = require("./env-Cmen1qwy.cjs");
|
|
10
9
|
const os = require("node:os");
|
|
11
10
|
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
12
11
|
const artCode = `
|
|
@@ -20,32 +19,35 @@ const artCode = `
|
|
|
20
19
|
function artCode$1() {
|
|
21
20
|
console.log(artCode);
|
|
22
21
|
}
|
|
23
|
-
function compileConfig() {
|
|
24
|
-
const compileResInfo = {
|
|
25
|
-
app: env.getAppConfigInfo(),
|
|
26
|
-
modules: env.getPageConfigInfo()
|
|
27
|
-
};
|
|
28
|
-
const json = JSON.stringify(compileResInfo, null, 4);
|
|
29
|
-
const mainDir = `${env.getTargetPath()}/main`;
|
|
30
|
-
if (!fs.existsSync(mainDir)) {
|
|
31
|
-
fs.mkdirSync(mainDir);
|
|
32
|
-
}
|
|
33
|
-
fs.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
34
|
-
}
|
|
35
22
|
function createDist() {
|
|
36
23
|
const distPath = env.getTargetPath();
|
|
37
|
-
if (
|
|
38
|
-
|
|
24
|
+
if (fs.existsSync(distPath)) {
|
|
25
|
+
fs.rmSync(distPath, { recursive: true, force: true });
|
|
39
26
|
}
|
|
40
|
-
|
|
27
|
+
fs.mkdirSync(distPath, { recursive: true });
|
|
41
28
|
}
|
|
42
29
|
function publishToDist(dist, useAppIdDir = true) {
|
|
43
30
|
const distPath = env.getTargetPath();
|
|
44
31
|
const appId = env.getAppId();
|
|
45
|
-
const absolutePath = useAppIdDir ? `${path.resolve(process.cwd(), dist)}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
const absolutePath = useAppIdDir ? `${path.resolve(process.cwd(), dist)}${path.sep}${appId}` : `${path.resolve(process.cwd(), dist)}`;
|
|
33
|
+
if (fs.existsSync(absolutePath)) {
|
|
34
|
+
fs.rmSync(absolutePath, { recursive: true, force: true });
|
|
35
|
+
}
|
|
36
|
+
fs.mkdirSync(absolutePath, { recursive: true });
|
|
37
|
+
function copyDir(src, dest) {
|
|
38
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
39
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
const srcPath = path.join(src, entry.name);
|
|
42
|
+
const destPath = path.join(dest, entry.name);
|
|
43
|
+
if (entry.isDirectory()) {
|
|
44
|
+
copyDir(srcPath, destPath);
|
|
45
|
+
} else {
|
|
46
|
+
fs.copyFileSync(srcPath, destPath);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
copyDir(distPath, absolutePath);
|
|
49
51
|
}
|
|
50
52
|
function getCGroupCPUCount() {
|
|
51
53
|
try {
|
|
@@ -68,7 +70,7 @@ function getCGroupMemoryLimit() {
|
|
|
68
70
|
const memLimitPath = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
|
|
69
71
|
if (fs.existsSync(memLimitPath)) {
|
|
70
72
|
const memLimit = Number.parseInt(fs.readFileSync(memLimitPath, "utf8"));
|
|
71
|
-
if (memLimit < Infinity && memLimit > 0) {
|
|
73
|
+
if (memLimit < Number.Infinity && memLimit > 0) {
|
|
72
74
|
return memLimit;
|
|
73
75
|
}
|
|
74
76
|
}
|
|
@@ -112,6 +114,206 @@ class WorkerPool {
|
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
116
|
const workerPool = new WorkerPool();
|
|
117
|
+
class NpmBuilder {
|
|
118
|
+
constructor(workPath, targetPath) {
|
|
119
|
+
this.workPath = workPath;
|
|
120
|
+
this.targetPath = targetPath;
|
|
121
|
+
this.builtPackages = /* @__PURE__ */ new Set();
|
|
122
|
+
this.packageDependencies = /* @__PURE__ */ new Map();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 构建 npm 包
|
|
126
|
+
* 扫描 miniprogram_npm 目录并构建相关包
|
|
127
|
+
*/
|
|
128
|
+
async buildNpmPackages() {
|
|
129
|
+
const miniprogramNpmPaths = this.findMiniprogramNpmDirs();
|
|
130
|
+
for (const npmPath of miniprogramNpmPaths) {
|
|
131
|
+
await this.buildNpmDir(npmPath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 查找所有 miniprogram_npm 目录
|
|
136
|
+
* @returns {string[]} miniprogram_npm 目录路径数组
|
|
137
|
+
*/
|
|
138
|
+
findMiniprogramNpmDirs() {
|
|
139
|
+
const npmDirs = [];
|
|
140
|
+
const scanDir = (dir, relativePath = "") => {
|
|
141
|
+
if (!fs.existsSync(dir)) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
145
|
+
for (const item of items) {
|
|
146
|
+
if (item.isDirectory()) {
|
|
147
|
+
const itemPath = path.join(dir, item.name);
|
|
148
|
+
const itemRelativePath = relativePath ? `${relativePath}/${item.name}` : item.name;
|
|
149
|
+
if (item.name === "miniprogram_npm") {
|
|
150
|
+
npmDirs.push(itemRelativePath);
|
|
151
|
+
} else {
|
|
152
|
+
scanDir(itemPath, itemRelativePath);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
scanDir(this.workPath);
|
|
158
|
+
return npmDirs;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 构建指定的 miniprogram_npm 目录
|
|
162
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
163
|
+
*/
|
|
164
|
+
async buildNpmDir(npmDirPath) {
|
|
165
|
+
const fullNpmPath = path.join(this.workPath, npmDirPath);
|
|
166
|
+
if (!fs.existsSync(fullNpmPath)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const packages = fs.readdirSync(fullNpmPath, { withFileTypes: true }).filter((item) => item.isDirectory()).map((item) => item.name);
|
|
170
|
+
for (const packageName of packages) {
|
|
171
|
+
await this.buildPackage(packageName, npmDirPath);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* 构建单个 npm 包
|
|
176
|
+
* @param {string} packageName 包名
|
|
177
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
178
|
+
*/
|
|
179
|
+
async buildPackage(packageName, npmDirPath) {
|
|
180
|
+
const packageKey = `${npmDirPath}/${packageName}`;
|
|
181
|
+
if (this.builtPackages.has(packageKey)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const packagePath = path.join(this.workPath, npmDirPath, packageName);
|
|
185
|
+
const targetPackagePath = path.join(this.targetPath, npmDirPath, packageName);
|
|
186
|
+
if (!fs.existsSync(path.dirname(targetPackagePath))) {
|
|
187
|
+
fs.mkdirSync(path.dirname(targetPackagePath), { recursive: true });
|
|
188
|
+
}
|
|
189
|
+
await this.copyPackageFiles(packagePath, targetPackagePath);
|
|
190
|
+
await this.processDependencies(packageName, packagePath, npmDirPath);
|
|
191
|
+
this.builtPackages.add(packageKey);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* 复制包文件
|
|
195
|
+
* @param {string} sourcePath 源路径
|
|
196
|
+
* @param {string} targetPath 目标路径
|
|
197
|
+
*/
|
|
198
|
+
async copyPackageFiles(sourcePath, targetPath) {
|
|
199
|
+
if (!fs.existsSync(sourcePath)) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (!fs.existsSync(targetPath)) {
|
|
203
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
204
|
+
}
|
|
205
|
+
const items = fs.readdirSync(sourcePath, { withFileTypes: true });
|
|
206
|
+
for (const item of items) {
|
|
207
|
+
const sourceItemPath = path.join(sourcePath, item.name);
|
|
208
|
+
const targetItemPath = path.join(targetPath, item.name);
|
|
209
|
+
if (item.isDirectory()) {
|
|
210
|
+
await this.copyPackageFiles(sourceItemPath, targetItemPath);
|
|
211
|
+
} else {
|
|
212
|
+
if (this.isMiniprogramFile(item.name)) {
|
|
213
|
+
fs.copyFileSync(sourceItemPath, targetItemPath);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* 检查是否为小程序相关文件
|
|
220
|
+
* @param {string} filename 文件名
|
|
221
|
+
* @returns {boolean} 是否为小程序文件
|
|
222
|
+
*/
|
|
223
|
+
isMiniprogramFile(filename) {
|
|
224
|
+
const miniprogramExts = [".js", ".json", ".wxml", ".wxss", ".wxs", ".ts", ".less", ".scss", ".styl"];
|
|
225
|
+
const ext = path.extname(filename).toLowerCase();
|
|
226
|
+
return miniprogramExts.includes(ext) || filename === "package.json" || filename === "README.md" || filename.startsWith(".");
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* 处理包依赖
|
|
230
|
+
* @param {string} packageName 包名
|
|
231
|
+
* @param {string} packagePath 包路径
|
|
232
|
+
* @param {string} npmDirPath npm 目录路径
|
|
233
|
+
*/
|
|
234
|
+
async processDependencies(packageName, packagePath, npmDirPath) {
|
|
235
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
236
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
241
|
+
const dependencies = {
|
|
242
|
+
...packageJson.dependencies,
|
|
243
|
+
...packageJson.peerDependencies
|
|
244
|
+
};
|
|
245
|
+
if (dependencies && Object.keys(dependencies).length > 0) {
|
|
246
|
+
this.packageDependencies.set(packageName, dependencies);
|
|
247
|
+
for (const depName of Object.keys(dependencies)) {
|
|
248
|
+
await this.buildPackage(depName, npmDirPath);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} catch (e) {
|
|
252
|
+
console.warn(`[npm-builder] 解析 package.json 失败: ${packageJsonPath}`, e.message);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* 验证 npm 包的完整性
|
|
257
|
+
* @param {string} packageName 包名
|
|
258
|
+
* @param {string} packagePath 包路径
|
|
259
|
+
* @returns {boolean} 是否有效
|
|
260
|
+
*/
|
|
261
|
+
validatePackage(packageName, packagePath) {
|
|
262
|
+
const requiredFiles = ["package.json"];
|
|
263
|
+
for (const file of requiredFiles) {
|
|
264
|
+
if (!fs.existsSync(path.join(packagePath, file))) {
|
|
265
|
+
console.warn(`[npm-builder] 包 ${packageName} 缺少必要文件: ${file}`);
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
271
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
272
|
+
if (!packageJson.name || !packageJson.version) {
|
|
273
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 格式不正确`);
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
} catch (e) {
|
|
277
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 解析失败:`, e.message);
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* 获取已构建的包列表
|
|
284
|
+
* @returns {string[]} 已构建的包列表
|
|
285
|
+
*/
|
|
286
|
+
getBuiltPackages() {
|
|
287
|
+
return Array.from(this.builtPackages);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* 获取包依赖关系
|
|
291
|
+
* @returns {Map} 包依赖关系映射
|
|
292
|
+
*/
|
|
293
|
+
getPackageDependencies() {
|
|
294
|
+
return this.packageDependencies;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* 清理构建缓存
|
|
298
|
+
*/
|
|
299
|
+
clearCache() {
|
|
300
|
+
this.builtPackages.clear();
|
|
301
|
+
this.packageDependencies.clear();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function compileConfig() {
|
|
305
|
+
const compileResInfo = {
|
|
306
|
+
app: env.getAppConfigInfo(),
|
|
307
|
+
modules: env.getPageConfigInfo(),
|
|
308
|
+
projectName: env.getAppName()
|
|
309
|
+
};
|
|
310
|
+
const json = JSON.stringify(compileResInfo, null, 4);
|
|
311
|
+
const mainDir = `${env.getTargetPath()}/main`;
|
|
312
|
+
if (!fs.existsSync(mainDir)) {
|
|
313
|
+
fs.mkdirSync(mainDir, { recursive: true });
|
|
314
|
+
}
|
|
315
|
+
fs.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
316
|
+
}
|
|
115
317
|
let isPrinted = false;
|
|
116
318
|
async function build(targetPath, workPath, useAppIdDir = true) {
|
|
117
319
|
if (!isPrinted) {
|
|
@@ -141,6 +343,13 @@ async function build(targetPath, workPath, useAppIdDir = true) {
|
|
|
141
343
|
task: () => {
|
|
142
344
|
compileConfig();
|
|
143
345
|
}
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
title: "构建 npm 包",
|
|
349
|
+
task: async () => {
|
|
350
|
+
const npmBuilder = new NpmBuilder(env.getWorkPath(), env.getTargetPath());
|
|
351
|
+
await npmBuilder.buildNpmPackages();
|
|
352
|
+
}
|
|
144
353
|
}
|
|
145
354
|
],
|
|
146
355
|
{ concurrent: false }
|
|
@@ -210,19 +419,32 @@ function runCompileInWorker(script, ctx, task) {
|
|
|
210
419
|
const totalTasks = Object.keys(ctx.pages.mainPages).length + Object.values(ctx.pages.subPages).reduce((sum, item) => sum + item.info.length, 0);
|
|
211
420
|
worker.postMessage({ pages: ctx.pages, storeInfo: ctx.storeInfo });
|
|
212
421
|
worker.on("message", (message) => {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
422
|
+
try {
|
|
423
|
+
if (message.completedTasks) {
|
|
424
|
+
const progress = message.completedTasks / totalTasks;
|
|
425
|
+
const percentage = progress * 100;
|
|
426
|
+
const barLength = 30;
|
|
427
|
+
const filledLength = Math.ceil(barLength * progress);
|
|
428
|
+
const bar = "█".repeat(filledLength) + "░".repeat(barLength - filledLength);
|
|
429
|
+
task.output = `[${bar}] ${percentage.toFixed(2)}%`;
|
|
430
|
+
}
|
|
431
|
+
if (message.success) {
|
|
432
|
+
resolve();
|
|
433
|
+
worker.terminate();
|
|
434
|
+
} else if (message.error) {
|
|
435
|
+
const error = new Error(message.error.message || message.error);
|
|
436
|
+
if (message.error.stack)
|
|
437
|
+
error.stack = message.error.stack;
|
|
438
|
+
if (message.error.file)
|
|
439
|
+
error.file = message.error.file;
|
|
440
|
+
if (message.error.line)
|
|
441
|
+
error.line = message.error.line;
|
|
442
|
+
reject(error);
|
|
443
|
+
worker.terminate();
|
|
444
|
+
}
|
|
445
|
+
} catch (err) {
|
|
446
|
+
reject(new Error(`Error processing worker message: ${err.message}
|
|
447
|
+
${err.stack}`));
|
|
226
448
|
worker.terminate();
|
|
227
449
|
}
|
|
228
450
|
});
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { Worker } from "node:worker_threads";
|
|
3
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { Worker } from "node:worker_threads";
|
|
4
4
|
import { Listr } from "listr2";
|
|
5
|
-
import { k as getPageConfigInfo, j as getAppConfigInfo, g as getTargetPath, e as getAppId, s as storeInfo, l as getPages, m as getAppName } from "./env-CezfCSQz.js";
|
|
6
|
-
import fs from "node:fs";
|
|
7
5
|
import process from "node:process";
|
|
8
|
-
import
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import { g as getTargetPath, f as getAppId, k as getAppName, l as getPageConfigInfo, j as getAppConfigInfo, s as storeInfo, d as getWorkPath, m as getPages } from "./env-Csj3AHY4.js";
|
|
9
8
|
import os from "node:os";
|
|
10
9
|
const artCode = `
|
|
11
10
|
██████╗ ██╗███╗ ███╗██╗███╗ ██╗ █████╗
|
|
@@ -18,32 +17,35 @@ const artCode = `
|
|
|
18
17
|
function artCode$1() {
|
|
19
18
|
console.log(artCode);
|
|
20
19
|
}
|
|
21
|
-
function compileConfig() {
|
|
22
|
-
const compileResInfo = {
|
|
23
|
-
app: getAppConfigInfo(),
|
|
24
|
-
modules: getPageConfigInfo()
|
|
25
|
-
};
|
|
26
|
-
const json = JSON.stringify(compileResInfo, null, 4);
|
|
27
|
-
const mainDir = `${getTargetPath()}/main`;
|
|
28
|
-
if (!fs.existsSync(mainDir)) {
|
|
29
|
-
fs.mkdirSync(mainDir);
|
|
30
|
-
}
|
|
31
|
-
fs.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
32
|
-
}
|
|
33
20
|
function createDist() {
|
|
34
21
|
const distPath = getTargetPath();
|
|
35
|
-
if (
|
|
36
|
-
|
|
22
|
+
if (fs.existsSync(distPath)) {
|
|
23
|
+
fs.rmSync(distPath, { recursive: true, force: true });
|
|
37
24
|
}
|
|
38
|
-
|
|
25
|
+
fs.mkdirSync(distPath, { recursive: true });
|
|
39
26
|
}
|
|
40
27
|
function publishToDist(dist, useAppIdDir = true) {
|
|
41
28
|
const distPath = getTargetPath();
|
|
42
29
|
const appId = getAppId();
|
|
43
|
-
const absolutePath = useAppIdDir ? `${path.resolve(process.cwd(), dist)}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
30
|
+
const absolutePath = useAppIdDir ? `${path.resolve(process.cwd(), dist)}${path.sep}${appId}` : `${path.resolve(process.cwd(), dist)}`;
|
|
31
|
+
if (fs.existsSync(absolutePath)) {
|
|
32
|
+
fs.rmSync(absolutePath, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
fs.mkdirSync(absolutePath, { recursive: true });
|
|
35
|
+
function copyDir(src, dest) {
|
|
36
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
37
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
const srcPath = path.join(src, entry.name);
|
|
40
|
+
const destPath = path.join(dest, entry.name);
|
|
41
|
+
if (entry.isDirectory()) {
|
|
42
|
+
copyDir(srcPath, destPath);
|
|
43
|
+
} else {
|
|
44
|
+
fs.copyFileSync(srcPath, destPath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
copyDir(distPath, absolutePath);
|
|
47
49
|
}
|
|
48
50
|
function getCGroupCPUCount() {
|
|
49
51
|
try {
|
|
@@ -66,7 +68,7 @@ function getCGroupMemoryLimit() {
|
|
|
66
68
|
const memLimitPath = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
|
|
67
69
|
if (fs.existsSync(memLimitPath)) {
|
|
68
70
|
const memLimit = Number.parseInt(fs.readFileSync(memLimitPath, "utf8"));
|
|
69
|
-
if (memLimit < Infinity && memLimit > 0) {
|
|
71
|
+
if (memLimit < Number.Infinity && memLimit > 0) {
|
|
70
72
|
return memLimit;
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -110,6 +112,206 @@ class WorkerPool {
|
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
const workerPool = new WorkerPool();
|
|
115
|
+
class NpmBuilder {
|
|
116
|
+
constructor(workPath, targetPath) {
|
|
117
|
+
this.workPath = workPath;
|
|
118
|
+
this.targetPath = targetPath;
|
|
119
|
+
this.builtPackages = /* @__PURE__ */ new Set();
|
|
120
|
+
this.packageDependencies = /* @__PURE__ */ new Map();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 构建 npm 包
|
|
124
|
+
* 扫描 miniprogram_npm 目录并构建相关包
|
|
125
|
+
*/
|
|
126
|
+
async buildNpmPackages() {
|
|
127
|
+
const miniprogramNpmPaths = this.findMiniprogramNpmDirs();
|
|
128
|
+
for (const npmPath of miniprogramNpmPaths) {
|
|
129
|
+
await this.buildNpmDir(npmPath);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 查找所有 miniprogram_npm 目录
|
|
134
|
+
* @returns {string[]} miniprogram_npm 目录路径数组
|
|
135
|
+
*/
|
|
136
|
+
findMiniprogramNpmDirs() {
|
|
137
|
+
const npmDirs = [];
|
|
138
|
+
const scanDir = (dir, relativePath = "") => {
|
|
139
|
+
if (!fs.existsSync(dir)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
143
|
+
for (const item of items) {
|
|
144
|
+
if (item.isDirectory()) {
|
|
145
|
+
const itemPath = path.join(dir, item.name);
|
|
146
|
+
const itemRelativePath = relativePath ? `${relativePath}/${item.name}` : item.name;
|
|
147
|
+
if (item.name === "miniprogram_npm") {
|
|
148
|
+
npmDirs.push(itemRelativePath);
|
|
149
|
+
} else {
|
|
150
|
+
scanDir(itemPath, itemRelativePath);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
scanDir(this.workPath);
|
|
156
|
+
return npmDirs;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 构建指定的 miniprogram_npm 目录
|
|
160
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
161
|
+
*/
|
|
162
|
+
async buildNpmDir(npmDirPath) {
|
|
163
|
+
const fullNpmPath = path.join(this.workPath, npmDirPath);
|
|
164
|
+
if (!fs.existsSync(fullNpmPath)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const packages = fs.readdirSync(fullNpmPath, { withFileTypes: true }).filter((item) => item.isDirectory()).map((item) => item.name);
|
|
168
|
+
for (const packageName of packages) {
|
|
169
|
+
await this.buildPackage(packageName, npmDirPath);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 构建单个 npm 包
|
|
174
|
+
* @param {string} packageName 包名
|
|
175
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
176
|
+
*/
|
|
177
|
+
async buildPackage(packageName, npmDirPath) {
|
|
178
|
+
const packageKey = `${npmDirPath}/${packageName}`;
|
|
179
|
+
if (this.builtPackages.has(packageKey)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const packagePath = path.join(this.workPath, npmDirPath, packageName);
|
|
183
|
+
const targetPackagePath = path.join(this.targetPath, npmDirPath, packageName);
|
|
184
|
+
if (!fs.existsSync(path.dirname(targetPackagePath))) {
|
|
185
|
+
fs.mkdirSync(path.dirname(targetPackagePath), { recursive: true });
|
|
186
|
+
}
|
|
187
|
+
await this.copyPackageFiles(packagePath, targetPackagePath);
|
|
188
|
+
await this.processDependencies(packageName, packagePath, npmDirPath);
|
|
189
|
+
this.builtPackages.add(packageKey);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* 复制包文件
|
|
193
|
+
* @param {string} sourcePath 源路径
|
|
194
|
+
* @param {string} targetPath 目标路径
|
|
195
|
+
*/
|
|
196
|
+
async copyPackageFiles(sourcePath, targetPath) {
|
|
197
|
+
if (!fs.existsSync(sourcePath)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (!fs.existsSync(targetPath)) {
|
|
201
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
202
|
+
}
|
|
203
|
+
const items = fs.readdirSync(sourcePath, { withFileTypes: true });
|
|
204
|
+
for (const item of items) {
|
|
205
|
+
const sourceItemPath = path.join(sourcePath, item.name);
|
|
206
|
+
const targetItemPath = path.join(targetPath, item.name);
|
|
207
|
+
if (item.isDirectory()) {
|
|
208
|
+
await this.copyPackageFiles(sourceItemPath, targetItemPath);
|
|
209
|
+
} else {
|
|
210
|
+
if (this.isMiniprogramFile(item.name)) {
|
|
211
|
+
fs.copyFileSync(sourceItemPath, targetItemPath);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* 检查是否为小程序相关文件
|
|
218
|
+
* @param {string} filename 文件名
|
|
219
|
+
* @returns {boolean} 是否为小程序文件
|
|
220
|
+
*/
|
|
221
|
+
isMiniprogramFile(filename) {
|
|
222
|
+
const miniprogramExts = [".js", ".json", ".wxml", ".wxss", ".wxs", ".ts", ".less", ".scss", ".styl"];
|
|
223
|
+
const ext = path.extname(filename).toLowerCase();
|
|
224
|
+
return miniprogramExts.includes(ext) || filename === "package.json" || filename === "README.md" || filename.startsWith(".");
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* 处理包依赖
|
|
228
|
+
* @param {string} packageName 包名
|
|
229
|
+
* @param {string} packagePath 包路径
|
|
230
|
+
* @param {string} npmDirPath npm 目录路径
|
|
231
|
+
*/
|
|
232
|
+
async processDependencies(packageName, packagePath, npmDirPath) {
|
|
233
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
234
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
239
|
+
const dependencies = {
|
|
240
|
+
...packageJson.dependencies,
|
|
241
|
+
...packageJson.peerDependencies
|
|
242
|
+
};
|
|
243
|
+
if (dependencies && Object.keys(dependencies).length > 0) {
|
|
244
|
+
this.packageDependencies.set(packageName, dependencies);
|
|
245
|
+
for (const depName of Object.keys(dependencies)) {
|
|
246
|
+
await this.buildPackage(depName, npmDirPath);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
} catch (e) {
|
|
250
|
+
console.warn(`[npm-builder] 解析 package.json 失败: ${packageJsonPath}`, e.message);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 验证 npm 包的完整性
|
|
255
|
+
* @param {string} packageName 包名
|
|
256
|
+
* @param {string} packagePath 包路径
|
|
257
|
+
* @returns {boolean} 是否有效
|
|
258
|
+
*/
|
|
259
|
+
validatePackage(packageName, packagePath) {
|
|
260
|
+
const requiredFiles = ["package.json"];
|
|
261
|
+
for (const file of requiredFiles) {
|
|
262
|
+
if (!fs.existsSync(path.join(packagePath, file))) {
|
|
263
|
+
console.warn(`[npm-builder] 包 ${packageName} 缺少必要文件: ${file}`);
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
269
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
270
|
+
if (!packageJson.name || !packageJson.version) {
|
|
271
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 格式不正确`);
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
} catch (e) {
|
|
275
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 解析失败:`, e.message);
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* 获取已构建的包列表
|
|
282
|
+
* @returns {string[]} 已构建的包列表
|
|
283
|
+
*/
|
|
284
|
+
getBuiltPackages() {
|
|
285
|
+
return Array.from(this.builtPackages);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 获取包依赖关系
|
|
289
|
+
* @returns {Map} 包依赖关系映射
|
|
290
|
+
*/
|
|
291
|
+
getPackageDependencies() {
|
|
292
|
+
return this.packageDependencies;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 清理构建缓存
|
|
296
|
+
*/
|
|
297
|
+
clearCache() {
|
|
298
|
+
this.builtPackages.clear();
|
|
299
|
+
this.packageDependencies.clear();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function compileConfig() {
|
|
303
|
+
const compileResInfo = {
|
|
304
|
+
app: getAppConfigInfo(),
|
|
305
|
+
modules: getPageConfigInfo(),
|
|
306
|
+
projectName: getAppName()
|
|
307
|
+
};
|
|
308
|
+
const json = JSON.stringify(compileResInfo, null, 4);
|
|
309
|
+
const mainDir = `${getTargetPath()}/main`;
|
|
310
|
+
if (!fs.existsSync(mainDir)) {
|
|
311
|
+
fs.mkdirSync(mainDir, { recursive: true });
|
|
312
|
+
}
|
|
313
|
+
fs.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
314
|
+
}
|
|
113
315
|
let isPrinted = false;
|
|
114
316
|
async function build(targetPath, workPath, useAppIdDir = true) {
|
|
115
317
|
if (!isPrinted) {
|
|
@@ -139,6 +341,13 @@ async function build(targetPath, workPath, useAppIdDir = true) {
|
|
|
139
341
|
task: () => {
|
|
140
342
|
compileConfig();
|
|
141
343
|
}
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
title: "构建 npm 包",
|
|
347
|
+
task: async () => {
|
|
348
|
+
const npmBuilder = new NpmBuilder(getWorkPath(), getTargetPath());
|
|
349
|
+
await npmBuilder.buildNpmPackages();
|
|
350
|
+
}
|
|
142
351
|
}
|
|
143
352
|
],
|
|
144
353
|
{ concurrent: false }
|
|
@@ -208,19 +417,32 @@ function runCompileInWorker(script, ctx, task) {
|
|
|
208
417
|
const totalTasks = Object.keys(ctx.pages.mainPages).length + Object.values(ctx.pages.subPages).reduce((sum, item) => sum + item.info.length, 0);
|
|
209
418
|
worker.postMessage({ pages: ctx.pages, storeInfo: ctx.storeInfo });
|
|
210
419
|
worker.on("message", (message) => {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
420
|
+
try {
|
|
421
|
+
if (message.completedTasks) {
|
|
422
|
+
const progress = message.completedTasks / totalTasks;
|
|
423
|
+
const percentage = progress * 100;
|
|
424
|
+
const barLength = 30;
|
|
425
|
+
const filledLength = Math.ceil(barLength * progress);
|
|
426
|
+
const bar = "█".repeat(filledLength) + "░".repeat(barLength - filledLength);
|
|
427
|
+
task.output = `[${bar}] ${percentage.toFixed(2)}%`;
|
|
428
|
+
}
|
|
429
|
+
if (message.success) {
|
|
430
|
+
resolve();
|
|
431
|
+
worker.terminate();
|
|
432
|
+
} else if (message.error) {
|
|
433
|
+
const error = new Error(message.error.message || message.error);
|
|
434
|
+
if (message.error.stack)
|
|
435
|
+
error.stack = message.error.stack;
|
|
436
|
+
if (message.error.file)
|
|
437
|
+
error.file = message.error.file;
|
|
438
|
+
if (message.error.line)
|
|
439
|
+
error.line = message.error.line;
|
|
440
|
+
reject(error);
|
|
441
|
+
worker.terminate();
|
|
442
|
+
}
|
|
443
|
+
} catch (err) {
|
|
444
|
+
reject(new Error(`Error processing worker message: ${err.message}
|
|
445
|
+
${err.stack}`));
|
|
224
446
|
worker.terminate();
|
|
225
447
|
}
|
|
226
448
|
});
|