Skip to content

fix(vite): pre-bundle @runanywhere/proto-ts deep imports so npm run dev doesn't hang - #18

Merged
sanchitmonga22 merged 1 commit into
mainfrom
fix/vite-proto-ts-esm-dedupe
Aug 17, 2026
Merged

fix(vite): pre-bundle @runanywhere/proto-ts deep imports so npm run dev doesn't hang#18
sanchitmonga22 merged 1 commit into
mainfrom
fix/vite-proto-ts-esm-dedupe

Conversation

@sanchitmonga22

@sanchitmonga22 sanchitmonga22 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Bug

npm run dev hangs forever on the "Starting RunAnywhere / Loading the SDK…"
splash. The browser console shows:

The requested module '/node_modules/@runanywhere/proto-ts/dist/logging.js?v=...'
does not provide an export named 'LogLevel'

Reloading surfaces a different export each time (SDKEvent from
sdk_events.js, etc.) depending on which module happens to load first.

Root cause

@runanywhere/proto-ts ships as plain CommonJS (exports.LogLevel = ...).
@runanywhere/web / web-llamacpp / web-onnx deep-import dozens of its
generated 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_types on its own, but not logging or
sdk_events, even though @runanywhere/web's compiled JS imports them the
same 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) already
resolve 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's
a second nested copy of the package under
@runanywhere/web/node_modules/@runanywhere/proto-ts that npm ci
reproduces 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 physical
    copy of the package is ever in the module graph.
  • optimizeDeps.include — instead of listing deep subpaths one crash at a
    time, protoTsDeepImports() walks node_modules/@runanywhere/proto-ts/dist
    at config-eval time and lists every generated .js module, so esbuild
    pre-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 build all still pass.
  • After the fix: dev server splash clears, zero console errors,
    window.__RUNANYWHERE_AI_READY__ reports
    sdk:"ready"/backend:"registered".
  • Full real end-to-end pass: downloaded PrismML Bonsai 1.7B (237 MB GGUF)
    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, load http://localhost:3000, confirm it gets
    past the loading splash into the model picker (no console errors)
  • Download and load any model, send one chat message, confirm a real
    reply comes back
  • npm run build && npm run preview still works (already unaffected, but
    worth a sanity check)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved application startup and bundling when using generated deep-imported JavaScript modules.
    • Reduced duplicate package loading by consistently resolving the shared protocol package to a single installation.

…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>
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6448db2c-3b22-47a2-b8e5-8abf83e66008

📥 Commits

Reviewing files that changed from the base of the PR and between 386928a and 2abcebc.

📒 Files selected for processing (1)
  • vite.config.ts

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Vite now recursively discovers generated JavaScript deep imports in @runanywhere/proto-ts. It pre-bundles the package root and discovered modules, and deduplicates package resolution to the top-level installation.

Changes

Proto-ts Vite integration

Layer / File(s) Summary
Discover and configure proto-ts imports
vite.config.ts
The configuration scans @runanywhere/proto-ts/dist for non-declaration JavaScript modules. Vite pre-bundles the root and discovered deep imports, then deduplicates package resolution.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🔵 Low · up to 2abce

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: shubhammalhotra28

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the Vite fix and the pre-bundling of @runanywhere/proto-ts deep imports that prevents npm run dev from hanging.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/vite-proto-ts-esm-dedupe

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sanchitmonga22
sanchitmonga22 merged commit 71acc88 into main Aug 17, 2026
5 checks passed
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