fix(desktop): pin @std/http in generated Vite SPA entrypoint + add hermetic compile test#35676
Conversation
…rmetic compile test The Vite SPA (`vite build` → static `dist/`) framework entrypoint generated by `deno compile .` / `deno desktop .` imported `jsr:@std/http/file-server` without a version constraint. A compiled desktop/standalone binary is meant to be a self-contained artifact, so resolving an unpinned remote dependency at build time makes the output non-reproducible and lets a future breaking `@std/http` release change the app on a plain rebuild. Pin it to `jsr:@std/http@^1`. Also add the first end-to-end spec test for the Vite SPA branch. Previously only the Vite SSR path had a compile spec; the SPA path (which generates the `serveDir`-based entrypoint) was covered by unit tests over the generated code string only, never actually compiled. The new test keeps hermetic by remapping the `@std/http` import to a local stub via the project's import map, and asserts that `deno compile .` detects Vite, runs the build task, resolves the generated entrypoint's import, includes `dist/`, and produces a binary. Refs #35590 Co-Authored-By: Divy Srivastava <[email protected]>
|
CI note: the only red job is Everything that actually exercises this change is green on every platform: all |
The only failing job was an unrelated `deno serve --watch` output-timing flake (`integration::watcher::serve_watch_parallel_stops_old_workers`) on the Windows-aarch64 runner; all specs/unit/lint jobs are green. Co-Authored-By: Divy Srivastava <[email protected]>
|
One gap worth closing: unlike There's a cheap way to get that coverage with the existing stub: since // _file_server.ts
console.log("file-server stub loaded");
if (Deno.env.get("EXIT_ON_LOAD")) Deno.exit(0);
export function serveDir(_req: Request): Promise<Response> {
return Promise.resolve(new Response(null, { status: 404 }));
}plus a second step per platform mirroring Not a blocker, but since this test's whole purpose is end-to-end coverage of the SPA path, running the artifact it produces seems worth the extra step. |
Address review feedback: the vite_spa test stopped at compiling the binary and never ran it, leaving the runtime half — the binary booting and loading the generated entrypoint + VFS-embedded remapped import — uncovered. The generated SPA entrypoint imports the (stubbed) file-server module before it reaches the blocking `Deno.serve`, so the stub's top level runs at startup. Make it print a marker and, when `EXIT_ON_LOAD` is set, `Deno.exit(0)` before the server starts. A new run step per platform boots `./main` with `EXIT_ON_LOAD=1` and asserts the marker, proving the compiled binary starts and resolves the import-map-remapped specifier out of the embedded VFS — without hanging the harness on a live server. Co-Authored-By: Divy Srivastava <[email protected]>
|
Good call — done in 8fc2c65. The stub now logs That gives the runtime coverage you described: the compiled binary boots, resolves the import-map-remapped Verified locally: |
Summary
The Vite SPA framework entrypoint that
deno compile ./deno desktop .generate imported
jsr:@std/http/file-serverwithout a version constraint.A compiled desktop/standalone binary is meant to be a self-contained artifact,
so resolving an unpinned remote dependency at build time makes the output
non-reproducible and lets a future breaking
@std/httprelease silently changethe app on a plain rebuild. This pins it to
jsr:@std/http@^1.It also adds the first end-to-end spec test for the Vite SPA branch. Until
now only the Vite SSR path had a
compilespec test; the SPA path (whichgenerates the
serveDir-based entrypoint) was covered only by unit tests thatassert the generated code string — it was never actually compiled. The new
tests/specs/compile/framework_detection/vite_spatest stays hermetic byremapping the
@std/httpimport to a local stub through the project's importmap, and verifies the whole pipeline: detect Vite → run the build task → resolve
the generated entrypoint's import → include
dist/→ produce a binary.Context / relation to #35590
While investigating the blank-window report in #35590, the root cause of the
empty webview DOM turned out to be the
app://in-process memory-channeltransport added in #35272 (the webview doesn't render that non-standard scheme
as a normal document) — that is being addressed by the transport revert #35670,
which restores TCP-loopback serving. I verified the generated
serveDirSPAentrypoint itself serves the built
dist/correctly over plain HTTP (/→index.htmlwith#app, hashed JS/CSS assets with correct MIME types), so theserving layer was never the problem.
This PR is the complementary hardening + regression coverage for that same Vite
desktop SPA path, independent of (and non-conflicting with) the transport
revert.
Testing
cargo test -p deno --lib framework— 61 passed (incl. the new pin assertion)cargo test --test specs -- framework_detection— 5 passed, incl. the newvite_spaand the existingvite_ssr(no regression)Refs #35590
Closes denoland/divybot#744