From f9462973263f9dd23bcb945c65cbacb7cc85bade Mon Sep 17 00:00:00 2001 From: christophe dervieux Date: Thu, 23 Apr 2026 16:44:54 +0200 Subject: [PATCH 1/2] Warn and skip preview build when npm is missing during configure Check for npm at the start of configure() instead of failing late in buildQuartoPreviewJs() after ~300MB of downloads. When npm is missing, emit a warning explaining that the quarto preview live-reload feature will not be available, then skip the quarto-preview.js build step. The rest of Quarto (render, pdf, publish) builds and runs normally. --- package/src/common/configure.ts | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/package/src/common/configure.ts b/package/src/common/configure.ts index f8406df08b..b3e12458c1 100644 --- a/package/src/common/configure.ts +++ b/package/src/common/configure.ts @@ -18,13 +18,25 @@ import { configureDependency, kDependencies, } from "./dependencies/dependencies.ts"; -import { suggestUserBinPaths } from "../../../src/core/path.ts"; +import { suggestUserBinPaths, which } from "../../../src/core/path.ts"; import { buildQuartoPreviewJs } from "./previewjs.ts"; import { isWindows } from "../../../src/deno_ral/platform.ts"; export async function configure( config: Configuration, ) { + // npm is only required for building quarto-preview.js (used by `quarto preview` + // for HTML/revealjs live-reload). Warn upfront so the user knows before the + // long dependency downloads; the JS build is skipped below if npm is missing. + const hasNpm = (await which("npm")) !== undefined; + if (!hasNpm) { + warning( + "npm not found on PATH. The 'quarto preview' live-reload feature " + + "will not be available. Install Node.js (which provides npm) and " + + "re-run configure to enable it.", + ); + } + // Download dependencies for (const dependency of kDependencies) { const targetDir = join( @@ -34,12 +46,16 @@ export async function configure( await configureDependency(dependency, targetDir, config); } - info("Building quarto-preview.js..."); - const result = buildQuartoPreviewJs(config.directoryInfo.src); - if (!result.success) { - throw new Error(); + if (hasNpm) { + info("Building quarto-preview.js..."); + const result = buildQuartoPreviewJs(config.directoryInfo.src); + if (!result.success) { + throw new Error(); + } + info("Build completed."); + } else { + info("Skipping quarto-preview.js build (npm not found)."); } - info("Build completed."); // Move the quarto script into place info("Placing Quarto script"); From 52f6a76221e17b3b839e7db225fa65404c7bd47c Mon Sep 17 00:00:00 2001 From: christophe dervieux Date: Thu, 23 Apr 2026 18:25:08 +0200 Subject: [PATCH 2/2] Error out instead of skipping when npm is missing A half-built Quarto without quarto-preview.js would later fail at runtime when `quarto preview` tries to read the missing file, producing another confusing error. Requiring npm upfront keeps the contract simple: configure succeeds only if all required tools are available. --- package/src/common/configure.ts | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/package/src/common/configure.ts b/package/src/common/configure.ts index b3e12458c1..a40b185fa8 100644 --- a/package/src/common/configure.ts +++ b/package/src/common/configure.ts @@ -25,15 +25,12 @@ import { isWindows } from "../../../src/deno_ral/platform.ts"; export async function configure( config: Configuration, ) { - // npm is only required for building quarto-preview.js (used by `quarto preview` - // for HTML/revealjs live-reload). Warn upfront so the user knows before the - // long dependency downloads; the JS build is skipped below if npm is missing. - const hasNpm = (await which("npm")) !== undefined; - if (!hasNpm) { - warning( - "npm not found on PATH. The 'quarto preview' live-reload feature " + - "will not be available. Install Node.js (which provides npm) and " + - "re-run configure to enable it.", + // npm is required later for building quarto-preview.js (used by `quarto + // preview` live-reload). Check upfront to fail fast before downloading + // hundreds of MB of dependencies when npm is missing. + if ((await which("npm")) === undefined) { + throw new Error( + "npm not found on PATH. Please install Node.js (which provides npm) before running configure.", ); } @@ -46,16 +43,12 @@ export async function configure( await configureDependency(dependency, targetDir, config); } - if (hasNpm) { - info("Building quarto-preview.js..."); - const result = buildQuartoPreviewJs(config.directoryInfo.src); - if (!result.success) { - throw new Error(); - } - info("Build completed."); - } else { - info("Skipping quarto-preview.js build (npm not found)."); + info("Building quarto-preview.js..."); + const result = buildQuartoPreviewJs(config.directoryInfo.src); + if (!result.success) { + throw new Error(); } + info("Build completed."); // Move the quarto script into place info("Placing Quarto script");