napcat-plugin-debug-cli 1.2.2 → 1.2.4
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/cli.mjs +31 -2
- package/package.json +1 -1
- package/vite.mjs +144 -1
package/cli.mjs
CHANGED
|
@@ -5149,13 +5149,42 @@ function createWatcher(watchPath, onPluginChange) {
|
|
|
5149
5149
|
const watchers = /* @__PURE__ */ new Map();
|
|
5150
5150
|
const timers = /* @__PURE__ */ new Map();
|
|
5151
5151
|
let active = false;
|
|
5152
|
-
const EXTS = /* @__PURE__ */ new Set([
|
|
5152
|
+
const EXTS = /* @__PURE__ */ new Set([
|
|
5153
|
+
".js",
|
|
5154
|
+
".mjs",
|
|
5155
|
+
".cjs",
|
|
5156
|
+
".ts",
|
|
5157
|
+
".mts",
|
|
5158
|
+
".cts",
|
|
5159
|
+
".json",
|
|
5160
|
+
// 前端 / WebUI 相关
|
|
5161
|
+
".jsx",
|
|
5162
|
+
".tsx",
|
|
5163
|
+
".vue",
|
|
5164
|
+
".svelte",
|
|
5165
|
+
".html",
|
|
5166
|
+
".htm",
|
|
5167
|
+
".css",
|
|
5168
|
+
".scss",
|
|
5169
|
+
".sass",
|
|
5170
|
+
".less",
|
|
5171
|
+
".styl",
|
|
5172
|
+
".svg",
|
|
5173
|
+
".png",
|
|
5174
|
+
".jpg",
|
|
5175
|
+
".jpeg",
|
|
5176
|
+
".gif",
|
|
5177
|
+
".webp",
|
|
5178
|
+
".ico"
|
|
5179
|
+
]);
|
|
5180
|
+
const IGNORE_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".vite", ".cache"]);
|
|
5153
5181
|
function watchDir(name, dirPath) {
|
|
5154
5182
|
try {
|
|
5155
5183
|
const w = fs.watch(dirPath, { recursive: true, persistent: false }, (_ev, file) => {
|
|
5156
5184
|
if (!file) return;
|
|
5157
5185
|
if (!EXTS.has(path.extname(file))) return;
|
|
5158
|
-
|
|
5186
|
+
const parts = file.split(/[\\/]/);
|
|
5187
|
+
if (parts.some((p) => IGNORE_DIRS.has(p) || p.startsWith("."))) return;
|
|
5159
5188
|
const t = timers.get(name);
|
|
5160
5189
|
if (t) clearTimeout(t);
|
|
5161
5190
|
timers.set(name, setTimeout(() => {
|
package/package.json
CHANGED
package/vite.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
3
4
|
|
|
4
5
|
const C = {
|
|
5
6
|
reset: "\x1B[0m",
|
|
@@ -86,13 +87,17 @@ function napcatHmrPlugin(options = {}) {
|
|
|
86
87
|
wsUrl = "ws://127.0.0.1:8998",
|
|
87
88
|
token,
|
|
88
89
|
enabled = true,
|
|
89
|
-
autoConnect = true
|
|
90
|
+
autoConnect = true,
|
|
91
|
+
webui
|
|
90
92
|
} = options;
|
|
93
|
+
const webuiConfigs = webui ? Array.isArray(webui) ? webui : [webui] : [];
|
|
91
94
|
let rpc = null;
|
|
92
95
|
let remotePluginPath = null;
|
|
93
96
|
let connecting = false;
|
|
94
97
|
let config;
|
|
95
98
|
let isFirstBuild = true;
|
|
99
|
+
const webuiWatchers = [];
|
|
100
|
+
let webuiDeployDebounceTimer = null;
|
|
96
101
|
async function connect() {
|
|
97
102
|
if (rpc?.connected) return true;
|
|
98
103
|
if (connecting) return false;
|
|
@@ -183,6 +188,37 @@ function napcatHmrPlugin(options = {}) {
|
|
|
183
188
|
logErr(`复制文件失败: ${e.message}`);
|
|
184
189
|
return;
|
|
185
190
|
}
|
|
191
|
+
const projectRoot = config.root || process.cwd();
|
|
192
|
+
for (const wc of webuiConfigs) {
|
|
193
|
+
const webuiTargetDir = wc.targetDir || "webui";
|
|
194
|
+
const webuiDistDir = path.resolve(projectRoot, wc.distDir);
|
|
195
|
+
const webuiRoot = wc.root ? path.resolve(projectRoot, wc.root) : path.dirname(webuiDistDir);
|
|
196
|
+
if (wc.buildCommand) {
|
|
197
|
+
try {
|
|
198
|
+
log(`构建 WebUI (${co(webuiTargetDir, C.cyan)})...`);
|
|
199
|
+
execSync(wc.buildCommand, {
|
|
200
|
+
cwd: webuiRoot,
|
|
201
|
+
stdio: "pipe",
|
|
202
|
+
env: { ...process.env, NODE_ENV: "production" }
|
|
203
|
+
});
|
|
204
|
+
logOk(`WebUI (${webuiTargetDir}) 构建完成`);
|
|
205
|
+
} catch (e) {
|
|
206
|
+
logErr(`WebUI (${webuiTargetDir}) 构建失败: ${e.stderr?.toString() || e.message}`);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (!fs.existsSync(webuiDistDir)) {
|
|
211
|
+
logErr(`WebUI 产物目录不存在: ${webuiDistDir}`);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const webuiDestDir = path.join(destDir, webuiTargetDir);
|
|
216
|
+
copyDirRecursive(webuiDistDir, webuiDestDir);
|
|
217
|
+
logOk(`WebUI (${webuiTargetDir}) 已部署 (${countFiles(webuiDistDir)} 个文件)`);
|
|
218
|
+
} catch (e) {
|
|
219
|
+
logErr(`WebUI (${webuiTargetDir}) 部署失败: ${e.message}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
186
222
|
try {
|
|
187
223
|
const reloaded = await rpc.call("reloadPlugin", pluginName);
|
|
188
224
|
if (reloaded === false) {
|
|
@@ -203,6 +239,98 @@ function napcatHmrPlugin(options = {}) {
|
|
|
203
239
|
}
|
|
204
240
|
}
|
|
205
241
|
}
|
|
242
|
+
async function deployWebuiOnly() {
|
|
243
|
+
if (!rpc?.connected || !remotePluginPath) {
|
|
244
|
+
logErr("未连接到调试服务,跳过 WebUI 部署");
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const distDir = path.resolve(config.build.outDir);
|
|
248
|
+
const pkgPath = path.join(distDir, "package.json");
|
|
249
|
+
if (!fs.existsSync(pkgPath)) {
|
|
250
|
+
logErr("dist/package.json 不存在,跳过 WebUI 部署");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
let pluginName;
|
|
254
|
+
try {
|
|
255
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
256
|
+
pluginName = pkg.name;
|
|
257
|
+
if (!pluginName) return;
|
|
258
|
+
} catch {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const destDir = path.join(remotePluginPath, pluginName);
|
|
262
|
+
const projectRoot = config.root || process.cwd();
|
|
263
|
+
let hasChanges = false;
|
|
264
|
+
for (const wc of webuiConfigs) {
|
|
265
|
+
const webuiTargetDir = wc.targetDir || "webui";
|
|
266
|
+
const webuiDistDir = path.resolve(projectRoot, wc.distDir);
|
|
267
|
+
const webuiRoot = wc.root ? path.resolve(projectRoot, wc.root) : path.dirname(webuiDistDir);
|
|
268
|
+
if (wc.buildCommand) {
|
|
269
|
+
try {
|
|
270
|
+
log(`构建 WebUI (${co(webuiTargetDir, C.cyan)})...`);
|
|
271
|
+
execSync(wc.buildCommand, {
|
|
272
|
+
cwd: webuiRoot,
|
|
273
|
+
stdio: "pipe",
|
|
274
|
+
env: { ...process.env, NODE_ENV: "production" }
|
|
275
|
+
});
|
|
276
|
+
logOk(`WebUI (${webuiTargetDir}) 构建完成`);
|
|
277
|
+
} catch (e) {
|
|
278
|
+
logErr(`WebUI (${webuiTargetDir}) 构建失败: ${e.stderr?.toString() || e.message}`);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!fs.existsSync(webuiDistDir)) {
|
|
283
|
+
logErr(`WebUI 产物目录不存在: ${webuiDistDir}`);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const webuiDestDir = path.join(destDir, webuiTargetDir);
|
|
288
|
+
if (fs.existsSync(webuiDestDir)) {
|
|
289
|
+
fs.rmSync(webuiDestDir, { recursive: true, force: true });
|
|
290
|
+
}
|
|
291
|
+
copyDirRecursive(webuiDistDir, webuiDestDir);
|
|
292
|
+
logOk(`WebUI (${webuiTargetDir}) 已部署 (${countFiles(webuiDistDir)} 个文件)`);
|
|
293
|
+
hasChanges = true;
|
|
294
|
+
} catch (e) {
|
|
295
|
+
logErr(`WebUI (${webuiTargetDir}) 部署失败: ${e.message}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (hasChanges) {
|
|
299
|
+
try {
|
|
300
|
+
await rpc.call("reloadPlugin", pluginName);
|
|
301
|
+
logHmr(`${co(pluginName, C.green, C.bold)} 已重载 (WebUI 更新)`);
|
|
302
|
+
} catch (e) {
|
|
303
|
+
logErr(`重载失败: ${e.message}`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function startWebuiWatchers(projectRoot) {
|
|
308
|
+
for (const wc of webuiConfigs) {
|
|
309
|
+
if (!wc.watchDir) continue;
|
|
310
|
+
const watchPath = path.resolve(projectRoot, wc.watchDir);
|
|
311
|
+
const webuiTargetDir = wc.targetDir || "webui";
|
|
312
|
+
if (!fs.existsSync(watchPath)) {
|
|
313
|
+
logErr(`WebUI watchDir 不存在: ${watchPath}`);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const watcher = fs.watch(watchPath, { recursive: true }, (_event, filename) => {
|
|
318
|
+
if (!filename) return;
|
|
319
|
+
const normalized = filename.replace(/\\/g, "/");
|
|
320
|
+
if (normalized.includes("node_modules") || normalized.includes("/dist/") || normalized.startsWith("dist/") || normalized.startsWith(".")) return;
|
|
321
|
+
if (webuiDeployDebounceTimer) clearTimeout(webuiDeployDebounceTimer);
|
|
322
|
+
webuiDeployDebounceTimer = setTimeout(() => {
|
|
323
|
+
log(`WebUI 文件变化: ${co(normalized, C.dim)}`);
|
|
324
|
+
deployWebuiOnly().catch((e) => logErr(`WebUI 部署出错: ${e.message}`));
|
|
325
|
+
}, 300);
|
|
326
|
+
});
|
|
327
|
+
webuiWatchers.push(watcher);
|
|
328
|
+
logOk(`监听 WebUI (${webuiTargetDir}): ${co(watchPath, C.dim)}`);
|
|
329
|
+
} catch (e) {
|
|
330
|
+
logErr(`无法监听 WebUI 目录: ${e.message}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
206
334
|
return {
|
|
207
335
|
name: "napcat-hmr",
|
|
208
336
|
apply: "build",
|
|
@@ -230,9 +358,24 @@ function napcatHmrPlugin(options = {}) {
|
|
|
230
358
|
if (!ok) return;
|
|
231
359
|
}
|
|
232
360
|
await deployAndReload(distDir);
|
|
361
|
+
if (isFirstBuild && config.build.watch && webuiConfigs.some((wc) => wc.watchDir)) {
|
|
362
|
+
const projectRoot = config.root || process.cwd();
|
|
363
|
+
startWebuiWatchers(projectRoot);
|
|
364
|
+
}
|
|
233
365
|
isFirstBuild = false;
|
|
234
366
|
},
|
|
235
367
|
closeBundle() {
|
|
368
|
+
for (const w of webuiWatchers) {
|
|
369
|
+
try {
|
|
370
|
+
w.close();
|
|
371
|
+
} catch {
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
webuiWatchers.length = 0;
|
|
375
|
+
if (webuiDeployDebounceTimer) {
|
|
376
|
+
clearTimeout(webuiDeployDebounceTimer);
|
|
377
|
+
webuiDeployDebounceTimer = null;
|
|
378
|
+
}
|
|
236
379
|
if (config.build.watch) return;
|
|
237
380
|
rpc?.close();
|
|
238
381
|
rpc = null;
|