From 0d147b275cd8fc56dca1e480b148361d0c381e06 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Tue, 29 Sep 2026 13:15:59 +0000 Subject: [PATCH] bun run dev keeps Vite's address in view: the backend's full log goes to a file PocketBase prints about 230 lines of startup SQL, and the dev plugin forwarded every line to the terminal, so Vite's "Local:" address scrolled out of view right after it appeared. The fourth fresh reader of the README saw it happen. Each dev backend's output now goes whole to .pb/logs/.log (gitignored), and the terminal gets only the lines a person must act on: errors, warnings, panics, and "address already in use", the line the README and HOWTO tell a reader to watch for before setting DX_PB_PORT. The started line names the log file. Tested against representative lines (in use, WARN, panic shown; SQL and the banner quiet). The live check rides the next fresh-reader run. --- internal/backend-dev-plugin.mjs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/internal/backend-dev-plugin.mjs b/internal/backend-dev-plugin.mjs index 556506144..9b4ad6899 100644 --- a/internal/backend-dev-plugin.mjs +++ b/internal/backend-dev-plugin.mjs @@ -18,7 +18,7 @@ * DEV ONLY (`apply: 'serve'`). A production build never starts or bundles a backend. */ import { spawn } from 'node:child_process' -import { existsSync, mkdirSync, writeFileSync, rmSync, chmodSync, renameSync } from 'node:fs' +import { existsSync, mkdirSync, writeFileSync, rmSync, chmodSync, renameSync, createWriteStream } from 'node:fs' import { createHash } from 'node:crypto' import { connect } from 'node:net' import { inflateRawSync } from 'node:zlib' @@ -153,9 +153,22 @@ function start(root, b, logger, restarts = 0) { const child = spawn(resolve(root, b.bin), b.args || [], { cwd: root, env: { ...process.env, ...b.env }, stdio: ['ignore', 'pipe', 'pipe'] }) const entry = { child, restarts, logger } REG.procs.set(b.name, entry) - const out = (d) => String(d).trim().split('\n').forEach((l) => l && entry.logger.info(`${tag} ${l}`)) + // ★ THE FULL LOG GOES TO A FILE; THE TERMINAL GETS WHAT A PERSON MUST ACT ON. PocketBase prints about + // 230 lines of startup SQL, which scrolled Vite's "➜ Local:" address out of view for a fresh reader of the + // README. Every line still lands in .pb/logs/.log (gitignored). Errors, warnings and "address already + // in use" (the line the README and HOWTO tell a reader to watch for before setting DX_PB_PORT) are + // forwarded exactly as before. + const logDir = resolve(root, '.pb', 'logs') + mkdirSync(logDir, { recursive: true }) + const sink = createWriteStream(resolve(logDir, `${b.name}.log`), { flags: 'a' }) + const LOUD = /\b(error|fail(ed|ure)?|panic|fatal|warn(ing)?|refused|denied|in use|cannot|unable)\b/i + const out = (d) => { + sink.write(d) + String(d).trim().split('\n').forEach((l) => l && LOUD.test(l) && entry.logger.info(`${tag} ${l}`)) + } child.stdout.on('data', out) child.stderr.on('data', out) + child.on('exit', () => sink.end()) child.on('exit', (code) => { if (REG.procs.get(b.name) !== entry) return REG.procs.delete(b.name) @@ -170,7 +183,7 @@ function start(root, b, logger, restarts = 0) { }, 2000) } }) - logger.info(`${tag} started → ${b.route} on 127.0.0.1:${b.port}`) + logger.info(`${tag} started → ${b.route} on 127.0.0.1:${b.port} (full log: .pb/logs/${b.name}.log)`) } export function backendDevPlugin(root, env = process.env) {