예제 소스
오목 Next.js 웹과 VLM 착수 API 연결하기 · 파일 59개
dev-with-ts.mjs
#!/usr/bin/env node
/**
* next 요청 로그에 시각을 붙이고, 포트를 3002로 고정합니다.
* [18:17:05.123] GET /play 200 in 21ms
*
* npm run dev
* npm run start
*/
import { spawn } from "node:child_process";
import { createRequire } from "node:module";
const FIXED_PORT = "3002";
const require = createRequire(import.meta.url);
const nextBin = require.resolve("next/dist/bin/next");
const rawArgs = process.argv.slice(2);
/** -p / --port 값을 제거하고 고정 포트를 붙입니다. (호스트는 Next 기본=전체 인터페이스) */
function withFixedListen(args) {
const out = [];
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (a === "-p" || a === "--port") {
i += 1;
continue;
}
if (a.startsWith("--port=") || a.startsWith("-p=")) {
continue;
}
out.push(a);
}
out.push("-p", FIXED_PORT);
return out;
}
const args = withFixedListen(rawArgs);
const env = {
...process.env,
PORT: FIXED_PORT,
};
process.stdout.write(`${(() => {
const now = new Date();
const hh = String(now.getHours()).padStart(2, "0");
const mm = String(now.getMinutes()).padStart(2, "0");
const ss = String(now.getSeconds()).padStart(2, "0");
const ms = String(now.getMilliseconds()).padStart(3, "0");
return `[${hh}:${mm}:${ss}.${ms}]`;
})()} omook-web listen { port: ${FIXED_PORT} }\n`);
const child = spawn(process.execPath, [nextBin, ...args], {
stdio: ["inherit", "pipe", "pipe"],
env,
});
const pending = new Map();
function ts() {
const now = new Date();
const hh = String(now.getHours()).padStart(2, "0");
const mm = String(now.getMinutes()).padStart(2, "0");
const ss = String(now.getSeconds()).padStart(2, "0");
const ms = String(now.getMilliseconds()).padStart(3, "0");
return `[${hh}:${mm}:${ss}.${ms}]`;
}
function onData(chunk, out) {
const text = (pending.get(out) ?? "") + chunk.toString("utf8");
const parts = text.split(/\r?\n/);
pending.set(out, parts.pop() ?? "");
for (const line of parts) {
out.write(`${ts()} ${line}\n`);
}
}
child.stdout.on("data", (c) => onData(c, process.stdout));
child.stderr.on("data", (c) => onData(c, process.stderr));
function flush() {
for (const [out, buf] of pending) {
if (buf) out.write(`${ts()} ${buf}\n`);
}
pending.clear();
}
child.on("exit", (code, signal) => {
flush();
if (signal) {
process.kill(process.pid, signal);
return;
}
process.exit(code ?? 1);
});
process.on("SIGINT", () => child.kill("SIGINT"));
process.on("SIGTERM", () => child.kill("SIGTERM"));