282 lines
8 KiB
JavaScript
282 lines
8 KiB
JavaScript
|
|
import { a as legacyRootDirArgs, i as extendsArgs, n as dotEnvArgs, o as logLevelArgs, r as envNameArgs, t as cwdArgs } from "./_shared-BCYCnX0T.mjs";
|
||
|
|
import { n as logger, t as debug } from "./logger-B4ge7MhP.mjs";
|
||
|
|
import "./env-DV8TWRZt.mjs";
|
||
|
|
import { t as initialize } from "./dev-BKPehGZf.mjs";
|
||
|
|
import "./kit-B3S8uoS_.mjs";
|
||
|
|
import "./versions-Bly87QYZ.mjs";
|
||
|
|
import "./banner-DMgRAl0q.mjs";
|
||
|
|
import "./fs-CQH7NJn6.mjs";
|
||
|
|
import "./nuxt-B1NSR4xh.mjs";
|
||
|
|
import process from "node:process";
|
||
|
|
import { defineCommand } from "citty";
|
||
|
|
import { isBun, isDeno, isTest } from "std-env";
|
||
|
|
import { colors } from "consola/utils";
|
||
|
|
import { resolve } from "pathe";
|
||
|
|
import { satisfies } from "semver";
|
||
|
|
import { getArgs, parseArgs } from "listhen/cli";
|
||
|
|
import { fork } from "node:child_process";
|
||
|
|
|
||
|
|
//#region ../nuxi/src/dev/pool.ts
|
||
|
|
var ForkPool = class {
|
||
|
|
pool = [];
|
||
|
|
poolSize;
|
||
|
|
rawArgs;
|
||
|
|
listenOverrides;
|
||
|
|
warming = false;
|
||
|
|
constructor(options) {
|
||
|
|
this.rawArgs = options.rawArgs;
|
||
|
|
this.poolSize = options.poolSize ?? 2;
|
||
|
|
this.listenOverrides = options.listenOverrides;
|
||
|
|
for (const signal of [
|
||
|
|
"exit",
|
||
|
|
"SIGTERM",
|
||
|
|
"SIGINT",
|
||
|
|
"SIGQUIT"
|
||
|
|
]) process.once(signal, () => {
|
||
|
|
this.killAll(signal === "exit" ? 0 : signal);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
startWarming() {
|
||
|
|
if (this.warming) return;
|
||
|
|
this.warming = true;
|
||
|
|
for (let i = 0; i < this.poolSize; i++) this.warmFork();
|
||
|
|
}
|
||
|
|
async getFork(context, onMessage) {
|
||
|
|
const readyFork = this.pool.find((f) => f.state === "ready");
|
||
|
|
if (readyFork) {
|
||
|
|
readyFork.state = "active";
|
||
|
|
if (onMessage) this.attachMessageHandler(readyFork.process, onMessage);
|
||
|
|
await this.sendContext(readyFork.process, context);
|
||
|
|
if (this.warming) this.warmFork();
|
||
|
|
return () => this.killFork(readyFork);
|
||
|
|
}
|
||
|
|
const warmingFork = this.pool.find((f) => f.state === "warming");
|
||
|
|
if (warmingFork) {
|
||
|
|
await warmingFork.ready;
|
||
|
|
warmingFork.state = "active";
|
||
|
|
if (onMessage) this.attachMessageHandler(warmingFork.process, onMessage);
|
||
|
|
await this.sendContext(warmingFork.process, context);
|
||
|
|
if (this.warming) this.warmFork();
|
||
|
|
return () => this.killFork(warmingFork);
|
||
|
|
}
|
||
|
|
debug("No pre-warmed forks available, starting cold fork");
|
||
|
|
const coldFork = this.createFork();
|
||
|
|
await coldFork.ready;
|
||
|
|
coldFork.state = "active";
|
||
|
|
if (onMessage) this.attachMessageHandler(coldFork.process, onMessage);
|
||
|
|
await this.sendContext(coldFork.process, context);
|
||
|
|
return () => this.killFork(coldFork);
|
||
|
|
}
|
||
|
|
attachMessageHandler(childProc, onMessage) {
|
||
|
|
childProc.on("message", (message) => {
|
||
|
|
if (message.type !== "nuxt:internal:dev:fork-ready") onMessage(message);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
warmFork() {
|
||
|
|
const fork$1 = this.createFork();
|
||
|
|
fork$1.ready.then(() => {
|
||
|
|
if (fork$1.state === "warming") fork$1.state = "ready";
|
||
|
|
}).catch(() => {
|
||
|
|
this.removeFork(fork$1);
|
||
|
|
});
|
||
|
|
this.pool.push(fork$1);
|
||
|
|
}
|
||
|
|
createFork() {
|
||
|
|
const childProc = fork(globalThis.__nuxt_cli__.devEntry, this.rawArgs, {
|
||
|
|
execArgv: ["--enable-source-maps", process.argv.find((a) => a.includes("--inspect"))].filter(Boolean),
|
||
|
|
env: {
|
||
|
|
...process.env,
|
||
|
|
__NUXT__FORK: "true"
|
||
|
|
}
|
||
|
|
});
|
||
|
|
let readyResolve;
|
||
|
|
let readyReject;
|
||
|
|
const pooledFork = {
|
||
|
|
process: childProc,
|
||
|
|
ready: new Promise((resolve$1, reject) => {
|
||
|
|
readyResolve = resolve$1;
|
||
|
|
readyReject = reject;
|
||
|
|
}),
|
||
|
|
state: "warming"
|
||
|
|
};
|
||
|
|
childProc.on("message", (message) => {
|
||
|
|
if (message.type === "nuxt:internal:dev:fork-ready") readyResolve();
|
||
|
|
});
|
||
|
|
childProc.on("error", (err) => {
|
||
|
|
readyReject(err);
|
||
|
|
this.removeFork(pooledFork);
|
||
|
|
});
|
||
|
|
childProc.on("close", (errorCode) => {
|
||
|
|
if (pooledFork.state === "active" && errorCode) process.exit(errorCode);
|
||
|
|
this.removeFork(pooledFork);
|
||
|
|
});
|
||
|
|
return pooledFork;
|
||
|
|
}
|
||
|
|
async sendContext(childProc, context) {
|
||
|
|
childProc.send({
|
||
|
|
type: "nuxt:internal:dev:context",
|
||
|
|
listenOverrides: this.listenOverrides,
|
||
|
|
context
|
||
|
|
});
|
||
|
|
}
|
||
|
|
killFork(fork$1, signal = "SIGTERM") {
|
||
|
|
fork$1.state = "dead";
|
||
|
|
if (fork$1.process) fork$1.process.kill(signal === 0 && isDeno ? "SIGTERM" : signal);
|
||
|
|
this.removeFork(fork$1);
|
||
|
|
}
|
||
|
|
removeFork(fork$1) {
|
||
|
|
const index = this.pool.indexOf(fork$1);
|
||
|
|
if (index > -1) this.pool.splice(index, 1);
|
||
|
|
}
|
||
|
|
killAll(signal) {
|
||
|
|
for (const fork$1 of this.pool) this.killFork(fork$1, signal);
|
||
|
|
}
|
||
|
|
getStats() {
|
||
|
|
return {
|
||
|
|
total: this.pool.length,
|
||
|
|
warming: this.pool.filter((f) => f.state === "warming").length,
|
||
|
|
ready: this.pool.filter((f) => f.state === "ready").length,
|
||
|
|
active: this.pool.filter((f) => f.state === "active").length
|
||
|
|
};
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
//#region ../nuxi/src/commands/dev.ts
|
||
|
|
const startTime = Date.now();
|
||
|
|
const forkSupported = !isTest && (!isBun || isBunForkSupported());
|
||
|
|
const listhenArgs = getArgs();
|
||
|
|
const command = defineCommand({
|
||
|
|
meta: {
|
||
|
|
name: "dev",
|
||
|
|
description: "Run Nuxt development server"
|
||
|
|
},
|
||
|
|
args: {
|
||
|
|
...cwdArgs,
|
||
|
|
...logLevelArgs,
|
||
|
|
...dotEnvArgs,
|
||
|
|
...legacyRootDirArgs,
|
||
|
|
...envNameArgs,
|
||
|
|
...extendsArgs,
|
||
|
|
clear: {
|
||
|
|
type: "boolean",
|
||
|
|
description: "Clear console on restart",
|
||
|
|
default: false
|
||
|
|
},
|
||
|
|
fork: {
|
||
|
|
type: "boolean",
|
||
|
|
description: forkSupported ? "Disable forked mode" : "Enable forked mode",
|
||
|
|
negativeDescription: "Disable forked mode",
|
||
|
|
default: forkSupported,
|
||
|
|
alias: ["f"]
|
||
|
|
},
|
||
|
|
...listhenArgs,
|
||
|
|
port: {
|
||
|
|
...listhenArgs.port,
|
||
|
|
description: "Port to listen on (default: `NUXT_PORT || NITRO_PORT || PORT || nuxtOptions.devServer.port`)",
|
||
|
|
alias: ["p"]
|
||
|
|
},
|
||
|
|
open: {
|
||
|
|
...listhenArgs.open,
|
||
|
|
alias: ["o"],
|
||
|
|
default: false
|
||
|
|
},
|
||
|
|
host: {
|
||
|
|
...listhenArgs.host,
|
||
|
|
alias: ["h"],
|
||
|
|
description: "Host to listen on (default: `NUXT_HOST || NITRO_HOST || HOST || nuxtOptions.devServer?.host`)"
|
||
|
|
},
|
||
|
|
clipboard: {
|
||
|
|
...listhenArgs.clipboard,
|
||
|
|
default: false
|
||
|
|
},
|
||
|
|
sslCert: {
|
||
|
|
type: "string",
|
||
|
|
description: "(DEPRECATED) Use `--https.cert` instead."
|
||
|
|
},
|
||
|
|
sslKey: {
|
||
|
|
type: "string",
|
||
|
|
description: "(DEPRECATED) Use `--https.key` instead."
|
||
|
|
}
|
||
|
|
},
|
||
|
|
async run(ctx) {
|
||
|
|
const cwd = resolve(ctx.args.cwd || ctx.args.rootDir);
|
||
|
|
const listenOverrides = resolveListenOverrides(ctx.args);
|
||
|
|
const { listener, close, onRestart, onReady } = await initialize({
|
||
|
|
cwd,
|
||
|
|
args: ctx.args
|
||
|
|
}, {
|
||
|
|
data: ctx.data,
|
||
|
|
listenOverrides,
|
||
|
|
showBanner: true
|
||
|
|
});
|
||
|
|
if (!ctx.args.fork) return {
|
||
|
|
listener,
|
||
|
|
close
|
||
|
|
};
|
||
|
|
const pool = new ForkPool({
|
||
|
|
rawArgs: ctx.rawArgs,
|
||
|
|
poolSize: 2,
|
||
|
|
listenOverrides
|
||
|
|
});
|
||
|
|
onReady((_address) => {
|
||
|
|
pool.startWarming();
|
||
|
|
if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`);
|
||
|
|
});
|
||
|
|
let cleanupCurrentFork;
|
||
|
|
async function restartWithFork() {
|
||
|
|
const context = {
|
||
|
|
cwd,
|
||
|
|
args: ctx.args
|
||
|
|
};
|
||
|
|
cleanupCurrentFork?.();
|
||
|
|
cleanupCurrentFork = await pool.getFork(context, (message) => {
|
||
|
|
if (message.type === "nuxt:internal:dev:ready") {
|
||
|
|
if (startTime) debug(`Dev server ready for connections in ${Date.now() - startTime}ms`);
|
||
|
|
} else if (message.type === "nuxt:internal:dev:restart") restartWithFork();
|
||
|
|
else if (message.type === "nuxt:internal:dev:rejection") {
|
||
|
|
logger.info(`Restarting Nuxt due to error: ${colors.cyan(message.message)}`);
|
||
|
|
restartWithFork();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
onRestart(async () => {
|
||
|
|
await close();
|
||
|
|
await restartWithFork();
|
||
|
|
});
|
||
|
|
return { async close() {
|
||
|
|
cleanupCurrentFork?.();
|
||
|
|
await Promise.all([listener.close(), close()]);
|
||
|
|
} };
|
||
|
|
}
|
||
|
|
});
|
||
|
|
var dev_default = command;
|
||
|
|
function resolveListenOverrides(args) {
|
||
|
|
if (process.env._PORT) return {
|
||
|
|
port: process.env._PORT || 0,
|
||
|
|
hostname: "127.0.0.1",
|
||
|
|
showURL: false
|
||
|
|
};
|
||
|
|
const options = parseArgs({
|
||
|
|
...args,
|
||
|
|
"host": args.host || process.env.NUXT_HOST || process.env.NITRO_HOST || process.env.HOST,
|
||
|
|
"port": args.port || process.env.NUXT_PORT || process.env.NITRO_PORT || process.env.PORT,
|
||
|
|
"https": args.https !== false,
|
||
|
|
"https.cert": args["https.cert"] || args.sslCert || process.env.NUXT_SSL_CERT || process.env.NITRO_SSL_CERT,
|
||
|
|
"https.key": args["https.key"] || args.sslKey || process.env.NUXT_SSL_KEY || process.env.NITRO_SSL_KEY
|
||
|
|
});
|
||
|
|
return {
|
||
|
|
...options,
|
||
|
|
_https: args.https,
|
||
|
|
get https() {
|
||
|
|
return this._https ? options.https : false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function isBunForkSupported() {
|
||
|
|
const bunVersion = globalThis.Bun.version;
|
||
|
|
return satisfies(bunVersion, ">=1.2");
|
||
|
|
}
|
||
|
|
|
||
|
|
//#endregion
|
||
|
|
export { dev_default as default };
|