diff --git a/src/build.ts b/src/build.ts index 421808d95c..fb8f1dc9cf 100644 --- a/src/build.ts +++ b/src/build.ts @@ -17,6 +17,7 @@ import { parseNodeModulePath, resolvePath, } from "mlly"; +import { version as nitroVersion } from "../package.json"; import { generateFSTree } from "./utils/tree"; import { getRollupConfig, RollupConfig } from "./rollup/config"; import { @@ -26,7 +27,7 @@ import { resolvePath as resolveNitroPath, } from "./utils"; import { GLOB_SCAN_PATTERN, scanHandlers } from "./scan"; -import type { Nitro } from "./types"; +import type { Nitro, NitroBuildInfo } from "./types"; import { runtimeDir } from "./dirs"; import { snapshotStorage } from "./storage"; import { compressPublicAssets } from "./compress"; @@ -405,17 +406,21 @@ async function _build(nitro: Nitro, rollupConfig: RollupConfig) { await build.write(rollupConfig.output); } - // Write build info - const nitroConfigPath = resolve(nitro.options.output.dir, "nitro.json"); - const buildInfo = { - date: new Date(), + // Write .output/nitro.json + const buildInfoPath = resolve(nitro.options.output.dir, "nitro.json"); + const buildInfo: NitroBuildInfo = { + date: new Date().toJSON(), preset: nitro.options.preset, + framework: nitro.options.framework, + versions: { + nitro: nitroVersion, + }, commands: { preview: nitro.options.commands.preview, deploy: nitro.options.commands.deploy, }, }; - await writeFile(nitroConfigPath, JSON.stringify(buildInfo, null, 2)); + await writeFile(buildInfoPath, JSON.stringify(buildInfo, null, 2)); if (!nitro.options.static) { nitro.logger.success("Nitro server built"); diff --git a/src/dev/server.ts b/src/dev/server.ts index 5755c1e128..3c2fc9d64e 100644 --- a/src/dev/server.ts +++ b/src/dev/server.ts @@ -1,5 +1,6 @@ import { Worker } from "node:worker_threads"; import { existsSync, accessSync, promises as fsp } from "node:fs"; +import { writeFile } from "node:fs/promises"; import { debounce } from "perfect-debounce"; import { App, @@ -17,13 +18,14 @@ import serveStatic from "serve-static"; import { resolve } from "pathe"; import { joinURL } from "ufo"; import { FSWatcher, watch } from "chokidar"; -import type { Nitro } from "../types"; +import type { Nitro, NitroBuildInfo } from "../types"; +import { version as nitroVersion } from "../../package.json"; import { createVFSHandler } from "./vfs"; import defaultErrorHandler from "./error"; export interface NitroWorker { worker: Worker; - address: { host: string; port: number; socketPath?: string }; + address: { host: string; port: number } | { socketPath: string }; } export interface NitroDevServer { @@ -95,7 +97,7 @@ async function killWorker(worker: NitroWorker, nitro: Nitro) { await worker.worker.terminate(); worker.worker = null; } - if (worker.address.socketPath && existsSync(worker.address.socketPath)) { + if ("socketPath" in worker.address && existsSync(worker.address.socketPath)) { await fsp.rm(worker.address.socketPath).catch(() => {}); } } @@ -122,6 +124,21 @@ export function createDevServer(nitro: Nitro): NitroDevServer { await killWorker(oldWorker, nitro); // Create a new worker currentWorker = await initWorker(workerEntry); + // Write nitro.json + const buildInfoPath = resolve(nitro.options.buildDir, "nitro.json"); + const buildInfo: NitroBuildInfo = { + date: new Date().toJSON(), + preset: nitro.options.preset, + framework: nitro.options.framework, + versions: { + nitro: nitroVersion, + }, + dev: { + pid: process.pid, + workerAddress: currentWorker.address, + }, + }; + await writeFile(buildInfoPath, JSON.stringify(buildInfo, null, 2)); } const reload = debounce(() => { reloadPromise = _reload() @@ -193,7 +210,7 @@ export function createDevServer(nitro: Nitro): NitroDevServer { if (!address) { return; } - if (address.socketPath) { + if ("socketPath" in address) { try { accessSync(address.socketPath); } catch (err) { @@ -213,7 +230,7 @@ export function createDevServer(nitro: Nitro): NitroDevServer { if (!address) { return errorHandler(lastError, event); } - await proxy.handle(event, { target: address }).catch((err) => { + await proxy.handle(event, { target: address as any }).catch((err) => { lastError = err; throw err; }); diff --git a/src/types/nitro.ts b/src/types/nitro.ts index af12366316..5f15ea261a 100644 --- a/src/types/nitro.ts +++ b/src/types/nitro.ts @@ -197,6 +197,31 @@ export interface WasmOptions { rollup?: RollupWasmOptions; } +export interface NitroFrameworkInfo { + // eslint-disable-next-line @typescript-eslint/ban-types + name?: "nitro" | (string & {}); + version?: string; +} + +/** Build info written to `.output/nitro.json` or `.nitro/dev/nitro.json` */ +export interface NitroBuildInfo { + date: string; + preset: string; + framework: NitroFrameworkInfo; + versions: { + nitro: string; + [key: string]: string; + }; + commands?: { + preview?: string; + deploy?: string; + }; + dev?: { + pid: number; + workerAddress: { host: string; port: number } | { socketPath: string }; + }; +} + export interface NitroOptions extends PresetOptions { // Internal _config: NitroConfig; @@ -353,11 +378,7 @@ export interface NitroOptions extends PresetOptions { }; // Framework - framework: { - // eslint-disable-next-line @typescript-eslint/ban-types - name?: "nitro" | (string & {}); - version?: string; - }; + framework: NitroFrameworkInfo; // IIS iis?: {