auto-select available port in dev mode
In dev mode (NODE_ENV !== 'production'), defaults getter automatically finds an available port if the requested one is taken.
This commit is contained in:
parent
861a024a1f
commit
82a13a3768
|
|
@ -161,14 +161,37 @@ export class Hype<
|
||||||
get defaults() {
|
get defaults() {
|
||||||
this.registerRoutes()
|
this.registerRoutes()
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV !== 'production'
|
||||||
|
let port = process.env.PORT ? Number(process.env.PORT) : 3000
|
||||||
|
|
||||||
|
if (isDev) {
|
||||||
|
port = findAvailablePortSync(port)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
port: process.env.PORT ?? '3000',
|
port,
|
||||||
fetch: this.fetch,
|
fetch: this.fetch,
|
||||||
idleTimeout: 255
|
idleTimeout: 255
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously find an available port starting from the given port
|
||||||
|
*/
|
||||||
|
function findAvailablePortSync(startPort: number, maxAttempts = 100): number {
|
||||||
|
for (let port = startPort; port < startPort + maxAttempts; port++) {
|
||||||
|
try {
|
||||||
|
const server = Bun.serve({ port, fetch: () => new Response() })
|
||||||
|
server.stop(true)
|
||||||
|
return port
|
||||||
|
} catch {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(`Could not find an available port after ${maxAttempts} attempts starting from ${startPort}`)
|
||||||
|
}
|
||||||
|
|
||||||
function render404(c: Context) {
|
function render404(c: Context) {
|
||||||
return c.text('File not found', 404)
|
return c.text('File not found', 404)
|
||||||
}
|
}
|
||||||
44
src/port-selection.test.ts
Normal file
44
src/port-selection.test.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { test, expect } from "bun:test"
|
||||||
|
import { Hype } from "./index.tsx"
|
||||||
|
|
||||||
|
test("defaults returns next available port in dev mode", () => {
|
||||||
|
// Start a server on port 4000 to block it
|
||||||
|
const blocker = Bun.serve({
|
||||||
|
port: 4000,
|
||||||
|
fetch: () => new Response("blocker"),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set NODE_ENV to development and PORT to 4000
|
||||||
|
const originalNodeEnv = process.env.NODE_ENV
|
||||||
|
const originalPort = process.env.PORT
|
||||||
|
process.env.NODE_ENV = "development"
|
||||||
|
process.env.PORT = "4000"
|
||||||
|
|
||||||
|
const app = new Hype({})
|
||||||
|
const config = app.defaults
|
||||||
|
|
||||||
|
// Should have found port 4001 since 4000 is taken
|
||||||
|
expect(config.port).toBe(4001)
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
blocker.stop(true)
|
||||||
|
process.env.NODE_ENV = originalNodeEnv
|
||||||
|
process.env.PORT = originalPort
|
||||||
|
})
|
||||||
|
|
||||||
|
test("defaults uses exact port in production mode", () => {
|
||||||
|
const originalNodeEnv = process.env.NODE_ENV
|
||||||
|
const originalPort = process.env.PORT
|
||||||
|
process.env.NODE_ENV = "production"
|
||||||
|
process.env.PORT = "4002"
|
||||||
|
|
||||||
|
const app = new Hype({})
|
||||||
|
const config = app.defaults
|
||||||
|
|
||||||
|
// Should use exact port in production
|
||||||
|
expect(config.port).toBe(4002)
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
process.env.NODE_ENV = originalNodeEnv
|
||||||
|
process.env.PORT = originalPort
|
||||||
|
})
|
||||||
Loading…
Reference in New Issue
Block a user