defuss-ssg 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { v as validateProjectDir, b as build } from './vite-DdJcWQGP.mjs';
3
- import { d as dev, s as serve } from './serve-CTYzPwKQ.mjs';
4
- import { join, dirname, resolve } from 'node:path';
5
- import { existsSync, readFileSync } from 'node:fs';
6
- import { spawn } from 'node:child_process';
2
+ import { r as readConfig, v as validateProjectDir, b as build } from './vite-CSOGjlHB.mjs';
3
+ import { spawnSync, spawn } from 'node:child_process';
4
+ import { createHash } from 'node:crypto';
5
+ import { mkdtempSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import { resolve, join, basename, dirname } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { d as dev, s as serve } from './serve-BFMU8uCH.mjs';
7
10
  import 'fast-glob';
8
11
  import 'node:fs/promises';
9
12
  import 'defuss/server';
10
- import 'node:crypto';
11
13
  import '@mdx-js/rollup';
12
14
  import 'vite';
13
15
  import 'defuss-vite';
14
16
  import 'node:module';
15
- import 'node:url';
16
- import 'node:os';
17
- import 'esbuild';
17
+ import 'rolldown';
18
18
  import 'rehype-katex';
19
19
  import 'rehype-stringify';
20
20
  import 'remark-frontmatter';
@@ -23,8 +23,243 @@ import 'remark-gfm';
23
23
  import 'remark-parse';
24
24
  import 'remark-rehype';
25
25
  import 'remark-mdx-frontmatter';
26
+ import './path-CjHWUK8o.mjs';
27
+ import 'node:process';
26
28
  import 'defuss-express';
27
29
 
30
+ const CONTAINER_IMAGE_TAG = "defuss-ssg";
31
+ const CONTAINER_WORKSPACE_DIR = "/workspace";
32
+ const CONTAINER_NODE_MODULES_DIR = `${CONTAINER_WORKSPACE_DIR}/node_modules`;
33
+ const DEFAULT_CONTAINER_PORT = 3e3;
34
+ const GENERATED_DOCKERFILE_NAME = "Dockerfile";
35
+ const createDockerfile = (packageTarballName) => `# syntax=docker/dockerfile:1.7
36
+
37
+ FROM oven/bun:1.3.9 AS bun
38
+
39
+ FROM node:24-trixie-slim
40
+
41
+ WORKDIR /app
42
+
43
+ ENV NODE_ENV=production
44
+
45
+ RUN apt-get update \\
46
+ && apt-get install -y --no-install-recommends ca-certificates git \\
47
+ && git config --global --add url."https://github.com/".insteadOf ssh://git@github.com/ \\
48
+ && git config --global --add url."https://github.com/".insteadOf git+ssh://git@github.com/ \\
49
+ && git config --global --add url."https://github.com/".insteadOf git@github.com: \\
50
+ && rm -rf /var/lib/apt/lists/*
51
+
52
+ COPY ${packageTarballName} /tmp/${packageTarballName}
53
+ COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun
54
+ RUN ln -sf /usr/local/bin/bun /usr/local/bin/bunx \\
55
+ && npm install -g /tmp/${packageTarballName} \\
56
+ && rm -f /tmp/${packageTarballName} \\
57
+ && npm cache clean --force
58
+
59
+ ENTRYPOINT ["defuss-ssg"]
60
+ CMD ["dev", "/workspace", "--host", "0.0.0.0", "--port", "3000"]
61
+ `;
62
+ const getPackageRootDir = () => fileURLToPath(new URL("../", import.meta.url));
63
+ const packCurrentPackage = (tempDir) => {
64
+ const packageRootDir = getPackageRootDir();
65
+ const result = spawnSync(
66
+ "npm",
67
+ ["pack", "--json", "--pack-destination", tempDir],
68
+ {
69
+ cwd: packageRootDir,
70
+ encoding: "utf8",
71
+ shell: process.platform === "win32"
72
+ }
73
+ );
74
+ if (result.error) {
75
+ throw result.error;
76
+ }
77
+ if (result.status !== 0) {
78
+ throw new Error(
79
+ result.stderr || "Failed to pack the current defuss-ssg package."
80
+ );
81
+ }
82
+ const output = JSON.parse(result.stdout);
83
+ const tarballName = output.at(0)?.filename;
84
+ if (!tarballName) {
85
+ throw new Error("npm pack did not return a package tarball name.");
86
+ }
87
+ return tarballName;
88
+ };
89
+ const getNodeModulesVolumeName = (projectDir) => {
90
+ const safeBaseName = basename(projectDir).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "project";
91
+ const hash = createHash("sha256").update(projectDir).digest("hex").slice(0, 12);
92
+ return `defuss-ssg-node-modules-${safeBaseName}-${hash}`;
93
+ };
94
+ const hasCommand = (command) => {
95
+ const result = spawnSync(command, ["--version"], {
96
+ stdio: "ignore",
97
+ shell: process.platform === "win32"
98
+ });
99
+ return !result.error && result.status === 0;
100
+ };
101
+ const resolveContainerRuntime = async (projectDir, debug) => {
102
+ const configuredRuntime = (await readConfig(projectDir, debug)).containerRuntime;
103
+ if (configuredRuntime) {
104
+ if (!hasCommand(configuredRuntime)) {
105
+ throw new Error(
106
+ `Configured containerRuntime "${configuredRuntime}" is not available on PATH.`
107
+ );
108
+ }
109
+ return configuredRuntime;
110
+ }
111
+ if (hasCommand("docker")) {
112
+ return "docker";
113
+ }
114
+ if (hasCommand("podman")) {
115
+ return "podman";
116
+ }
117
+ throw new Error(
118
+ "Neither docker nor podman is available on PATH. Install one of them or set containerRuntime in config.ts."
119
+ );
120
+ };
121
+ const runContainerRuntime = (runtime, args, label, cwd) => {
122
+ const result = spawnSync(runtime, args, {
123
+ cwd,
124
+ stdio: "inherit",
125
+ shell: process.platform === "win32"
126
+ });
127
+ if (result.error) {
128
+ throw result.error;
129
+ }
130
+ if (result.status !== 0) {
131
+ throw new Error(
132
+ `${runtime} ${args.join(" ")} failed while ${label} with code ${result.status ?? "unknown"}`
133
+ );
134
+ }
135
+ };
136
+ const hasPublishArgs = (dockerArgs) => {
137
+ for (let index = 0; index < dockerArgs.length; index += 1) {
138
+ const arg = dockerArgs[index];
139
+ if (arg === "-p" || arg === "-P" || arg === "--publish" || arg === "--publish-all" || arg.startsWith("--publish=")) {
140
+ return true;
141
+ }
142
+ }
143
+ return false;
144
+ };
145
+ const extractHostNetworkArgs = (dockerArgs) => {
146
+ const remainingArgs = [];
147
+ let hostNetworkRequested = false;
148
+ for (let index = 0; index < dockerArgs.length; index += 1) {
149
+ const arg = dockerArgs[index];
150
+ if (arg === "--net=host" || arg === "--network=host") {
151
+ hostNetworkRequested = true;
152
+ continue;
153
+ }
154
+ if ((arg === "--net" || arg === "--network") && dockerArgs[index + 1] === "host") {
155
+ hostNetworkRequested = true;
156
+ index += 1;
157
+ continue;
158
+ }
159
+ remainingArgs.push(arg);
160
+ }
161
+ return {
162
+ remainingArgs,
163
+ hostNetworkRequested
164
+ };
165
+ };
166
+ const getInnerCommand = (command) => command.slice("docker-".length);
167
+ const createInnerArgs = ({
168
+ command,
169
+ debug,
170
+ host,
171
+ port,
172
+ multicore,
173
+ skipSetup
174
+ }) => {
175
+ const innerCommand = getInnerCommand(command);
176
+ const innerArgs = [innerCommand, CONTAINER_WORKSPACE_DIR];
177
+ if (debug) {
178
+ innerArgs.push("--debug");
179
+ }
180
+ if (innerCommand === "serve" && multicore) {
181
+ innerArgs.push("--multicore");
182
+ }
183
+ if (skipSetup) {
184
+ innerArgs.push("--skip-setup");
185
+ }
186
+ if (innerCommand === "dev" || innerCommand === "serve") {
187
+ const selectedHost = host ?? "0.0.0.0";
188
+ const selectedPort = port ?? DEFAULT_CONTAINER_PORT;
189
+ innerArgs.push("--host", selectedHost, "--port", String(selectedPort));
190
+ return { innerArgs, selectedPort };
191
+ }
192
+ return {
193
+ innerArgs,
194
+ selectedPort: port
195
+ };
196
+ };
197
+ const runContainerCommand = async ({
198
+ command,
199
+ projectDir,
200
+ debug = false,
201
+ host,
202
+ port,
203
+ multicore = false,
204
+ skipSetup = false,
205
+ dockerArgs
206
+ }) => {
207
+ const resolvedProjectDir = resolve(projectDir);
208
+ const runtime = await resolveContainerRuntime(resolvedProjectDir, debug);
209
+ const { remainingArgs, hostNetworkRequested } = extractHostNetworkArgs(dockerArgs);
210
+ const useHostNetwork = hostNetworkRequested && process.platform === "linux";
211
+ const tempDir = mkdtempSync(join(tmpdir(), "defuss-ssg-container-"));
212
+ const volumeName = getNodeModulesVolumeName(resolvedProjectDir);
213
+ const dockerfilePath = join(tempDir, GENERATED_DOCKERFILE_NAME);
214
+ const { innerArgs, selectedPort } = createInnerArgs({
215
+ command,
216
+ debug,
217
+ host,
218
+ port,
219
+ multicore,
220
+ skipSetup
221
+ });
222
+ const packageTarballName = packCurrentPackage(tempDir);
223
+ writeFileSync(dockerfilePath, createDockerfile(packageTarballName), "utf8");
224
+ try {
225
+ console.log(`Using ${runtime} for containerized ${getInnerCommand(command)}.`);
226
+ if (hostNetworkRequested && !useHostNetwork) {
227
+ console.warn(
228
+ `Ignoring --network host on ${process.platform}; using published ports for localhost access instead.`
229
+ );
230
+ }
231
+ runContainerRuntime(
232
+ runtime,
233
+ ["build", "-t", CONTAINER_IMAGE_TAG, "-f", GENERATED_DOCKERFILE_NAME, tempDir],
234
+ "building the defuss-ssg container image",
235
+ tempDir
236
+ );
237
+ const runArgs = [
238
+ "run",
239
+ "--rm",
240
+ ...remainingArgs,
241
+ "-v",
242
+ `${resolvedProjectDir}:${CONTAINER_WORKSPACE_DIR}`,
243
+ "-v",
244
+ `${volumeName}:${CONTAINER_NODE_MODULES_DIR}`
245
+ ];
246
+ if (useHostNetwork) {
247
+ runArgs.push("--network", "host");
248
+ }
249
+ if ((selectedPort ?? 0) > 0 && (getInnerCommand(command) === "dev" || getInnerCommand(command) === "serve") && !hasPublishArgs(remainingArgs) && !useHostNetwork) {
250
+ runArgs.push("-p", `${selectedPort}:${selectedPort}`);
251
+ }
252
+ runArgs.push(CONTAINER_IMAGE_TAG, ...innerArgs);
253
+ runContainerRuntime(
254
+ runtime,
255
+ runArgs,
256
+ `running ${command} for ${resolvedProjectDir}`
257
+ );
258
+ } finally {
259
+ rmSync(tempDir, { recursive: true, force: true });
260
+ }
261
+ };
262
+
28
263
  const canResolve = (dep, dir) => {
29
264
  let current = dir;
30
265
  while (true) {
@@ -38,7 +273,7 @@ const canResolve = (dep, dir) => {
38
273
  const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
39
274
  const child = spawn(cmd, args, {
40
275
  cwd,
41
- shell: true,
276
+ shell: process.platform === "win32",
42
277
  stdio: ["inherit", "pipe", "pipe"],
43
278
  env: env ?? process.env
44
279
  });
@@ -48,11 +283,11 @@ const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
48
283
  lastLines.push(line);
49
284
  if (lastLines.length > 3) lastLines.shift();
50
285
  if (process.stdout.isTTY) {
51
- for (let i = 0; i < printedLines; i++) {
286
+ for (let index = 0; index < printedLines; index += 1) {
52
287
  process.stdout.write("\x1B[1A\x1B[2K");
53
288
  }
54
- for (const l of lastLines) {
55
- process.stdout.write(`${l}
289
+ for (const outputLine of lastLines) {
290
+ process.stdout.write(`${outputLine}
56
291
  `);
57
292
  }
58
293
  printedLines = lastLines.length;
@@ -62,22 +297,49 @@ const runInstall = (cmd, args, cwd, env) => new Promise((resolve, reject) => {
62
297
  }
63
298
  };
64
299
  const handleData = (chunk) => {
65
- const lines = chunk.toString().split(/\r\n|\n|\r/).filter((l) => l.trim().length > 0);
300
+ const lines = chunk.toString().split(/\r\n|\n|\r/).filter((line) => line.trim().length > 0);
66
301
  for (const line of lines) pushLine(line);
67
302
  };
68
303
  child.stdout?.on("data", handleData);
69
304
  child.stderr?.on("data", handleData);
70
305
  child.on("error", reject);
71
306
  child.on("close", (code) => {
72
- if (code === 0) resolve();
73
- else
74
- reject(
75
- new Error(
76
- `${cmd} ${args.join(" ")} exited with code ${code ?? "unknown"}`
77
- )
78
- );
307
+ if (code === 0) {
308
+ resolve();
309
+ return;
310
+ }
311
+ reject(
312
+ new Error(
313
+ `${cmd} ${args.join(" ")} exited with code ${code ?? "unknown"}`
314
+ )
315
+ );
79
316
  });
80
317
  });
318
+ const getInstallCommand = (pm, projectDir) => {
319
+ if (pm === "bun") {
320
+ return {
321
+ cmd: "bun",
322
+ args: ["install", "--no-cache"],
323
+ env: { ...process.env, BUN_WORKSPACE_ROOT: projectDir }
324
+ };
325
+ }
326
+ if (pm === "yarn") {
327
+ return {
328
+ cmd: "corepack",
329
+ args: ["yarn", "install"]
330
+ };
331
+ }
332
+ if (pm === "pnpm") {
333
+ return {
334
+ cmd: "corepack",
335
+ args: ["pnpm", "install"]
336
+ };
337
+ }
338
+ return {
339
+ cmd: "npm",
340
+ args: ["install"]
341
+ };
342
+ };
81
343
  const setup = async (projectDir) => {
82
344
  const projectDirStatus = validateProjectDir(projectDir);
83
345
  if (projectDirStatus.code !== "OK") return projectDirStatus;
@@ -110,22 +372,19 @@ const setup = async (projectDir) => {
110
372
  ...packageJson.dependencies,
111
373
  ...packageJson.devDependencies
112
374
  };
113
- const depNames = Object.keys(allDeps).filter(
114
- (d) => d !== "defuss-ssg"
115
- // skip self-reference (we're already running)
116
- );
117
- const allResolvable = depNames.length === 0 || depNames.every((d) => canResolve(d, projectDir));
375
+ const depNames = Object.keys(allDeps);
376
+ const allResolvable = depNames.length === 0 || depNames.every((dependency) => canResolve(dependency, projectDir));
118
377
  if (allResolvable) {
119
- console.log(`All dependencies already available - skipping install.`);
378
+ console.log("All dependencies already available - skipping install.");
120
379
  return { code: "OK", message: "Setup completed (deps already available)" };
121
380
  }
122
381
  console.log(`Setting up project in ${projectDir} using ${pm}...`);
123
382
  if (pm === "bun") {
124
383
  try {
125
384
  await new Promise((resolve, reject) => {
126
- const child = spawn(pm, ["pm", "trust", "esbuild"], {
385
+ const child = spawn("bun", ["pm", "trust", "esbuild"], {
127
386
  cwd: projectDir,
128
- shell: true,
387
+ shell: process.platform === "win32",
129
388
  stdio: "ignore",
130
389
  env: { ...process.env, BUN_WORKSPACE_ROOT: projectDir }
131
390
  });
@@ -136,46 +395,142 @@ const setup = async (projectDir) => {
136
395
  }
137
396
  }
138
397
  try {
139
- const bunEnv = { ...process.env, BUN_WORKSPACE_ROOT: projectDir };
398
+ const installCommand = getInstallCommand(pm, projectDir);
140
399
  await runInstall(
141
- pm,
142
- pm === "bun" ? ["install", "--no-cache", "--linker", "isolated"] : ["install"],
400
+ installCommand.cmd,
401
+ installCommand.args,
143
402
  projectDir,
144
- pm === "bun" ? bunEnv : void 0
403
+ installCommand.env
145
404
  );
146
405
  console.log("Dependencies installed successfully.");
406
+ return { code: "OK", message: "Setup completed successfully" };
147
407
  } catch (error) {
148
- if (pm === "bun") {
149
- console.warn(
150
- `Warning: ${error.message}
151
- Falling back to npm install...`
152
- );
153
- try {
154
- await runInstall("npm", ["install"], projectDir);
155
- console.log("Dependencies installed successfully via npm.");
156
- } catch (npmError) {
157
- console.warn(
158
- `Warning: npm install also failed: ${npmError.message}
159
- Continuing anyway - dependencies may already be available.`
160
- );
408
+ return {
409
+ code: "INSTALL_FAILED",
410
+ message: `Failed to install dependencies with ${pm}: ${error.message}`
411
+ };
412
+ }
413
+ };
414
+
415
+ const usage = `Usage: defuss-ssg [dev|build|serve|docker-dev|docker-build|docker-serve] [folder] [options]
416
+ No args => dev .
417
+ Single path => dev <path>
418
+ Single command => <command> .
419
+ Command + folder => <command> <folder>
420
+ Flags:
421
+ --debug, -d
422
+ --multicore
423
+ --port, -p <number>
424
+ --host, -H <host>
425
+ --skip-setup
426
+ --docker-args <args...>`;
427
+ const isTruthy = (value) => {
428
+ if (!value) return false;
429
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
430
+ };
431
+ const isDefussWorkerProcess = () => typeof process.env.DEFUSS_WORKER_INDEX === "string";
432
+ const readFlagValue = (args, index, flag) => {
433
+ const next = args[index + 1];
434
+ if (!next || next.startsWith("-")) {
435
+ throw new Error(`Missing value for ${flag}`);
436
+ }
437
+ return next;
438
+ };
439
+ const parsePort = (value) => {
440
+ const port = Number(value);
441
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
442
+ throw new Error(`Invalid port: ${value}`);
443
+ }
444
+ return port;
445
+ };
446
+ const parseCliArgs = (args) => {
447
+ const dockerArgsIndex = args.indexOf("--docker-args");
448
+ const cliArgs = dockerArgsIndex === -1 ? args : args.slice(0, dockerArgsIndex);
449
+ const dockerArgs = dockerArgsIndex === -1 ? [] : args.slice(dockerArgsIndex + 1);
450
+ let debug = false;
451
+ let multicore = false;
452
+ let skipSetup = isTruthy(process.env.DEFUSS_SSG_SKIP_SETUP) || isDefussWorkerProcess();
453
+ let port;
454
+ let host;
455
+ const positional = [];
456
+ for (let index = 0; index < cliArgs.length; index += 1) {
457
+ const arg = cliArgs[index];
458
+ if (arg === "--debug" || arg === "-d") {
459
+ debug = true;
460
+ continue;
461
+ }
462
+ if (arg === "--multicore") {
463
+ multicore = true;
464
+ continue;
465
+ }
466
+ if (arg === "--skip-setup" || arg === "--no-setup") {
467
+ skipSetup = true;
468
+ continue;
469
+ }
470
+ if (arg === "--port" || arg === "-p") {
471
+ port = parsePort(readFlagValue(args, index, arg));
472
+ index += 1;
473
+ continue;
474
+ }
475
+ if (arg.startsWith("--port=")) {
476
+ port = parsePort(arg.slice("--port=".length));
477
+ continue;
478
+ }
479
+ if (arg === "--host" || arg === "-H") {
480
+ host = readFlagValue(args, index, arg);
481
+ index += 1;
482
+ continue;
483
+ }
484
+ if (arg.startsWith("--host=")) {
485
+ host = arg.slice("--host=".length);
486
+ if (!host) {
487
+ throw new Error("Missing value for --host");
161
488
  }
162
- } else {
163
- console.warn(
164
- `Warning: ${error.message}
165
- Continuing anyway - dependencies may already be available.`
166
- );
489
+ continue;
167
490
  }
491
+ positional.push(arg);
168
492
  }
169
- return { code: "OK", message: "Setup completed successfully" };
493
+ return {
494
+ debug,
495
+ dockerArgs,
496
+ multicore,
497
+ skipSetup,
498
+ port,
499
+ host,
500
+ positional
501
+ };
170
502
  };
171
-
172
503
  (async () => {
173
504
  const args = process.argv.slice(2);
174
- const debug = args.includes("--debug") || args.includes("-d");
175
- const multicore = args.includes("--multicore");
176
- const positional = args.filter((a) => !a.startsWith("-"));
177
- const commands = /* @__PURE__ */ new Set(["dev", "build", "serve"]);
178
- const usage = "Usage: defuss-ssg [dev|build|serve] [folder]\n No args => dev .\n Single path => dev <path>\n Single command => <command> .\n Command + folder => <command> <folder>\n Flags: [--debug] [--multicore]";
505
+ const commands = /* @__PURE__ */ new Set([
506
+ "dev",
507
+ "build",
508
+ "serve",
509
+ "docker-dev",
510
+ "docker-build",
511
+ "docker-serve"
512
+ ]);
513
+ const containerCommands = /* @__PURE__ */ new Set([
514
+ "docker-dev",
515
+ "docker-build",
516
+ "docker-serve"
517
+ ]);
518
+ let debug;
519
+ let dockerArgs;
520
+ let multicore;
521
+ let skipSetup;
522
+ let port;
523
+ let host;
524
+ let positional;
525
+ try {
526
+ ({ debug, dockerArgs, multicore, skipSetup, port, host, positional } = parseCliArgs(args));
527
+ } catch (error) {
528
+ console.error(
529
+ `${error instanceof Error ? error.message : "Invalid CLI arguments"}
530
+ ${usage}`
531
+ );
532
+ process.exit(1);
533
+ }
179
534
  let command;
180
535
  let folder;
181
536
  if (positional.length === 0) {
@@ -202,26 +557,70 @@ Continuing anyway - dependencies may already be available.`
202
557
  process.exit(1);
203
558
  }
204
559
  const projectDir = resolve(folder);
205
- await setup(projectDir);
560
+ const workerProcess = isDefussWorkerProcess();
561
+ const isContainerCommand = containerCommands.has(command);
562
+ if (!isContainerCommand && dockerArgs.length > 0) {
563
+ console.error(
564
+ `--docker-args can only be used with docker-dev, docker-build, or docker-serve.
565
+ ${usage}`
566
+ );
567
+ process.exit(1);
568
+ }
569
+ if (isContainerCommand) {
570
+ await runContainerCommand({
571
+ command,
572
+ projectDir,
573
+ debug,
574
+ host,
575
+ port,
576
+ multicore,
577
+ skipSetup,
578
+ dockerArgs
579
+ });
580
+ return;
581
+ }
582
+ if (skipSetup) {
583
+ if (!workerProcess) {
584
+ console.log(
585
+ `Skipping dependency setup for ${folder} (prepared environment).`
586
+ );
587
+ }
588
+ } else {
589
+ const setupStatus = await setup(projectDir);
590
+ if (setupStatus.code !== "OK") {
591
+ console.error(setupStatus.message);
592
+ process.exit(1);
593
+ }
594
+ }
206
595
  if (command === "dev") {
207
- console.log(`Starting Vite dev server for ${folder}...`);
596
+ if (!workerProcess) {
597
+ console.log(`Starting Vite dev server for ${folder}...`);
598
+ }
208
599
  await dev({
209
600
  projectDir,
210
601
  debug,
602
+ host,
603
+ port,
211
604
  writeDevOutput: true
212
605
  });
213
606
  } else if (command === "build") {
214
- console.log(`Building ${folder}...`);
607
+ if (!workerProcess) {
608
+ console.log(`Building ${folder}...`);
609
+ }
215
610
  await build({
216
611
  projectDir,
217
612
  debug,
218
613
  mode: "build"
219
614
  });
220
615
  } else if (command === "serve") {
221
- console.log(`Serving built output for ${folder}...`);
616
+ if (!workerProcess) {
617
+ console.log(`Serving built output for ${folder}...`);
618
+ }
222
619
  await serve({
223
620
  projectDir,
224
621
  debug,
622
+ host,
623
+ port,
225
624
  workers: multicore ? "auto" : 1
226
625
  });
227
626
  } else {