Skip to content

Commit cfc2227

Browse files
fix: use committed .js wrapper + separate _handler.js bundle to avoid Vercel TS compilation and file-not-found errors
Agent-Logs-Url: https://github.com/objectstack-ai/framework/sessions/656a5b4f-383c-4318-a657-a952f4445583 Co-authored-by: xuyushun441-sys <255036401+xuyushun441-sys@users.noreply.github.com>
1 parent ab6ad6a commit cfc2227

6 files changed

Lines changed: 31 additions & 39 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixed
1111
- **Studio Vercel API routes returning HTML instead of JSON** — Adopted the
1212
same Vercel deployment pattern used by `hotcrm`: committed
13-
`api/[[...route]].ts` catch-all route so Vercel detects it pre-build,
13+
`api/[[...route]].js` catch-all route so Vercel detects it pre-build,
1414
switched esbuild output from CJS to ESM (fixes `"type": "module"` conflict),
15-
and changed the output path from `api/index.js` to `api/[[...route]].js`.
15+
and changed the bundle output to `api/_handler.js` (a separate file that
16+
the committed wrapper re-exports). This avoids both Vercel's TS
17+
compilation overwriting the bundle (`ERR_MODULE_NOT_FOUND`) and the
18+
"File not found" error from deleting source files during build.
1619
Updated rewrites to match: `/api/:path*``/api/[[...route]]`.
17-
Added post-bundle cleanup to remove the `.ts` stub so Vercel's
18-
`@vercel/node` builder uses the self-contained esbuild bundle instead of
19-
compiling the stub (which would fail with `ERR_MODULE_NOT_FOUND`).
2020
- **Studio CORS error on Vercel temporary/preview domains** — Changed
2121
`VITE_SERVER_URL` from hardcoded `https://play.objectstack.ai` to `""`
2222
(empty string / same-origin) in `vercel.json` so each deployment — including

apps/studio/.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ pnpm-lock.yaml
55
# Build outputs
66
dist
77
build
8-
api/*.js
9-
api/*.js.map
8+
api/_handler.js
9+
api/_handler.js.map
1010
*.tsbuildinfo
1111

1212
# Development

apps/studio/api/[[...route]].js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Vercel Serverless Function — Catch-all API route.
2+
//
3+
// This file MUST be committed to the repository so Vercel can detect it
4+
// as a serverless function during the pre-build phase.
5+
//
6+
// It delegates to the esbuild bundle (`_handler.js`) generated by
7+
// `scripts/bundle-api.mjs` during the Vercel build step. A separate
8+
// bundle file is used (rather than overwriting this file) so that:
9+
// 1. Vercel always finds this committed entry point (no "File not found").
10+
// 2. Vercel does not TypeScript-compile a .ts stub that references
11+
// source files absent at runtime (no ERR_MODULE_NOT_FOUND).
12+
//
13+
// @see ../server/index.ts — the actual server entrypoint
14+
// @see ../scripts/bundle-api.mjs — the esbuild bundler
15+
// @see https://github.com/objectstack-ai/hotcrm/blob/main/vercel.json
16+
17+
export { default, config } from './_handler.js';

apps/studio/api/[[...route]].ts

Lines changed: 0 additions & 21 deletions
This file was deleted.

apps/studio/scripts/build-vercel.sh

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ set -euo pipefail
44
# Build script for Vercel deployment of @objectstack/studio.
55
#
66
# Follows the same Vercel deployment pattern as hotcrm:
7-
# - api/[[...route]].ts is committed to the repo (Vercel detects it pre-build)
8-
# - esbuild bundles server/index.ts → api/[[...route]].js (replaces TS at deploy)
7+
# - api/[[...route]].js is committed to the repo (Vercel detects it pre-build)
8+
# - esbuild bundles server/index.ts → api/_handler.js (self-contained bundle)
9+
# - The committed .js wrapper re-exports from _handler.js at runtime
910
# - Vite SPA output is copied to public/ for CDN serving
1011
#
1112
# Vercel routing (framework: null, no outputDirectory):
@@ -14,7 +15,7 @@ set -euo pipefail
1415
#
1516
# Steps:
1617
# 1. Turbo build (Vite SPA → dist/)
17-
# 2. Bundle the API serverless function (→ api/[[...route]].js)
18+
# 2. Bundle the API serverless function (→ api/_handler.js)
1819
# 3. Copy Vite output to public/ for Vercel CDN serving
1920

2021
echo "[build-vercel] Starting studio build..."
@@ -26,15 +27,10 @@ cd apps/studio
2627

2728
# 2. Bundle API serverless function
2829
node scripts/bundle-api.mjs
29-
# Remove the TS source file so Vercel's @vercel/node builder uses the
30-
# pre-bundled JS directly. Without this, Vercel compiles the TS stub
31-
# itself, producing a thin re-export that references ../server/index —
32-
# a file that doesn't exist at runtime (ERR_MODULE_NOT_FOUND).
33-
rm -f "api/[[...route]].ts"
3430

3531
# 3. Copy Vite build output to public/ for static file serving
3632
rm -rf public
3733
mkdir -p public
3834
cp -r dist/* public/
3935

40-
echo "[build-vercel] Done. Static files in public/, serverless function in api/[[...route]].js"
36+
echo "[build-vercel] Done. Static files in public/, serverless function in api/[[...route]].js → api/_handler.js"

apps/studio/scripts/bundle-api.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ await build({
3737
platform: 'node',
3838
format: 'esm',
3939
target: 'es2020',
40-
outfile: 'api/[[...route]].js',
40+
outfile: 'api/_handler.js',
4141
sourcemap: true,
4242
external: EXTERNAL,
4343
// Silence warnings about optional/unused require() calls in knex drivers
@@ -48,4 +48,4 @@ await build({
4848
banner: { js: '// Bundled by esbuild — see scripts/bundle-api.mjs' },
4949
});
5050

51-
console.log('[bundle-api] Bundled server/index.ts → api/[[...route]].js');
51+
console.log('[bundle-api] Bundled server/index.ts → api/_handler.js');

0 commit comments

Comments
 (0)