@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/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 shelljs = require("shelljs");
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 (shelljs.test("-d", distPath)) {
38
- shelljs.rm("-rf", distPath);
24
+ if (fs.existsSync(distPath)) {
25
+ fs.rmSync(distPath, { recursive: true, force: true });
39
26
  }
40
- shelljs.mkdir("-p", `${distPath}`);
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)}/${appId}` : `${path.resolve(process.cwd(), dist)}`;
46
- shelljs.rm("-rf", absolutePath);
47
- shelljs.mkdir("-p", absolutePath);
48
- shelljs.cp("-r", `${distPath}/*`, absolutePath);
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
- if (message.completedTasks) {
214
- const progress = message.completedTasks / totalTasks;
215
- const percentage = progress * 100;
216
- const barLength = 30;
217
- const filledLength = Math.ceil(barLength * progress);
218
- const bar = "█".repeat(filledLength) + "░".repeat(barLength - filledLength);
219
- task.output = `[${bar}] ${percentage.toFixed(2)}%`;
220
- }
221
- if (message.success) {
222
- resolve();
223
- worker.terminate();
224
- } else if (message.error) {
225
- reject(new Error(message.error));
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 shelljs from "shelljs";
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 (shelljs.test("-d", distPath)) {
36
- shelljs.rm("-rf", distPath);
22
+ if (fs.existsSync(distPath)) {
23
+ fs.rmSync(distPath, { recursive: true, force: true });
37
24
  }
38
- shelljs.mkdir("-p", `${distPath}`);
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)}/${appId}` : `${path.resolve(process.cwd(), dist)}`;
44
- shelljs.rm("-rf", absolutePath);
45
- shelljs.mkdir("-p", absolutePath);
46
- shelljs.cp("-r", `${distPath}/*`, absolutePath);
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
- if (message.completedTasks) {
212
- const progress = message.completedTasks / totalTasks;
213
- const percentage = progress * 100;
214
- const barLength = 30;
215
- const filledLength = Math.ceil(barLength * progress);
216
- const bar = "█".repeat(filledLength) + "░".repeat(barLength - filledLength);
217
- task.output = `[${bar}] ${percentage.toFixed(2)}%`;
218
- }
219
- if (message.success) {
220
- resolve();
221
- worker.terminate();
222
- } else if (message.error) {
223
- reject(new Error(message.error));
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
  });