chore(dev): 添加开发进程自动清理脚本
- 新增 kill:dev 脚本用于清理占用 18181 端口的进程 - 在 dev:fresh 和 dev:desktop:fresh 前自动执行清理 - 支持跨平台(Windows/Linux/macOS) - 双轮清理策略确保进程完全退出
This commit is contained in:
1 parent
9842a81f84
commit
b8cf182154
2 files changed
+142
-3
No files matched your search
+4
-3
@@ -18,11 +18,11 @@
|
||||
"build:desktop-only": "pnpm -F @prompt-optimizer/desktop build",
|
||||
"build:desktop": "npm-run-all build:core build:ui build:web build:desktop-only",
|
||||
"dev": "npm-run-all clean:dist build:core build:ui dev:parallel",
|
||||
"dev:fresh": "npm-run-all clean pnpm-install dev",
|
||||
"dev:fresh": "npm-run-all kill:dev clean pnpm-install dev",
|
||||
"dev:parallel": "concurrently -k -p \"[{name}]\" -n \"UI,WEB\" \"pnpm -F @prompt-optimizer/ui build --watch\" \"pnpm -F @prompt-optimizer/web dev\"",
|
||||
"dev:ext": "pnpm -F @prompt-optimizer/extension dev",
|
||||
"dev:desktop": "npm-run-all clean:dist build:core build:ui dev:desktop:parallel",
|
||||
"dev:desktop:fresh": "npm-run-all clean pnpm-install dev:desktop",
|
||||
"dev:desktop:fresh": "npm-run-all kill:dev clean pnpm-install dev:desktop",
|
||||
"dev:desktop:parallel": "concurrently -k -p \"[{name}]\" -n \"WEB,DESKTOP\" \"pnpm -F @prompt-optimizer/web dev\" \"pnpm -F @prompt-optimizer/desktop dev\"",
|
||||
"test": "pnpm -r test --run --passWithNoTests",
|
||||
"test:e2e": "playwright test",
|
||||
@@ -45,7 +45,8 @@
|
||||
"lint:fix": "pnpm -F @prompt-optimizer/ui lint:fix",
|
||||
"bmad:refresh": "bmad-method install -f -i codex",
|
||||
"bmad:list": "bmad-method list:agents",
|
||||
"bmad:validate": "bmad-method validate"
|
||||
"bmad:validate": "bmad-method validate",
|
||||
"kill:dev": "node scripts/kill-dev.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^6.0.3",
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* kill-dev v2 - Ultimate Safe Process Cleanup Script
|
||||
*
|
||||
* Strategy:
|
||||
* 1. Clean up processes occupying ports (most critical)
|
||||
* 2. Wait 2 seconds for parent processes to exit naturally
|
||||
* 3. Check ports again to ensure complete cleanup
|
||||
*
|
||||
* About "missed processes":
|
||||
* - Parent processes (pnpm) usually exit automatically after child processes terminate
|
||||
* - vite build --watch doesn't occupy ports, exits with parent process
|
||||
* - Even if missed, they don't occupy ports and won't block new starts
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const os = require('os');
|
||||
|
||||
console.log('🧹 Safely cleaning up project development processes...\n');
|
||||
|
||||
// Limit to project-specific ports so we do not kill other apps using defaults like 5173
|
||||
const PORTS = [18181];
|
||||
|
||||
/**
|
||||
* Cross-platform non-blocking sleep
|
||||
*/
|
||||
function wait(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function killByPorts(round = 1) {
|
||||
const platform = os.platform();
|
||||
let killedCount = 0;
|
||||
const killedPids = new Set();
|
||||
|
||||
console.log(`🔍 Round ${round}: Checking port occupation...`);
|
||||
|
||||
if (platform === 'win32') {
|
||||
for (const port of PORTS) {
|
||||
try {
|
||||
const output = execSync(`netstat -ano | findstr ":${port}"`, {
|
||||
encoding: 'utf-8',
|
||||
stdio: 'pipe'
|
||||
});
|
||||
|
||||
// Windows uses \r\n, so split by \n and trim each line
|
||||
const lines = output.split('\n').map(line => line.trim()).filter(Boolean);
|
||||
lines.forEach(line => {
|
||||
const match = line.match(/LISTENING\s+(\d+)/);
|
||||
if (match && !killedPids.has(match[1])) {
|
||||
const pid = match[1];
|
||||
try {
|
||||
execSync(`taskkill /F /PID ${pid}`, { stdio: 'pipe' });
|
||||
console.log(` ✓ Killed process on port ${port} (PID: ${pid})`);
|
||||
killedPids.add(pid);
|
||||
killedCount++;
|
||||
} catch (e) {
|
||||
// Process may have already exited
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
// Port not occupied or command failed
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const port of PORTS) {
|
||||
try {
|
||||
const output = execSync(`lsof -ti :${port}`, {
|
||||
encoding: 'utf-8',
|
||||
stdio: 'pipe'
|
||||
});
|
||||
|
||||
const pids = output.split('\n').map(pid => pid.trim()).filter(Boolean);
|
||||
pids.forEach(pid => {
|
||||
if (!killedPids.has(pid)) {
|
||||
try {
|
||||
execSync(`kill -9 ${pid}`, { stdio: 'pipe' });
|
||||
console.log(` ✓ Killed process on port ${port} (PID: ${pid})`);
|
||||
killedPids.add(pid);
|
||||
killedCount++;
|
||||
} catch (e) {
|
||||
// Process may have already exited
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
// Port not occupied or command failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (killedCount === 0) {
|
||||
console.log(' ℹ️ No processes found occupying ports');
|
||||
}
|
||||
|
||||
return killedCount;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// First round cleanup
|
||||
let totalKilled = killByPorts(1);
|
||||
|
||||
if (totalKilled > 0) {
|
||||
// Wait for parent processes to exit naturally (cross-platform)
|
||||
console.log('\n⏳ Waiting 2 seconds for parent processes to exit naturally...\n');
|
||||
await wait(2000);
|
||||
|
||||
// Second round cleanup (ensure no missed processes)
|
||||
const round2Killed = killByPorts(2);
|
||||
totalKilled += round2Killed;
|
||||
|
||||
if (round2Killed > 0) {
|
||||
console.log('\n💡 Found and cleaned up missed processes');
|
||||
} else {
|
||||
console.log('\n✅ Confirmed: All processes completely cleaned up');
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Total cleaned: ${totalKilled} process(es)`);
|
||||
|
||||
if (totalKilled > 0) {
|
||||
console.log('✅ Cleanup complete! You can now run pnpm dev:fresh');
|
||||
} else {
|
||||
console.log('ℹ️ No processes found that need cleanup');
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error('\n❌ Cleanup failed:', error.message);
|
||||
console.error('\n💡 Please try:');
|
||||
console.error(' 1. Run this script again');
|
||||
console.error(' 2. Or manually terminate related processes in Task Manager');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in new issue
Block a user