fix(vite): pre-bundle @runanywhere/proto-ts deep imports so npm run dev doesn't hang - #18
Conversation
…ev doesn't hang @runanywhere/proto-ts ships as plain CommonJS, and @runanywhere/web / web-llamacpp / web-onnx deep-import dozens of its generated modules individually (proto-ts/logging, /sdk_events, /convenience/errors_convenience, ...) instead of the package root. Vite's dependency scanner only auto-discovers some of these during dev and serves the rest straight to the browser as raw CJS files, which the browser's native ESM loader can't read as modules — the app hangs forever on "Loading the SDK..." with a "does not provide an export named '...'" console error, a different export each time depending on which undiscovered subpath loads first. Confirmed via real headless-browser testing that this only affects `npm run dev` (Vite's dev-server module serving) — `npm run build` + `vite preview` (Rollup) already resolved CJS/ESM correctly and were never affected. Fix: enumerate every generated module under proto-ts's dist/ at config-eval time and force all of them into optimizeDeps.include (plus dedupe, since npm ci reproduces a nested duplicate proto-ts copy from the lockfile), so esbuild pre-bundles them into real ESM up front. This self-updates as the SDK's generated proto surface grows, instead of adding subpaths one crash at a time. Verified end to end after the fix: splash clears, zero console errors, readiness contract reports sdk:"ready"/backend:"registered", and a full download -> load -> chat round trip against PrismML Bonsai 1.7B produced a correct real response. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review. 📝 WalkthroughWalkthroughVite now recursively discovers generated JavaScript deep imports in ChangesProto-ts Vite integration
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: 🔵 Low · up to The change unifies the proto package resolution and pre-bundles its generated modules to prevent the development server from hanging, but the shared resolution setting also affects build and preview behavior. The PR is mergeable with owner awareness that the selected package copy should be validated across all modes. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: dependency version conflict. Check your lock file or package.json. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bug
npm run devhangs forever on the "Starting RunAnywhere / Loading the SDK…"splash. The browser console shows:
Reloading surfaces a different export each time (
SDKEventfromsdk_events.js, etc.) depending on which module happens to load first.Root cause
@runanywhere/proto-tsships as plain CommonJS (exports.LogLevel = ...).@runanywhere/web/web-llamacpp/web-onnxdeep-import dozens of itsgenerated modules individually —
@runanywhere/proto-ts/logging,/sdk_events,/convenience/errors_convenience,/model_types, etc. —rather than through the package root.
Vite's dependency scanner only auto-discovers some of these deep imports
during dev (it found
model_typeson its own, but notloggingorsdk_events, even though@runanywhere/web's compiled JS imports them thesame way, side by side). The undiscovered ones get served straight to the
browser as raw CJS files, and the browser's native ESM loader can't see a
CommonJS named export — hence the app hangs and the error rotates depending
on load order.
I confirmed via headless-browser testing (Playwright) that this only
affects
npm run dev—npm run build+vite preview(Rollup) alreadyresolve CJS/ESM correctly and were never affected. So this is a real,
100%-of-the-time local-dev blocker, not a production regression.
I also tried
resolve.dedupe: ['@runanywhere/proto-ts']alone first (there'sa second nested copy of the package under
@runanywhere/web/node_modules/@runanywhere/proto-tsthatnpm cireproduces verbatim from the lockfile) — it correctly consolidated resolution
down to one copy, but the identical error persisted, confirming the bug is
about the file never being pre-bundled at all, not about which physical copy
of it gets used.
Fix
vite.config.ts:resolve.dedupe: ['@runanywhere/proto-ts']— ensures only one physicalcopy of the package is ever in the module graph.
optimizeDeps.include— instead of listing deep subpaths one crash at atime,
protoTsDeepImports()walksnode_modules/@runanywhere/proto-ts/distat config-eval time and lists every generated
.jsmodule, so esbuildpre-bundles all of them into real ESM up front. This self-updates as the
SDK's generated proto surface grows.
Verification
npm run lint/npm run typecheck/npm run test(23/23) /npm run buildall still pass.window.__RUNANYWHERE_AI_READY__reportssdk:"ready"/backend:"registered".through the actual UI, loaded it, sent "Say the word banana and nothing
else." through the chat UI, got back a correct real generated reply
(
banana).Test plan
npm ci && npm run dev, loadhttp://localhost:3000, confirm it getspast the loading splash into the model picker (no console errors)
reply comes back
npm run build && npm run previewstill works (already unaffected, butworth a sanity check)
🤖 Generated with Claude Code
Summary by CodeRabbit