Skip to content

fix(browse): externalize @ngrok/ngrok in Node server bundle#978

Open
muddy-clay wants to merge 1 commit intogarrytan:mainfrom
muddy-clay:fix/bun-build-ngrok-external
Open

fix(browse): externalize @ngrok/ngrok in Node server bundle#978
muddy-clay wants to merge 1 commit intogarrytan:mainfrom
muddy-clay:fix/bun-build-ngrok-external

Conversation

@muddy-clay
Copy link
Copy Markdown

Summary

  • ./setup fails on Windows with bun ≥ 1.3.12 at the Node server bundle step
  • Error: cannot write multiple output files without an output directory
  • Fix: add --external "@ngrok/ngrok" alongside the existing externals

Root cause

bun 1.3.12 inlines @ngrok/ngrok's native .node binary as a second bundle asset when building browse/src/server.ts. bun build --outfile only allows a single output file, so the build aborts:

$ bun build browse/src/server.ts --target=node --outfile browse/dist/server-node.mjs \
    --external playwright --external playwright-core --external diff --external "bun:sqlite"
error: cannot write multiple output files without an output directory

Switching to --outdir reveals what the second output is:

$ bun build ... --outdir browse/dist
Bundled 26 modules in 62ms

  server.js                           0.34 MB   (entry point)
  ngrok.win32-x64-msvc-0fye9xvy.node  10.30 MB  (asset)

@ngrok/ngrok ships a platform-specific native binary and loads it from node_modules at runtime via its package index — bundling buys nothing and forces the multi-output failure. It needs the same --external treatment as playwright and playwright-core.

The existing build previously worked on earlier bun versions because they didn't treat .node assets as bundle outputs the same way. bun 1.3.12 (the current version bun.sh's installer hands out as of this PR) triggers it consistently.

Blast radius

This is the one-line diff:

   --external "bun:sqlite" \
+  --external "@ngrok/ngrok"

No behavior change — @ngrok/ngrok is still require'd from node_modules at runtime exactly as before. The compiled browse.exe / find-browse.exe aren't affected (those use bun build --compile, not this script).

Test plan

  • Fresh ./setup on Windows 10 with bun 1.3.12: Node server bundle ready: .../server-node.mjs (317KB)
  • browse/dist/server-node.mjs, bun-polyfill.cjs, and ngrok.*.node all present in browse/dist/ after build
  • Verify on macOS / Linux (should be a no-op since those paths still work — the fix is adding an external, not removing one)

Repro before this PR: install bun 1.3.10 via bun.sh/install (installer actually hands out 1.3.12 despite BUN_VERSION=1.3.10 env var), then run ./setup on Windows. Setup reports gstack ready but the Node bundle step silently errors mid-run.

bun 1.3.12+ inlines @ngrok/ngrok's native .node binary as a second
bundle asset, which causes `bun build --outfile` to fail with:

    error: cannot write multiple output files without an output directory

This breaks `./setup` on Windows for every user on bun >= 1.3.12,
leaving browse/dist/server-node.mjs unbuilt.

@ngrok/ngrok ships a native binary per platform and is loaded from
node_modules at runtime by its package index, so there is no benefit
to bundling it — it must be externalized for the same reason as
playwright and playwright-core.

Tested locally: re-running ./setup on Windows with bun 1.3.12 now
produces server-node.mjs (317KB) cleanly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant