@neuxnet/neux-cli 0.2.3
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 +438 -0
- package/README.zh-CN.md +554 -0
- package/assets/container/assets/index.css +1 -0
- package/assets/container/assets/index.js +137 -0
- package/assets/container/assets/pageFrame.css +1 -0
- package/assets/container/assets/pageFrame.js +56 -0
- package/assets/container/assets/service.js +6 -0
- package/assets/container/assets/vconsole.js +931 -0
- package/assets/container/favicon.ico +0 -0
- package/assets/container/images/icon-arrow.png +0 -0
- package/assets/container/images/mini-action-white.png +0 -0
- package/assets/container/images/mini-action.png +0 -0
- package/assets/container/images/mini-arrow-left-white.png +0 -0
- package/assets/container/images/mini-arrow-left.jpg +0 -0
- package/assets/container/images/mini-arrow-left.png +0 -0
- package/assets/container/images/mini-close-white.png +0 -0
- package/assets/container/images/mini-close.png +0 -0
- package/assets/container/images/more.png +0 -0
- package/assets/container/images/search.jpg +0 -0
- package/assets/container/index.html +1 -0
- package/assets/container/pageFrame.html +1 -0
- package/assets/init/tabbar/home-active.png +0 -0
- package/assets/init/tabbar/home.png +0 -0
- package/assets/init/tabbar/list-active.png +0 -0
- package/assets/init/tabbar/list.png +0 -0
- package/assets/init/types/neux-api.d.ts +1402 -0
- package/package.json +68 -0
- package/scripts/generate-init-types.js +210 -0
- package/scripts/sync-compiler.js +22 -0
- package/scripts/sync-web-container.js +34 -0
- package/src/bin/cli.js +646 -0
- package/src/core/brand.js +11 -0
- package/src/core/compiler.js +305 -0
- package/src/core/defaults.js +12 -0
- package/src/core/dev.js +15 -0
- package/src/core/errors.js +17 -0
- package/src/core/fs.js +66 -0
- package/src/core/i18n.js +37 -0
- package/src/core/init.js +866 -0
- package/src/core/lifecycle.js +32 -0
- package/src/core/manifest.js +72 -0
- package/src/core/pack.js +156 -0
- package/src/core/package-info.js +27 -0
- package/src/core/preview-server.js +123 -0
- package/src/core/project.js +101 -0
- package/src/core/prompts.js +71 -0
- package/src/core/proxy-security.js +141 -0
- package/src/core/proxy.js +156 -0
- package/src/core/qr.js +41 -0
- package/src/core/terminal-qr.js +72 -0
- package/src/core/update.js +278 -0
- package/src/core/watch.js +113 -0
- package/src/core/web.js +649 -0
- package/src/core/zip.js +120 -0
- package/src/index.js +20 -0
- package/src/providers/service-client.js +149 -0
- package/src/providers/service-config.js +264 -0
- package/src/providers/service.js +146 -0
- package/src/providers/upload.js +112 -0
- package/vendor/dimina-compiler/bin/index.cjs +265 -0
- package/vendor/dimina-compiler/bin/index.js +263 -0
- package/vendor/dimina-compiler/compatibility-B-DoZtUX.cjs +395 -0
- package/vendor/dimina-compiler/compatibility-Cl3-DO6V.js +366 -0
- package/vendor/dimina-compiler/core/logic-compiler.cjs +378 -0
- package/vendor/dimina-compiler/core/logic-compiler.js +374 -0
- package/vendor/dimina-compiler/core/style-compiler.cjs +392 -0
- package/vendor/dimina-compiler/core/style-compiler.js +377 -0
- package/vendor/dimina-compiler/core/view-compiler.cjs +1601 -0
- package/vendor/dimina-compiler/core/view-compiler.js +1582 -0
- package/vendor/dimina-compiler/index.cjs +762 -0
- package/vendor/dimina-compiler/index.js +751 -0
- package/vendor/dimina-compiler/sourcemap-BgtIgqkC.cjs +1377 -0
- package/vendor/dimina-compiler/sourcemap-CKjhV9h7.js +1135 -0
|
@@ -0,0 +1,751 @@
|
|
|
1
|
+
import { A as resetAssetCache, E as collectAssets, F as DependencyGraph, S as getWorkPath, T as storeInfo, _ as getTargetPath, a as getAppConfigInfo, b as getViewScriptExts, c as getAppStyleScopeId, g as getStyleExts, h as getProjectConfig, l as getComponent, m as getPages, o as getAppId, p as getPageConfigInfo, s as getAppName, y as getTemplateExts } from "./sourcemap-CKjhV9h7.js";
|
|
2
|
+
import { compileSS } from "./core/style-compiler.js";
|
|
3
|
+
import { compileML, resetViewCompilerCache } from "./core/view-compiler.js";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { Worker } from "node:worker_threads";
|
|
9
|
+
import { Listr, PRESET_TIMER, isUnicodeSupported } from "listr2";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
//#region src/common/compile-progress.js
|
|
12
|
+
var DEFAULT_TERMINAL_COLUMNS = 80;
|
|
13
|
+
var MIN_PROGRESS_WIDTH = 8;
|
|
14
|
+
var MAX_PROGRESS_WIDTH = 28;
|
|
15
|
+
var RENDERER_CHROME_WIDTH = 14;
|
|
16
|
+
var PROGRESS_BRACKETS_WIDTH = 2;
|
|
17
|
+
/**
|
|
18
|
+
* Format worker progress without assuming a fixed terminal width.
|
|
19
|
+
* The completed count remains the source of truth. Whole cells avoid the
|
|
20
|
+
* visible gap that partial block glyphs leave before the unfilled section.
|
|
21
|
+
*/
|
|
22
|
+
function formatCompileProgress(completed, total, options = {}) {
|
|
23
|
+
const unicode = options.unicode ?? isUnicodeSupported();
|
|
24
|
+
const columns = normalizePositiveInteger(options.columns) || process.stdout.columns || DEFAULT_TERMINAL_COLUMNS;
|
|
25
|
+
const safeTotal = normalizePositiveInteger(total);
|
|
26
|
+
const safeCompleted = Math.min(normalizePositiveInteger(completed), safeTotal);
|
|
27
|
+
const ratio = safeTotal === 0 ? 0 : safeCompleted / safeTotal;
|
|
28
|
+
const percentage = Math.round(ratio * 100);
|
|
29
|
+
const separator = unicode ? "·" : "|";
|
|
30
|
+
const metadata = `${String(safeCompleted).padStart(String(safeTotal).length)}/${safeTotal} ${separator} ${String(percentage).padStart(3)}%`;
|
|
31
|
+
const availableWidth = columns - metadata.length - RENDERER_CHROME_WIDTH - PROGRESS_BRACKETS_WIDTH;
|
|
32
|
+
if (availableWidth < MIN_PROGRESS_WIDTH) return metadata;
|
|
33
|
+
const width = Math.min(availableWidth, MAX_PROGRESS_WIDTH);
|
|
34
|
+
return `[${unicode ? createUnicodeBar(ratio, width) : createAsciiBar(ratio, width)}] ${metadata}`;
|
|
35
|
+
}
|
|
36
|
+
function createUnicodeBar(ratio, width) {
|
|
37
|
+
const completeWidth = Math.round(ratio * width);
|
|
38
|
+
const emptyWidth = width - completeWidth;
|
|
39
|
+
return `${"█".repeat(completeWidth)}${"░".repeat(emptyWidth)}`;
|
|
40
|
+
}
|
|
41
|
+
function createAsciiBar(ratio, width) {
|
|
42
|
+
const completeWidth = Math.floor(ratio * width);
|
|
43
|
+
const showHead = ratio > 0 && ratio < 1;
|
|
44
|
+
const bodyWidth = Math.max(0, completeWidth - (showHead ? 1 : 0));
|
|
45
|
+
const emptyWidth = width - bodyWidth - (showHead ? 1 : 0);
|
|
46
|
+
return `${"=".repeat(bodyWidth)}${showHead ? ">" : ""}${"-".repeat(emptyWidth)}`;
|
|
47
|
+
}
|
|
48
|
+
function normalizePositiveInteger(value) {
|
|
49
|
+
return Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : 0;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/common/publish.js
|
|
53
|
+
function createDist(seedPath) {
|
|
54
|
+
const distPath = getTargetPath();
|
|
55
|
+
if (fs.existsSync(distPath)) fs.rmSync(distPath, {
|
|
56
|
+
recursive: true,
|
|
57
|
+
force: true
|
|
58
|
+
});
|
|
59
|
+
fs.mkdirSync(distPath, { recursive: true });
|
|
60
|
+
if (seedPath && fs.existsSync(seedPath)) fs.cpSync(seedPath, distPath, { recursive: true });
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 发布到指定目录
|
|
64
|
+
* @param {string} dist 目标路径
|
|
65
|
+
* @param {boolean} useAppIdDir 是否在路径中包含appId
|
|
66
|
+
*/
|
|
67
|
+
function publishToDist(dist, useAppIdDir = true) {
|
|
68
|
+
const distPath = getTargetPath();
|
|
69
|
+
const appId = getAppId();
|
|
70
|
+
const absolutePath = useAppIdDir ? `${path.resolve(process.cwd(), dist)}${path.sep}${appId}` : `${path.resolve(process.cwd(), dist)}`;
|
|
71
|
+
if (fs.existsSync(absolutePath)) fs.rmSync(absolutePath, {
|
|
72
|
+
recursive: true,
|
|
73
|
+
force: true
|
|
74
|
+
});
|
|
75
|
+
fs.mkdirSync(absolutePath, { recursive: true });
|
|
76
|
+
function copyDir(src, dest) {
|
|
77
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
78
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
79
|
+
for (const entry of entries) {
|
|
80
|
+
const srcPath = path.join(src, entry.name);
|
|
81
|
+
const destPath = path.join(dest, entry.name);
|
|
82
|
+
if (entry.isDirectory()) copyDir(srcPath, destPath);
|
|
83
|
+
else fs.copyFileSync(srcPath, destPath);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
copyDir(distPath, absolutePath);
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/common/worker-pool.js
|
|
90
|
+
function getCGroupCPUCount() {
|
|
91
|
+
try {
|
|
92
|
+
const quotaPath = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us";
|
|
93
|
+
const periodPath = "/sys/fs/cgroup/cpu/cpu.cfs_period_us";
|
|
94
|
+
if (fs.existsSync(quotaPath) && fs.existsSync(periodPath)) {
|
|
95
|
+
const quota = Number.parseInt(fs.readFileSync(quotaPath, "utf8"));
|
|
96
|
+
const period = Number.parseInt(fs.readFileSync(periodPath, "utf8"));
|
|
97
|
+
if (quota > 0) return Math.max(1, Math.floor(quota / period));
|
|
98
|
+
}
|
|
99
|
+
} catch (e) {
|
|
100
|
+
console.warn("Failed to read CPU limits from cgroup:", e.message);
|
|
101
|
+
}
|
|
102
|
+
return os.cpus().length;
|
|
103
|
+
}
|
|
104
|
+
function getCGroupMemoryLimit() {
|
|
105
|
+
try {
|
|
106
|
+
const memLimitPath = "/sys/fs/cgroup/memory/memory.limit_in_bytes";
|
|
107
|
+
if (fs.existsSync(memLimitPath)) {
|
|
108
|
+
const memLimit = Number.parseInt(fs.readFileSync(memLimitPath, "utf8"));
|
|
109
|
+
if (memLimit < Number.Infinity && memLimit > 0) return memLimit;
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.warn("Failed to read memory limits from cgroup:", e.message);
|
|
113
|
+
}
|
|
114
|
+
return os.totalmem();
|
|
115
|
+
}
|
|
116
|
+
var MAX_WORKERS = Math.max(1, Math.min(4, Math.floor(getCGroupCPUCount() / 4)));
|
|
117
|
+
var WorkerPool = class {
|
|
118
|
+
constructor(maxWorkers = MAX_WORKERS) {
|
|
119
|
+
this.maxWorkers = maxWorkers;
|
|
120
|
+
this.activeWorkers = 0;
|
|
121
|
+
this.queue = [];
|
|
122
|
+
this.memoryLimit = Math.floor(getCGroupMemoryLimit() * .6 / maxWorkers);
|
|
123
|
+
}
|
|
124
|
+
async runWorker(workerCreator) {
|
|
125
|
+
if (this.activeWorkers >= this.maxWorkers) await new Promise((resolve) => this.queue.push(resolve));
|
|
126
|
+
this.activeWorkers++;
|
|
127
|
+
try {
|
|
128
|
+
return await workerCreator();
|
|
129
|
+
} finally {
|
|
130
|
+
this.activeWorkers--;
|
|
131
|
+
if (this.queue.length > 0) this.queue.shift()();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
getWorkerOptions() {
|
|
135
|
+
const memoryMb = Math.floor(this.memoryLimit / (1024 * 1024));
|
|
136
|
+
return { resourceLimits: {
|
|
137
|
+
maxOldGenerationSizeMb: Math.max(256, memoryMb),
|
|
138
|
+
maxYoungGenerationSizeMb: Math.max(64, Math.floor(memoryMb / 4)),
|
|
139
|
+
codeRangeSizeMb: 64
|
|
140
|
+
} };
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var workerPool = new WorkerPool();
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/common/npm-builder.js
|
|
146
|
+
/**
|
|
147
|
+
* npm 构建工具
|
|
148
|
+
* 用于处理小程序 npm 包的构建和管理
|
|
149
|
+
*/
|
|
150
|
+
var NpmBuilder = class {
|
|
151
|
+
constructor(workPath, targetPath, dependencyGraph = null) {
|
|
152
|
+
this.workPath = workPath;
|
|
153
|
+
this.targetPath = targetPath;
|
|
154
|
+
this.dependencyGraph = dependencyGraph;
|
|
155
|
+
this.builtPackages = /* @__PURE__ */ new Set();
|
|
156
|
+
this.packageDependencies = /* @__PURE__ */ new Map();
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 构建 npm 包
|
|
160
|
+
* 扫描 miniprogram_npm 目录并构建相关包
|
|
161
|
+
*/
|
|
162
|
+
async buildNpmPackages() {
|
|
163
|
+
const miniprogramNpmPaths = this.findMiniprogramNpmDirs();
|
|
164
|
+
for (const npmPath of miniprogramNpmPaths) await this.buildNpmDir(npmPath);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 查找所有 miniprogram_npm 目录
|
|
168
|
+
* @returns {string[]} miniprogram_npm 目录路径数组
|
|
169
|
+
*/
|
|
170
|
+
findMiniprogramNpmDirs() {
|
|
171
|
+
const npmDirs = [];
|
|
172
|
+
const scanDir = (dir, relativePath = "") => {
|
|
173
|
+
if (!fs.existsSync(dir)) return;
|
|
174
|
+
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
175
|
+
for (const item of items) if (item.isDirectory()) {
|
|
176
|
+
const itemPath = path.join(dir, item.name);
|
|
177
|
+
const itemRelativePath = relativePath ? `${relativePath}/${item.name}` : item.name;
|
|
178
|
+
if (item.name === "miniprogram_npm") npmDirs.push(itemRelativePath);
|
|
179
|
+
else scanDir(itemPath, itemRelativePath);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
scanDir(this.workPath);
|
|
183
|
+
return npmDirs;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* 构建指定的 miniprogram_npm 目录
|
|
187
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
188
|
+
*/
|
|
189
|
+
async buildNpmDir(npmDirPath) {
|
|
190
|
+
const fullNpmPath = path.join(this.workPath, npmDirPath);
|
|
191
|
+
if (!fs.existsSync(fullNpmPath)) return;
|
|
192
|
+
const packages = fs.readdirSync(fullNpmPath, { withFileTypes: true }).filter((item) => item.isDirectory()).map((item) => item.name);
|
|
193
|
+
for (const packageName of packages) await this.buildPackage(packageName, npmDirPath);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 构建单个 npm 包
|
|
197
|
+
* @param {string} packageName 包名
|
|
198
|
+
* @param {string} npmDirPath miniprogram_npm 目录路径
|
|
199
|
+
*/
|
|
200
|
+
async buildPackage(packageName, npmDirPath) {
|
|
201
|
+
const packageKey = `${npmDirPath}/${packageName}`;
|
|
202
|
+
if (this.builtPackages.has(packageKey)) return;
|
|
203
|
+
const packagePath = path.join(this.workPath, npmDirPath, packageName);
|
|
204
|
+
const targetPackagePath = path.join(this.targetPath, npmDirPath, packageName);
|
|
205
|
+
if (!fs.existsSync(path.dirname(targetPackagePath))) fs.mkdirSync(path.dirname(targetPackagePath), { recursive: true });
|
|
206
|
+
await this.copyPackageFiles(packagePath, targetPackagePath);
|
|
207
|
+
await this.processDependencies(packageName, packagePath, npmDirPath);
|
|
208
|
+
this.builtPackages.add(packageKey);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 复制包文件
|
|
212
|
+
* @param {string} sourcePath 源路径
|
|
213
|
+
* @param {string} targetPath 目标路径
|
|
214
|
+
*/
|
|
215
|
+
async copyPackageFiles(sourcePath, targetPath) {
|
|
216
|
+
if (!fs.existsSync(sourcePath)) return;
|
|
217
|
+
if (!fs.existsSync(targetPath)) fs.mkdirSync(targetPath, { recursive: true });
|
|
218
|
+
const items = fs.readdirSync(sourcePath, { withFileTypes: true });
|
|
219
|
+
for (const item of items) {
|
|
220
|
+
const sourceItemPath = path.join(sourcePath, item.name);
|
|
221
|
+
const targetItemPath = path.join(targetPath, item.name);
|
|
222
|
+
if (item.isDirectory()) await this.copyPackageFiles(sourceItemPath, targetItemPath);
|
|
223
|
+
else if (this.isMiniprogramFile(item.name)) {
|
|
224
|
+
this.dependencyGraph?.addFile("app", sourceItemPath, "config");
|
|
225
|
+
fs.copyFileSync(sourceItemPath, targetItemPath);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 检查是否为小程序相关文件
|
|
231
|
+
* @param {string} filename 文件名
|
|
232
|
+
* @returns {boolean} 是否为小程序文件
|
|
233
|
+
*/
|
|
234
|
+
isMiniprogramFile(filename) {
|
|
235
|
+
const miniprogramExts = [
|
|
236
|
+
".js",
|
|
237
|
+
".json",
|
|
238
|
+
".ts",
|
|
239
|
+
...getTemplateExts(),
|
|
240
|
+
...getStyleExts(),
|
|
241
|
+
...getViewScriptExts()
|
|
242
|
+
];
|
|
243
|
+
const ext = path.extname(filename).toLowerCase();
|
|
244
|
+
return miniprogramExts.includes(ext) || filename === "package.json" || filename === "README.md" || filename.startsWith(".");
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* 处理包依赖
|
|
248
|
+
* @param {string} packageName 包名
|
|
249
|
+
* @param {string} packagePath 包路径
|
|
250
|
+
* @param {string} npmDirPath npm 目录路径
|
|
251
|
+
*/
|
|
252
|
+
async processDependencies(packageName, packagePath, npmDirPath) {
|
|
253
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
254
|
+
if (!fs.existsSync(packageJsonPath)) return;
|
|
255
|
+
try {
|
|
256
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
257
|
+
const dependencies = {
|
|
258
|
+
...packageJson.dependencies,
|
|
259
|
+
...packageJson.peerDependencies
|
|
260
|
+
};
|
|
261
|
+
if (dependencies && Object.keys(dependencies).length > 0) {
|
|
262
|
+
this.packageDependencies.set(packageName, dependencies);
|
|
263
|
+
for (const depName of Object.keys(dependencies)) await this.buildPackage(depName, npmDirPath);
|
|
264
|
+
}
|
|
265
|
+
} catch (e) {
|
|
266
|
+
console.warn(`[npm-builder] 解析 package.json 失败: ${packageJsonPath}`, e.message);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* 验证 npm 包的完整性
|
|
271
|
+
* @param {string} packageName 包名
|
|
272
|
+
* @param {string} packagePath 包路径
|
|
273
|
+
* @returns {boolean} 是否有效
|
|
274
|
+
*/
|
|
275
|
+
validatePackage(packageName, packagePath) {
|
|
276
|
+
for (const file of ["package.json"]) if (!fs.existsSync(path.join(packagePath, file))) {
|
|
277
|
+
console.warn(`[npm-builder] 包 ${packageName} 缺少必要文件: ${file}`);
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
282
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
283
|
+
if (!packageJson.name || !packageJson.version) {
|
|
284
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 格式不正确`);
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
} catch (e) {
|
|
288
|
+
console.warn(`[npm-builder] 包 ${packageName} 的 package.json 解析失败:`, e.message);
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* 获取已构建的包列表
|
|
295
|
+
* @returns {string[]} 已构建的包列表
|
|
296
|
+
*/
|
|
297
|
+
getBuiltPackages() {
|
|
298
|
+
return Array.from(this.builtPackages);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* 获取包依赖关系
|
|
302
|
+
* @returns {Map} 包依赖关系映射
|
|
303
|
+
*/
|
|
304
|
+
getPackageDependencies() {
|
|
305
|
+
return this.packageDependencies;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 清理构建缓存
|
|
309
|
+
*/
|
|
310
|
+
clearCache() {
|
|
311
|
+
this.builtPackages.clear();
|
|
312
|
+
this.packageDependencies.clear();
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/core/config-compiler.js
|
|
317
|
+
/**
|
|
318
|
+
* 处理 tabBar.list 中的 iconPath / selectedIconPath。
|
|
319
|
+
* 视为相对小程序根目录的资源,复用 collectAssets 拷贝到 main/static/,
|
|
320
|
+
* 并把 list 中的路径改写成产物 URL,避免容器侧再做特殊解析。
|
|
321
|
+
*
|
|
322
|
+
* 注意:会在原 app 配置上原地修改,不影响后续输出(compileConfig 是
|
|
323
|
+
* 整个流水线最后才走到的环节,不会被再次读取)。
|
|
324
|
+
*/
|
|
325
|
+
function processTabBarIcons(app) {
|
|
326
|
+
const list = app?.tabBar?.list;
|
|
327
|
+
if (!Array.isArray(list) || list.length === 0) return;
|
|
328
|
+
const workPath = getWorkPath();
|
|
329
|
+
const targetPath = getTargetPath();
|
|
330
|
+
const appId = getAppId();
|
|
331
|
+
for (const item of list) {
|
|
332
|
+
if (item.iconPath) item.iconPath = collectAssets(workPath, "", item.iconPath, targetPath, appId);
|
|
333
|
+
if (item.selectedIconPath) item.selectedIconPath = collectAssets(workPath, "", item.selectedIconPath, targetPath, appId);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
*
|
|
338
|
+
* 编译项目配置文件 app-config.json
|
|
339
|
+
*/
|
|
340
|
+
function compileConfig() {
|
|
341
|
+
const app = getAppConfigInfo();
|
|
342
|
+
processTabBarIcons(app);
|
|
343
|
+
const compileResInfo = {
|
|
344
|
+
app,
|
|
345
|
+
modules: getPageConfigInfo(),
|
|
346
|
+
projectName: getAppName()
|
|
347
|
+
};
|
|
348
|
+
const apiNamespaces = getProjectConfig().apiNamespaces;
|
|
349
|
+
if (Array.isArray(apiNamespaces) && apiNamespaces.length > 0) compileResInfo.apiNamespaces = apiNamespaces;
|
|
350
|
+
const json = JSON.stringify(compileResInfo, null, 4);
|
|
351
|
+
const mainDir = `${getTargetPath()}/main`;
|
|
352
|
+
if (!fs.existsSync(mainDir)) fs.mkdirSync(mainDir, { recursive: true });
|
|
353
|
+
fs.writeFileSync(`${mainDir}/app-config.json`, json);
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
356
|
+
//#region src/index.js
|
|
357
|
+
var previousCompatibilityWarnings = /* @__PURE__ */ new Map();
|
|
358
|
+
var COMPILE_STAGE_ORDER = [
|
|
359
|
+
"view",
|
|
360
|
+
"logic",
|
|
361
|
+
"style"
|
|
362
|
+
];
|
|
363
|
+
var BUILD_LABELS = {
|
|
364
|
+
en: {
|
|
365
|
+
initialize: "Prepare project build environment",
|
|
366
|
+
collectConfig: "Collect project configuration",
|
|
367
|
+
prepareOutput: "Prepare output directory",
|
|
368
|
+
compileConfig: "Compile project configuration",
|
|
369
|
+
buildNpm: "Build npm packages",
|
|
370
|
+
compile: "Compile project",
|
|
371
|
+
view: "Compile view files",
|
|
372
|
+
logic: "Compile logic files",
|
|
373
|
+
style: "Compile style files",
|
|
374
|
+
writeOutput: "Write build output"
|
|
375
|
+
},
|
|
376
|
+
"zh-CN": {
|
|
377
|
+
initialize: "初始化项目",
|
|
378
|
+
collectConfig: "收集配置信息",
|
|
379
|
+
prepareOutput: "准备产物目录",
|
|
380
|
+
compileConfig: "编译配置信息",
|
|
381
|
+
buildNpm: "构建 npm 包",
|
|
382
|
+
compile: "编译项目",
|
|
383
|
+
view: "编译视图",
|
|
384
|
+
logic: "编译逻辑",
|
|
385
|
+
style: "编译样式",
|
|
386
|
+
writeOutput: "写入编译产物"
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
function resolveBuildLabels(options = {}) {
|
|
390
|
+
return BUILD_LABELS[String(options.lang || process.env.NEUX_CLI_LANG || "en").toLowerCase().startsWith("zh") ? "zh-CN" : "en"];
|
|
391
|
+
}
|
|
392
|
+
function getStyleOnlyChangedPathPattern() {
|
|
393
|
+
return createExtensionPattern([
|
|
394
|
+
...getStyleExts(),
|
|
395
|
+
".acss",
|
|
396
|
+
".css"
|
|
397
|
+
]);
|
|
398
|
+
}
|
|
399
|
+
function getViewOnlyChangedPathPattern() {
|
|
400
|
+
return createExtensionPattern([...getTemplateExts(), ".axml"]);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* 构建命令入口
|
|
404
|
+
* @param {string} targetPath 编译产物目标路径
|
|
405
|
+
* @param {string} workPath 编译工作目录
|
|
406
|
+
* @param {boolean} useAppIdDir 产物根目录是否包含 appId
|
|
407
|
+
* @param {object} [options] 构建选项
|
|
408
|
+
* @param {boolean} [options.sourcemap] 是否生成 sourcemap
|
|
409
|
+
* @param {{ template?: string[], style?: string[], viewScript?: string[] }} [options.fileTypes]
|
|
410
|
+
* 自定义文件类型,在内置 wx/dd 类型基础上追加;template 为模板扩展名,style 为样式扩展名,
|
|
411
|
+
* viewScript 为视图脚本扩展名和内联标签名
|
|
412
|
+
* @param {string[]} [options.affectedEntries] 仅重编这些页面的视图和样式;逻辑仍按包重建
|
|
413
|
+
* @param {string} [options.seedPath] 增量构建前用于保留未受影响产物的已发布目录
|
|
414
|
+
* @param {object} [options.dependencyGraph] 上一次构建的依赖图快照
|
|
415
|
+
* @param {Array<'view'|'logic'|'style'>} [options.stages] 仅运行指定编译阶段
|
|
416
|
+
*/
|
|
417
|
+
async function build(targetPath, workPath, useAppIdDir = true, options = {}) {
|
|
418
|
+
const { sourcemap = false, fileTypes, affectedEntries, seedPath, dependencyGraph, stages } = options;
|
|
419
|
+
const labels = resolveBuildLabels(options);
|
|
420
|
+
if (stages !== void 0 && (!Array.isArray(stages) || stages.some((stage) => !COMPILE_STAGE_ORDER.includes(stage)))) throw new TypeError(`Invalid compiler stages: ${JSON.stringify(stages)}`);
|
|
421
|
+
const enabledStages = new Set(stages === void 0 ? COMPILE_STAGE_ORDER : COMPILE_STAGE_ORDER.filter((stage) => stages.includes(stage)));
|
|
422
|
+
resetAssetCache();
|
|
423
|
+
const context = await new Listr([
|
|
424
|
+
{
|
|
425
|
+
title: labels.initialize,
|
|
426
|
+
task: (_, task) => task.newListr([
|
|
427
|
+
{
|
|
428
|
+
title: labels.collectConfig,
|
|
429
|
+
task: (ctx) => {
|
|
430
|
+
ctx.storeInfo = storeInfo(workPath, {
|
|
431
|
+
fileTypes,
|
|
432
|
+
dependencyGraph
|
|
433
|
+
});
|
|
434
|
+
ctx.dependencyGraph = new DependencyGraph(ctx.storeInfo.dependencyGraph);
|
|
435
|
+
}
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
title: labels.prepareOutput,
|
|
439
|
+
task: () => {
|
|
440
|
+
createDist(seedPath);
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
title: labels.compileConfig,
|
|
445
|
+
task: () => {
|
|
446
|
+
compileConfig();
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
title: labels.buildNpm,
|
|
451
|
+
task: async (ctx) => {
|
|
452
|
+
await new NpmBuilder(getWorkPath(), getTargetPath(), ctx.dependencyGraph).buildNpmPackages();
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
], { concurrent: false })
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
title: `${labels.compile} · ${path.basename(path.resolve(workPath))}`,
|
|
459
|
+
task: (ctx, task) => {
|
|
460
|
+
const allPages = getPages();
|
|
461
|
+
ctx.allPages = allPages;
|
|
462
|
+
ctx.pages = filterPagesByEntries(allPages, affectedEntries);
|
|
463
|
+
ctx.compatibilityWarnings = /* @__PURE__ */ new Set();
|
|
464
|
+
const compileTasks = [];
|
|
465
|
+
if (enabledStages.has("view")) compileTasks.push({
|
|
466
|
+
title: labels.view,
|
|
467
|
+
rendererOptions: {
|
|
468
|
+
outputBar: true,
|
|
469
|
+
persistentOutput: false
|
|
470
|
+
},
|
|
471
|
+
task: async (ctx, task) => {
|
|
472
|
+
return runCompileInWorker("view", ctx, task, { sourcemap });
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
if (enabledStages.has("logic")) compileTasks.push({
|
|
476
|
+
title: labels.logic,
|
|
477
|
+
rendererOptions: {
|
|
478
|
+
outputBar: true,
|
|
479
|
+
persistentOutput: false
|
|
480
|
+
},
|
|
481
|
+
task: async (ctx, task) => {
|
|
482
|
+
return runCompileInWorker("logic", ctx, task, {
|
|
483
|
+
sourcemap,
|
|
484
|
+
pages: ctx.allPages
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
if (enabledStages.has("style")) compileTasks.push({
|
|
489
|
+
title: labels.style,
|
|
490
|
+
rendererOptions: {
|
|
491
|
+
outputBar: true,
|
|
492
|
+
persistentOutput: false
|
|
493
|
+
},
|
|
494
|
+
task: async (ctx, task) => {
|
|
495
|
+
const stylePages = {
|
|
496
|
+
...ctx.pages,
|
|
497
|
+
mainPages: [{
|
|
498
|
+
path: "app",
|
|
499
|
+
id: getAppStyleScopeId()
|
|
500
|
+
}, ...ctx.pages.mainPages]
|
|
501
|
+
};
|
|
502
|
+
return runCompileInWorker("style", ctx, task, {
|
|
503
|
+
sourcemap,
|
|
504
|
+
pages: stylePages
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
if (compileTasks.length > 0) return task.newListr(compileTasks, { concurrent: true });
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
title: labels.writeOutput,
|
|
513
|
+
task: () => {
|
|
514
|
+
publishToDist(targetPath, useAppIdDir);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
], {
|
|
518
|
+
concurrent: false,
|
|
519
|
+
rendererOptions: {
|
|
520
|
+
collapseSubtasks: true,
|
|
521
|
+
formatOutput: "truncate",
|
|
522
|
+
timer: PRESET_TIMER
|
|
523
|
+
},
|
|
524
|
+
fallbackRendererOptions: { timer: PRESET_TIMER }
|
|
525
|
+
}).run();
|
|
526
|
+
printCompatibilityWarnings(workPath, context.compatibilityWarnings);
|
|
527
|
+
return {
|
|
528
|
+
appId: getAppId(),
|
|
529
|
+
name: getAppName(),
|
|
530
|
+
path: getAppConfigInfo().entryPagePath || context.allPages.mainPages[0].path,
|
|
531
|
+
dependencyGraph: context.dependencyGraph.toJSON()
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function filterPagesByEntries(pages, affectedEntries) {
|
|
535
|
+
if (!Array.isArray(affectedEntries)) return pages;
|
|
536
|
+
const selected = new Set(affectedEntries);
|
|
537
|
+
return {
|
|
538
|
+
mainPages: pages.mainPages.filter((page) => selected.has(page.path)),
|
|
539
|
+
subPages: Object.fromEntries(Object.entries(pages.subPages).map(([root, subPackage]) => [root, {
|
|
540
|
+
...subPackage,
|
|
541
|
+
info: subPackage.info.filter((page) => selected.has(page.path))
|
|
542
|
+
}]).filter(([, subPackage]) => subPackage.info.length > 0))
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
async function buildStyleOnly(targetPath, workPath, useAppIdDir = true, options = {}) {
|
|
546
|
+
storeInfo(workPath, { fileTypes: options.fileTypes });
|
|
547
|
+
const pages = getPages();
|
|
548
|
+
const affectedPages = getAffectedPages(pages, options.changedPath, getStyleOnlyChangedPathPattern());
|
|
549
|
+
const progress = { completedTasks: 0 };
|
|
550
|
+
await compileSS(affectedPages.mainPages, null, progress);
|
|
551
|
+
for (const [root, subPages] of Object.entries(affectedPages.subPages)) await compileSS(subPages.info, root, progress);
|
|
552
|
+
publishCssToDist(targetPath, useAppIdDir);
|
|
553
|
+
return {
|
|
554
|
+
appId: getAppId(),
|
|
555
|
+
name: getAppName(),
|
|
556
|
+
path: getAppConfigInfo().entryPagePath || pages.mainPages[0]?.path,
|
|
557
|
+
styleOnly: true,
|
|
558
|
+
compiledTasks: progress.completedTasks
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
async function buildViewOnly(targetPath, workPath, useAppIdDir = true, options = {}) {
|
|
562
|
+
resetViewCompilerCache();
|
|
563
|
+
storeInfo(workPath, { fileTypes: options.fileTypes });
|
|
564
|
+
const pages = getPages();
|
|
565
|
+
const affectedPages = getAffectedPages(pages, options.changedPath, getViewOnlyChangedPathPattern());
|
|
566
|
+
const progress = { completedTasks: 0 };
|
|
567
|
+
await compileML(affectedPages.mainPages, null, progress);
|
|
568
|
+
for (const [root, subPages] of Object.entries(affectedPages.subPages)) await compileML(subPages.info, root, progress);
|
|
569
|
+
publishFilesToDist(targetPath, useAppIdDir, ".js");
|
|
570
|
+
return {
|
|
571
|
+
appId: getAppId(),
|
|
572
|
+
name: getAppName(),
|
|
573
|
+
path: getAppConfigInfo().entryPagePath || pages.mainPages[0].path,
|
|
574
|
+
viewOnly: true,
|
|
575
|
+
compiledTasks: progress.completedTasks,
|
|
576
|
+
updatedPages: collectUpdatedPages(affectedPages)
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
async function buildLogicOnly(targetPath, workPath, useAppIdDir = true, options = {}) {
|
|
580
|
+
const currentStoreInfo = storeInfo(workPath, { fileTypes: options.fileTypes });
|
|
581
|
+
const pages = getPages();
|
|
582
|
+
await runCompileInWorker("logic", {
|
|
583
|
+
pages,
|
|
584
|
+
storeInfo: currentStoreInfo
|
|
585
|
+
}, {}, { sourcemap: options.sourcemap });
|
|
586
|
+
publishFilesToDist(targetPath, useAppIdDir, ".js");
|
|
587
|
+
return {
|
|
588
|
+
appId: getAppId(),
|
|
589
|
+
name: getAppName(),
|
|
590
|
+
path: getAppConfigInfo().entryPagePath || pages.mainPages[0].path,
|
|
591
|
+
logicOnly: true,
|
|
592
|
+
compiledTasks: pages.mainPages.length + Object.values(pages.subPages).reduce((sum, item) => sum + item.info.length, 0),
|
|
593
|
+
updatedPages: collectUpdatedPages(pages)
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function collectUpdatedPages(pages) {
|
|
597
|
+
return [...pages.mainPages.map((page) => ({
|
|
598
|
+
pagePath: page.path,
|
|
599
|
+
root: "main"
|
|
600
|
+
})), ...Object.entries(pages.subPages).flatMap(([root, subPackage]) => subPackage.info.map((page) => ({
|
|
601
|
+
pagePath: page.path,
|
|
602
|
+
root
|
|
603
|
+
})))];
|
|
604
|
+
}
|
|
605
|
+
function getAffectedPages(pages, changedPath, extensionPattern) {
|
|
606
|
+
const appStylePage = {
|
|
607
|
+
path: "app",
|
|
608
|
+
id: ""
|
|
609
|
+
};
|
|
610
|
+
if (!changedPath) return {
|
|
611
|
+
mainPages: extensionPattern.test("app.wxss") ? [appStylePage, ...pages.mainPages] : pages.mainPages,
|
|
612
|
+
subPages: pages.subPages
|
|
613
|
+
};
|
|
614
|
+
const modulePath = normalizeChangedModulePath(changedPath, extensionPattern);
|
|
615
|
+
if (!modulePath) return {
|
|
616
|
+
mainPages: extensionPattern.test("app.wxss") ? [appStylePage, ...pages.mainPages] : pages.mainPages,
|
|
617
|
+
subPages: pages.subPages
|
|
618
|
+
};
|
|
619
|
+
if (modulePath === "app") return {
|
|
620
|
+
mainPages: [appStylePage],
|
|
621
|
+
subPages: {}
|
|
622
|
+
};
|
|
623
|
+
const mainPages = pages.mainPages.filter((page) => isStyleModuleAffected(page, modulePath));
|
|
624
|
+
const subPages = {};
|
|
625
|
+
for (const [root, subPackage] of Object.entries(pages.subPages)) {
|
|
626
|
+
const info = subPackage.info.filter((page) => isStyleModuleAffected(page, modulePath));
|
|
627
|
+
if (info.length) subPages[root] = {
|
|
628
|
+
...subPackage,
|
|
629
|
+
info
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
if (!mainPages.length && !Object.keys(subPages).length) return {
|
|
633
|
+
mainPages: extensionPattern.test("app.wxss") ? [appStylePage, ...pages.mainPages] : pages.mainPages,
|
|
634
|
+
subPages: pages.subPages
|
|
635
|
+
};
|
|
636
|
+
return {
|
|
637
|
+
mainPages,
|
|
638
|
+
subPages
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function normalizeChangedModulePath(changedPath, extensionPattern) {
|
|
642
|
+
const relativePath = path.relative(getWorkPath(), changedPath);
|
|
643
|
+
if (!relativePath || relativePath.startsWith("..") || path.isAbsolute(relativePath)) return null;
|
|
644
|
+
return relativePath.replace(/\\/g, "/").replace(extensionPattern, "");
|
|
645
|
+
}
|
|
646
|
+
function isStyleModuleAffected(page, modulePath, visited = /* @__PURE__ */ new Set()) {
|
|
647
|
+
if (isSameStyleModulePath(page.path, modulePath)) return true;
|
|
648
|
+
if (!page.usingComponents || visited.has(page.path)) return false;
|
|
649
|
+
visited.add(page.path);
|
|
650
|
+
for (const componentPath of Object.values(page.usingComponents)) {
|
|
651
|
+
if (isSameStyleModulePath(componentPath, modulePath)) return true;
|
|
652
|
+
const component = getComponent(componentPath);
|
|
653
|
+
if (component && isStyleModuleAffected(component, modulePath, visited)) return true;
|
|
654
|
+
}
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
function isSameStyleModulePath(left, right) {
|
|
658
|
+
return String(left || "").replace(/^\/+/, "") === String(right || "").replace(/^\/+/, "");
|
|
659
|
+
}
|
|
660
|
+
function createExtensionPattern(extensions) {
|
|
661
|
+
const normalizedExts = [...new Set(extensions)].map((ext) => String(ext).trim().toLowerCase()).filter(Boolean).map((ext) => ext.startsWith(".") ? ext.slice(1) : ext).map((ext) => ext.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
662
|
+
return new RegExp(`\\.(?:${normalizedExts.join("|")})$`, "i");
|
|
663
|
+
}
|
|
664
|
+
function publishCssToDist(dist, useAppIdDir = true) {
|
|
665
|
+
publishFilesToDist(dist, useAppIdDir, ".css");
|
|
666
|
+
}
|
|
667
|
+
function publishFilesToDist(dist, useAppIdDir = true, extension) {
|
|
668
|
+
const sourceRoot = getTargetPath();
|
|
669
|
+
const targetRoot = useAppIdDir ? path.join(path.resolve(process.cwd(), dist), getAppId()) : path.resolve(process.cwd(), dist);
|
|
670
|
+
function copyFiles(src, dest) {
|
|
671
|
+
if (!fs.existsSync(src)) return;
|
|
672
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
673
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
674
|
+
const srcPath = path.join(src, entry.name);
|
|
675
|
+
const destPath = path.join(dest, entry.name);
|
|
676
|
+
if (entry.isDirectory()) copyFiles(srcPath, destPath);
|
|
677
|
+
else if (entry.isFile() && entry.name.endsWith(extension)) fs.copyFileSync(srcPath, destPath);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
copyFiles(sourceRoot, targetRoot);
|
|
681
|
+
}
|
|
682
|
+
function runCompileInWorker(script, ctx, task, options = {}) {
|
|
683
|
+
return workerPool.runWorker(() => new Promise((resolve, reject) => {
|
|
684
|
+
const worker = new Worker(path.join(path.dirname(fileURLToPath(import.meta.url)), `core/${script}-compiler.js`), workerPool.getWorkerOptions());
|
|
685
|
+
const pages = options.pages || ctx.pages;
|
|
686
|
+
const totalTasks = Object.keys(pages.mainPages).length + Object.values(pages.subPages).reduce((sum, item) => sum + item.info.length, 0);
|
|
687
|
+
let isResolved = false;
|
|
688
|
+
let workerError = null;
|
|
689
|
+
const handleError = (error) => {
|
|
690
|
+
if (isResolved) return;
|
|
691
|
+
isResolved = true;
|
|
692
|
+
worker.terminate();
|
|
693
|
+
reject(error);
|
|
694
|
+
};
|
|
695
|
+
worker.postMessage({
|
|
696
|
+
pages,
|
|
697
|
+
storeInfo: ctx.storeInfo,
|
|
698
|
+
sourcemap: !!options.sourcemap
|
|
699
|
+
});
|
|
700
|
+
worker.on("message", (message) => {
|
|
701
|
+
try {
|
|
702
|
+
for (const warning of message.compatibilityWarnings || []) ctx.compatibilityWarnings.add(warning);
|
|
703
|
+
if (process.stdout.isTTY && message.completedTasks !== void 0) task.output = formatCompileProgress(message.completedTasks, totalTasks);
|
|
704
|
+
if (message.success) {
|
|
705
|
+
if (isResolved) return;
|
|
706
|
+
isResolved = true;
|
|
707
|
+
if (process.stdout.isTTY && totalTasks > 0) task.output = formatCompileProgress(totalTasks, totalTasks);
|
|
708
|
+
ctx.dependencyGraph.merge(message.dependencyGraph);
|
|
709
|
+
worker.terminate();
|
|
710
|
+
resolve();
|
|
711
|
+
} else if (message.error) {
|
|
712
|
+
const error = new Error(message.error.message || message.error);
|
|
713
|
+
if (message.error.name) error.name = message.error.name;
|
|
714
|
+
if (message.error.stack) error.stack = message.error.stack;
|
|
715
|
+
if (message.error.file) error.file = message.error.file;
|
|
716
|
+
if (message.error.line != null) error.line = message.error.line;
|
|
717
|
+
if (message.error.column != null) error.column = message.error.column;
|
|
718
|
+
if (message.error.stage) error.stage = message.error.stage;
|
|
719
|
+
handleError(error);
|
|
720
|
+
}
|
|
721
|
+
} catch (err) {
|
|
722
|
+
handleError(/* @__PURE__ */ new Error(`Error processing worker message: ${err.message}\n${err.stack}`));
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
worker.on("error", (err) => {
|
|
726
|
+
workerError = err;
|
|
727
|
+
handleError(err);
|
|
728
|
+
});
|
|
729
|
+
worker.on("exit", (code) => {
|
|
730
|
+
if (code !== 0 && !isResolved) {
|
|
731
|
+
const error = workerError || /* @__PURE__ */ new Error(code === 1 ? "Worker terminated due to reaching memory limit: JS heap out of memory" : `Worker stopped with exit code ${code}`);
|
|
732
|
+
handleError(error);
|
|
733
|
+
}
|
|
734
|
+
});
|
|
735
|
+
}));
|
|
736
|
+
}
|
|
737
|
+
function printCompatibilityWarnings(workPath, warnings = /* @__PURE__ */ new Set()) {
|
|
738
|
+
const projectPath = path.resolve(workPath);
|
|
739
|
+
const hasPreviousResult = previousCompatibilityWarnings.has(projectPath);
|
|
740
|
+
const previousWarnings = previousCompatibilityWarnings.get(projectPath) || /* @__PURE__ */ new Set();
|
|
741
|
+
const currentWarnings = new Set(warnings);
|
|
742
|
+
const newWarnings = [...currentWarnings].filter((warning) => !previousWarnings.has(warning));
|
|
743
|
+
previousCompatibilityWarnings.set(projectPath, currentWarnings);
|
|
744
|
+
if (newWarnings.length === 0) return;
|
|
745
|
+
const qualifier = hasPreviousResult ? " new" : "";
|
|
746
|
+
const suffix = newWarnings.length === 1 ? "" : "s";
|
|
747
|
+
console.warn(`\n[compat] ${newWarnings.length}${qualifier} compatibility warning${suffix}`);
|
|
748
|
+
for (const warning of newWarnings) console.warn(` - ${warning.replace(/^\[compat\]\s*/, "")}`);
|
|
749
|
+
}
|
|
750
|
+
//#endregion
|
|
751
|
+
export { buildLogicOnly, buildStyleOnly, buildViewOnly, build as default };
|