Обновление файла скрипта запуска серверов
This commit is contained in:
parent
1ee9cbe9fe
commit
8c2d4007fa
2 changed files with 176 additions and 1 deletions
|
|
@ -4,7 +4,7 @@
|
|||
"description": "Монорепозиторий для Astro + PocketBase проекта",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"bun run dev:maildev\" \"bun run dev:frontend\" \"bun run dev:backend\"",
|
||||
"dev": "bun ./scripts/dev.js",
|
||||
"dev:maildev": "maildev",
|
||||
"dev:frontend": "cd frontend && bun run dev",
|
||||
"dev:backend": "cd backend && ./pocketbase.exe serve",
|
||||
|
|
|
|||
175
scripts/dev.js
Normal file
175
scripts/dev.js
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun";
|
||||
import { spawn } from "child_process";
|
||||
import path from "path";
|
||||
import { promisify } from "util";
|
||||
import net from "net";
|
||||
import chalk from "chalk";
|
||||
|
||||
const sleep = promisify(setTimeout);
|
||||
|
||||
async function isPortInUse(port) {
|
||||
return new Promise((resolve) => {
|
||||
const server = net.createServer();
|
||||
server.once("error", () => resolve(true));
|
||||
server.once("listening", () => {
|
||||
server.close();
|
||||
resolve(false);
|
||||
});
|
||||
server.listen(port);
|
||||
});
|
||||
}
|
||||
|
||||
async function killProcess(pid, force = true) {
|
||||
try {
|
||||
if (process.platform === "win32") {
|
||||
await $`taskkill /PID ${pid} ${force ? "/F" : ""}`.quiet();
|
||||
} else {
|
||||
process.kill(pid, force ? "SIGKILL" : "SIGTERM");
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
async function killPort(port) {
|
||||
try {
|
||||
if (process.platform === "win32") {
|
||||
const { stdout } = await $`netstat -ano | findstr :${port}`.quiet().nothrow();
|
||||
const lines = stdout.toString().trim().split("\n");
|
||||
const pids = new Set();
|
||||
|
||||
for (const line of lines) {
|
||||
const parts = line.trim().split(/\s+/);
|
||||
if (parts.length >= 5) {
|
||||
const pid = parts[4];
|
||||
if (pid && !isNaN(parseInt(pid))) {
|
||||
pids.add(parseInt(pid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const pid of pids) {
|
||||
await killProcess(pid);
|
||||
console.log(chalk.yellow(` 🔪 Убит процесс ${pid} на порту ${port}`));
|
||||
}
|
||||
} else {
|
||||
await $`lsof -ti:${port} | xargs kill -9`.quiet().nothrow();
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanupPorts() {
|
||||
console.log(chalk.cyan("🔍 Проверка портов..."));
|
||||
const ports = [1025, 1080, 4321, 8090];
|
||||
|
||||
for (const port of ports) {
|
||||
if (await isPortInUse(port)) {
|
||||
console.log(chalk.yellow(` ⚠️ Порт ${port} занят, освобождаем...`));
|
||||
await killPort(port);
|
||||
await sleep(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let maildev, backend, frontend;
|
||||
|
||||
async function cleanup() {
|
||||
console.log(chalk.red("\n🛑 Остановка серверов..."));
|
||||
|
||||
const kills = [];
|
||||
|
||||
if (maildev && !maildev.killed) {
|
||||
maildev.kill("SIGKILL");
|
||||
kills.push(new Promise(r => maildev.once("exit", r)));
|
||||
}
|
||||
if (backend && !backend.killed) {
|
||||
backend.kill("SIGKILL");
|
||||
kills.push(new Promise(r => backend.once("exit", r)));
|
||||
}
|
||||
if (frontend && !frontend.killed) {
|
||||
frontend.kill("SIGKILL");
|
||||
kills.push(new Promise(r => frontend.once("exit", r)));
|
||||
}
|
||||
|
||||
await Promise.race([
|
||||
Promise.all(kills),
|
||||
sleep(3000)
|
||||
]);
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await cleanupPorts();
|
||||
|
||||
console.log(chalk.green.bold("🚀 Запуск серверов astro-advokat...\n"));
|
||||
|
||||
maildev = spawn("maildev", ["--web", "1080", "--smtp", "1025"], {
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
windowsHide: true,
|
||||
detached: false
|
||||
});
|
||||
|
||||
backend = spawn("pocketbase.exe", ["serve"], {
|
||||
cwd: path.join(process.cwd(), "backend"),
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
windowsHide: true,
|
||||
detached: false,
|
||||
env: {
|
||||
...process.env,
|
||||
PB_SMTP_HOST: "localhost",
|
||||
PB_SMTP_PORT: "1025",
|
||||
PB_SMTP_FROM: "noreply@advokat-surgut.ru"
|
||||
}
|
||||
});
|
||||
|
||||
frontend = spawn("bun", ["dev"], {
|
||||
cwd: "frontend",
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
windowsHide: true,
|
||||
detached: false
|
||||
});
|
||||
|
||||
process.on("SIGINT", cleanup);
|
||||
process.on("SIGTERM", cleanup);
|
||||
process.on("SIGBREAK", cleanup);
|
||||
|
||||
if (process.platform === "win32") {
|
||||
const readline = await import("readline");
|
||||
readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
}).on("SIGINT", cleanup);
|
||||
}
|
||||
|
||||
maildev.on("exit", (code) => {
|
||||
console.log(chalk.gray(`\n📧 Maildev остановлен с кодом ${code}`));
|
||||
if (code !== 0 && code !== null) cleanup();
|
||||
});
|
||||
|
||||
backend.on("exit", (code) => {
|
||||
console.log(chalk.gray(`\n💾 Backend остановлен с кодом ${code}`));
|
||||
if (code !== 0 && code !== null) cleanup();
|
||||
});
|
||||
|
||||
frontend.on("exit", (code) => {
|
||||
console.log(chalk.gray(`\n🌐 Frontend остановлен с кодом ${code}`));
|
||||
cleanup();
|
||||
});
|
||||
|
||||
console.log(chalk.green("✅ Серверы запущены:\n"));
|
||||
console.log(chalk.blue(" 📧 Maildev (SMTP): ") + chalk.underline("http://localhost:1080"));
|
||||
console.log(chalk.blue(" 💾 Backend (PocketBase): ") + chalk.underline("http://localhost:8090"));
|
||||
console.log(chalk.blue(" 🌐 Frontend (Astro): ") + chalk.underline("http://localhost:4321") + "\n");
|
||||
console.log(chalk.gray("Нажмите Ctrl+C для остановки\n"));
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(chalk.red("❌ Ошибка:"), err);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue