@lark-apaas/coding-templates 0.1.43-alpha.10 → 0.1.43-alpha.12
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/package.json
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@radix-ui/react-toggle": "^1.1.9",
|
|
45
45
|
"@radix-ui/react-toggle-group": "^1.1.10",
|
|
46
46
|
"@radix-ui/react-tooltip": "^1.1.18",
|
|
47
|
-
"@lark-apaas/client-toolkit-lite": "1.1.7-alpha.
|
|
47
|
+
"@lark-apaas/client-toolkit-lite": "1.1.7-alpha.14",
|
|
48
48
|
"@formkit/auto-animate": "^0.9.0",
|
|
49
49
|
"@gsap/react": "^2.1.2",
|
|
50
50
|
"framer-motion": "^12.38.0",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@types/react": "^19",
|
|
81
81
|
"@types/react-dom": "^19",
|
|
82
82
|
"@lark-apaas/coding-presets": "^1.0.0",
|
|
83
|
-
"@lark-apaas/coding-vite-preset": "1.0.7-alpha.
|
|
83
|
+
"@lark-apaas/coding-vite-preset": "1.0.7-alpha.10",
|
|
84
84
|
"concurrently": "^9",
|
|
85
85
|
"eslint": "^9",
|
|
86
86
|
"eslint-plugin-react-hooks": "^7",
|
|
@@ -11,20 +11,28 @@
|
|
|
11
11
|
* - vite → 8001(CLIENT_DEV_PORT 可覆盖)
|
|
12
12
|
* - mock-health → 3000(占位,老沙箱探针兼容用)
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* 进程组与孤儿清理:
|
|
15
|
+
* - 子进程 detached: true → 自己一个 PGID,cleanup 时 process.kill(-pid) 整组带走
|
|
16
|
+
* - 监听 SIGINT/SIGTERM/SIGHUP/uncaughtException 触发 cleanup
|
|
17
|
+
* - 启动前 killOrphansByPort 清理端口残留孤儿(应对沙箱保活重启)
|
|
18
|
+
*
|
|
19
|
+
* 触发重启场景:
|
|
20
|
+
* - `pkill -f "npm run dev"` 杀 npm 进程 → dev.cjs 收 SIGHUP → cleanup
|
|
21
|
+
* - 沙箱保活机制重启 npm run dev → 新 dev.cjs → killOrphansByPort 清理旧 vite/mock-health
|
|
15
22
|
*/
|
|
16
23
|
'use strict';
|
|
17
24
|
|
|
18
25
|
const fs = require('fs');
|
|
19
26
|
const path = require('path');
|
|
20
27
|
const readline = require('readline');
|
|
21
|
-
const { spawn } = require('child_process');
|
|
28
|
+
const { spawn, execSync } = require('child_process');
|
|
22
29
|
|
|
23
30
|
const ROOT = path.resolve(__dirname, '..');
|
|
24
31
|
process.chdir(ROOT);
|
|
25
32
|
|
|
26
33
|
const LOG_DIR = process.env.LOG_DIR || 'logs';
|
|
27
34
|
const CLIENT_DEV_PORT = process.env.CLIENT_DEV_PORT || '8001';
|
|
35
|
+
const HEALTH_PORT = '3000';
|
|
28
36
|
|
|
29
37
|
fs.mkdirSync(LOG_DIR, { recursive: true });
|
|
30
38
|
|
|
@@ -37,6 +45,38 @@ function timestamp() {
|
|
|
37
45
|
);
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
function log(msg) {
|
|
49
|
+
const line = `[${timestamp()}] [dev] ${msg}\n`;
|
|
50
|
+
try { process.stdout.write(line); } catch {}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 启动前清理端口占用的孤儿进程(沙箱保活重启时关键):
|
|
55
|
+
* 之前 dev.cjs 被 pkill 杀掉后,子进程的 vite/mock-health 可能没被一起带走,
|
|
56
|
+
* 保活机制重启新 dev.cjs 时发现端口被占,导致 vite/mock-health 起不来。
|
|
57
|
+
*/
|
|
58
|
+
function killOrphansByPort(port) {
|
|
59
|
+
try {
|
|
60
|
+
const out = execSync(`lsof -ti:${port}`, { stdio: ['ignore', 'pipe', 'ignore'] })
|
|
61
|
+
.toString()
|
|
62
|
+
.trim();
|
|
63
|
+
if (!out) return [];
|
|
64
|
+
const pids = out.split('\n').filter(Boolean);
|
|
65
|
+
for (const pid of pids) {
|
|
66
|
+
try {
|
|
67
|
+
process.kill(Number(pid), 'SIGKILL');
|
|
68
|
+
log(`killed orphan pid=${pid} on :${port}`);
|
|
69
|
+
} catch {
|
|
70
|
+
// 进程可能已退出
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return pids;
|
|
74
|
+
} catch {
|
|
75
|
+
// lsof 没找到任何占用,正常情况
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
40
80
|
const managed = [];
|
|
41
81
|
|
|
42
82
|
function startProcess({ name, command, args, logFileName }) {
|
|
@@ -69,6 +109,10 @@ function startProcess({ name, command, args, logFileName }) {
|
|
|
69
109
|
return child;
|
|
70
110
|
}
|
|
71
111
|
|
|
112
|
+
// 先清掉可能残留的孤儿进程,再启动新子进程
|
|
113
|
+
killOrphansByPort(CLIENT_DEV_PORT);
|
|
114
|
+
killOrphansByPort(HEALTH_PORT);
|
|
115
|
+
|
|
72
116
|
startProcess({
|
|
73
117
|
name: 'client',
|
|
74
118
|
command: 'npx',
|
|
@@ -87,6 +131,8 @@ let stopping = false;
|
|
|
87
131
|
function cleanup(signal) {
|
|
88
132
|
if (stopping) return;
|
|
89
133
|
stopping = true;
|
|
134
|
+
log(`cleanup triggered by ${signal}`);
|
|
135
|
+
|
|
90
136
|
for (const { child } of managed) {
|
|
91
137
|
if (!child.pid) continue;
|
|
92
138
|
try { process.kill(-child.pid, signal || 'SIGTERM'); } catch {}
|
|
@@ -96,12 +142,19 @@ function cleanup(signal) {
|
|
|
96
142
|
if (!child.pid) continue;
|
|
97
143
|
try { process.kill(-child.pid, 'SIGKILL'); } catch {}
|
|
98
144
|
}
|
|
145
|
+
// 兜底再扫一次端口,确保孤儿被清理
|
|
146
|
+
killOrphansByPort(CLIENT_DEV_PORT);
|
|
147
|
+
killOrphansByPort(HEALTH_PORT);
|
|
99
148
|
process.exit(0);
|
|
100
149
|
}, 2000);
|
|
101
150
|
}
|
|
102
151
|
|
|
103
152
|
process.on('SIGINT', () => cleanup('SIGTERM'));
|
|
104
153
|
process.on('SIGTERM', () => cleanup('SIGTERM'));
|
|
154
|
+
// pkill -f "npm run dev" 把 npm 杀掉后,dev.cjs 会收到 SIGHUP(controlling
|
|
155
|
+
// tty 关闭),Node 默认行为是直接退出不跑 handler。注册 SIGHUP handler 触发
|
|
156
|
+
// cleanup,让子进程组跟着一起死,避免变孤儿
|
|
157
|
+
process.on('SIGHUP', () => cleanup('SIGTERM'));
|
|
105
158
|
|
|
106
159
|
// 任意子进程退出就触发整体 cleanup,避免半残留
|
|
107
160
|
Promise.race(
|