| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import { execFileSync } from "node:child_process";
- import { existsSync, readFileSync, rmSync } from "node:fs";
- import { resolve } from "node:path";
- const lockPath = ".next/dev/lock";
- const devDirPath = ".next/dev";
- const webpackRuntimePath = ".next/dev/server/webpack-runtime.js";
- const vendorChunkPath = ".next/dev/server/vendor-chunks/next.js";
- const projectRoot = process.cwd();
- function run(cmd, args) {
- try {
- return execFileSync(cmd, args, { encoding: "utf8" }).trim();
- } catch {
- return "";
- }
- }
- function pidExists(pid) {
- try {
- process.kill(pid, 0);
- return true;
- } catch {
- return false;
- }
- }
- function getProcessCwd(pid) {
- const output = run("lsof", ["-a", "-p", String(pid), "-d", "cwd", "-Fn"]);
- const cwdLine = output
- .split("\n")
- .find((line) => line.startsWith("n"));
- return cwdLine ? cwdLine.slice(1) : "";
- }
- function getListeningPids(port) {
- const output = run("lsof", ["-ti", `tcp:${port}`, "-sTCP:LISTEN"]);
- if (!output) return [];
- return output
- .split("\n")
- .map((line) => Number(line.trim()))
- .filter((v) => Number.isInteger(v) && v > 0);
- }
- function removeLock(reason) {
- rmSync(lockPath, { force: true });
- console.log(`Removed stale ${lockPath}: ${reason}`);
- }
- function resetDevCache(reason) {
- rmSync(devDirPath, { force: true, recursive: true });
- console.log(`Reset ${devDirPath}: ${reason}`);
- }
- if (existsSync(webpackRuntimePath) && !existsSync(vendorChunkPath)) {
- resetDevCache("missing vendor-chunks/next.js");
- process.exit(0);
- }
- if (!existsSync(lockPath)) process.exit(0);
- let lock;
- try {
- lock = JSON.parse(readFileSync(lockPath, "utf8"));
- } catch {
- removeLock("invalid JSON");
- process.exit(0);
- }
- const pid = Number(lock?.pid ?? 0);
- const port = Number(lock?.port ?? 3000);
- if (!pid) {
- removeLock("missing pid");
- process.exit(0);
- }
- if (!pidExists(pid)) {
- removeLock(`pid ${pid} not running`);
- process.exit(0);
- }
- const processCwd = getProcessCwd(pid);
- if (!processCwd) {
- removeLock(`cannot resolve cwd for pid ${pid}`);
- process.exit(0);
- }
- if (resolve(processCwd) !== resolve(projectRoot)) {
- removeLock(`pid ${pid} belongs to another directory`);
- process.exit(0);
- }
- const portPids = getListeningPids(port);
- if (portPids.length > 0 && !portPids.includes(pid)) {
- removeLock(`pid ${pid} is not listening on port ${port}`);
- }
|