Skip to content

start: busy port should shift to the next free one (Vite-style) and the printed URL should be openable #557

Description

@melvincarvalho

Port-back from jspod (lib/start.js), where both behaviours are implemented and proven.

Problem

  1. jss start on a busy port dies with a raw EADDRINUSE — a first-run papercut, especially when a stale instance is still running.
  2. The startup banner prints the bind host verbatim — http://0.0.0.0:4443 isn't an openable URL (and bare IPv6 hosts need brackets).

Fix (proven downstream in jspod)

  1. findFreePort — when the requested port is busy, probe upward one port at a time (cap ~10 tries, Vite's behaviour), print what happened, and bind there. Explicitly-passed --port could either still shift with a notice, or fail hard with a clear message (jspod shifts; either is fine if loud).
async function findFreePort(startPort, host, maxTries = 10) {
  for (let p = startPort; p < startPort + maxTries; p++) {
    const free = await new Promise((resolve) => {
      const srv = createServer();
      srv.once('error', () => resolve(false));
      srv.once('listening', () => srv.close(() => resolve(true)));
      srv.listen(p, host);
    });
    if (free) return p;
  }
  return null;
}
  1. formatUrl — for the banner only: 0.0.0.0/::/*localhost, bracket IPv6 literals.

Scope

bin/jss.js start action (+ the banner print). ~30 LoC + tests. No behaviour change when the requested port is free.

Refs

  • jspod lib/start.jsfindFreePort + formatUrl, in production downstream

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions