build-node-server.sh
62 lines · browse/scripts/build-node-server.sh at 3f79d81
1#!/usr/bin/env bash
2# Build a Node.js-compatible server bundle for Windows.
3#
4# On Windows, Bun can't launch or connect to Playwright's Chromium
5# (oven-sh/bun#4253, #9911). This script produces a server bundle
6# that runs under Node.js with Bun API polyfills.
8set -e
10GSTACK_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
11# Windows (MSYS/Git Bash): convert to a Windows-style path — Bun cannot open
12# MSYS /c/... absolute paths ("FileNotFound opening root directory").
13case "$(uname -s)" in
14 MINGW*|MSYS*|CYGWIN*) GSTACK_DIR="$(cygpath -m "$GSTACK_DIR")" ;;
15esac
16SRC_DIR="$GSTACK_DIR/browse/src"
17DIST_DIR="$GSTACK_DIR/browse/dist"
18mkdir -p "$DIST_DIR"
20echo "Building Node-compatible server bundle..."
22# Step 1: Transpile server.ts to a single .mjs bundle (externalize runtime deps)
23#
24# Externalize packages with native addons, dynamic imports, or runtime resolution
25# (sharp loads a platform .node addon; socks is resolved at runtime, and Bun on
26# Windows refuses to inline either, #2260).
27# If you add a new dependency that uses `await import()` or has a .node addon,
28# add it here. Otherwise `bun build --outfile` will fail with
29# "cannot write multiple output files without an output directory".
30bun build "$SRC_DIR/server.ts" \
31 --target=node \
32 --outfile "$DIST_DIR/server-node.mjs" \
33 --external playwright \
34 --external playwright-core \
35 --external diff \
36 --external "bun:sqlite" \
37 --external "@ngrok/ngrok" \
38 --external socks \
39 --external sharp
41# Step 2: Post-process
42# Replace import.meta.dir with a resolvable reference
43perl -pi -e 's/import\.meta\.dir/__browseNodeSrcDir/g' "$DIST_DIR/server-node.mjs"
45# Step 3: Create the final file with polyfill header injected after the first line
46{
47 head -1 "$DIST_DIR/server-node.mjs"
48 echo '// ── Windows Node.js compatibility (auto-generated) ──'
49 echo 'import { fileURLToPath as _ftp } from "node:url";'
50 echo 'import { dirname as _dn } from "node:path";'
51 echo 'const __browseNodeSrcDir = _dn(_dn(_ftp(import.meta.url))) + "/src";'
52 echo '{ const _r = createRequire(import.meta.url); _r("./bun-polyfill.cjs"); }'
53 echo '// ── end compatibility ──'
54 tail -n +2 "$DIST_DIR/server-node.mjs"
55} > "$DIST_DIR/server-node.tmp.mjs"
57mv "$DIST_DIR/server-node.tmp.mjs" "$DIST_DIR/server-node.mjs"
59# Step 4: Copy polyfill to dist/
60cp "$SRC_DIR/bun-polyfill.cjs" "$DIST_DIR/bun-polyfill.cjs"
62echo "Node server bundle ready: $DIST_DIR/server-node.mjs"