feat(framework): Vite dev adapter (#86)#95
Merged
Conversation
Add dev server middleware to the Vite plugin so that `pnpm dev` serves pages and handles API routes. Converts between Node req/res and Web Standard Request/Response, wires route scanning and module loading through createRequestHandler, and auto-updates routes on file changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vite rewrites / to /index.html before our middleware runs. Using req.originalUrl preserves the original path for route matching. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The bundled dist creates separate module instances from Vite's SSR module graph, causing SlotProvider and Slot to use different React contexts. Loading createRequestHandler through ssrLoadModule ensures all framework code shares the same module instances. Also uses req.originalUrl to handle Vite's historyApiFallback rewrite of / to /index.html. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check matchRoute before invoking the handler. Unmatched URLs fall through to Vite for static files and HMR. Matched URLs always get the framework response, including 404 pages defined as routes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes route pre-matching so unmatched URLs get the framework's default 404 page instead of falling through to Vite's empty 404. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTML responses now go through server.transformIndexHtml() to inject the /@vite/client script for HMR support. Test files (.test.tsx) are excluded from route scanning and codegen to prevent SSR evaluation errors and spurious route entries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TypeScript requires allowImportingTsExtensions for .tsx imports. Generated routes.gen.ts now uses extensionless import paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Routes can now use either .ts or .tsx extensions. Templates remain .tsx-only since they contain JSX. Updated route scanner, codegen, dev middleware, and vite plugin to accept both extensions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generated file contains a comment header that triggers the custom/no-comments rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Closed
qantrepreneur
added a commit
that referenced
this pull request
May 21, 2026
* feat(framework): add Vite dev adapter for request handling (#86) Add dev server middleware to the Vite plugin so that `pnpm dev` serves pages and handles API routes. Converts between Node req/res and Web Standard Request/Response, wires route scanning and module loading through createRequestHandler, and auto-updates routes on file changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: replace type casts with runtime guards, use async/await Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use originalUrl to handle Vite's historyApiFallback rewrite Vite rewrites / to /index.html before our middleware runs. Using req.originalUrl preserves the original path for route matching. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: load createRequestHandler via ssrLoadModule to share SlotContext The bundled dist creates separate module instances from Vite's SSR module graph, causing SlotProvider and Slot to use different React contexts. Loading createRequestHandler through ssrLoadModule ensures all framework code shares the same module instances. Also uses req.originalUrl to handle Vite's historyApiFallback rewrite of / to /index.html. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use route pre-match instead of response sniffing for fallthrough Check matchRoute before invoking the handler. Unmatched URLs fall through to Vite for static files and HMR. Matched URLs always get the framework response, including 404 pages defined as routes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: handle all requests through the framework, not just matched routes Removes route pre-matching so unmatched URLs get the framework's default 404 page instead of falling through to Vite's empty 404. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: inject Vite HMR client and exclude test files from routes HTML responses now go through server.transformIndexHtml() to inject the /@vite/client script for HMR support. Test files (.test.tsx) are excluded from route scanning and codegen to prevent SSR evaluation errors and spurious route entries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: strip .tsx extensions from generated import paths TypeScript requires allowImportingTsExtensions for .tsx imports. Generated routes.gen.ts now uses extensionless import paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: support both .ts and .tsx route files Routes can now use either .ts or .tsx extensions. Templates remain .tsx-only since they contain JSX. Updated route scanner, codegen, dev middleware, and vite plugin to accept both extensions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add routes.gen.ts to ESLint ignores Generated file contains a comment header that triggers the custom/no-comments rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: format with Prettier Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Lorenzo <lorenzofkramer@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
createRequestHandlercreateRequestHandlerviaserver.ssrLoadModule("@sundayceo/framework")to avoid dual module instance problem (sharedSlotContext)req.originalUrlto handle Vite'shistoryApiFallbackrewrite (/→/index.html)server.transformIndexHtml()to inject the Vite HMR client (/@vite/client).test.tsx/.test.tsfiles from routes and codegen.tsand.tsxextensions; templates remain.tsx-only.tsx/.tsextensions from generated import paths inroutes.gen.tsascasts throughoutTest plan
.tsand.tsxroute supportpnpm devin playground serves pages at/,/demo,/api/health.test.tsxroutes no longer accessibleCloses #86
🤖 Generated with Claude Code