Open redbaron76 opened 1 month ago
Hi @redbaron76
Have you ever tried @hono/vite-dev-server
? https://github.com/honojs/vite-plugins/tree/main/packages/dev-server?
In my case, I can't use this vite dev server because it is the Remix server forwarding to hono, but not the opposite.
Hono does actually provide the IncomingMessage using the node-server: https://hono.dev/docs/getting-started/nodejs#access-the-raw-node-js-apis
import { serve, type HttpBindings } from '@hono/node-server'
const app = new Hono<{ Bindings: HttpBindings }>()
app.all(
'/*',
createMiddleware<{ Bindings: HttpBindings }>(
(ctx, next) =>
new Promise((resolve) =>
viteServer.middlewares(ctx.env.incoming, ctx.env.outgoing, () =>
resolve(next())
)
)
)
)
serve({ fetch: app.fetch, port: 3000 }, () => {
console.log('Listening on http://localhost:3000')
})
Got something working to get Hono & Vite in both Bun & Node. Not sure if it extends to SSR, only supports streaming in Node.js
// Usage
import { serve, type HttpBindings } from '@hono/node-server'
const app = new Hono<{ Bindings: HttpBindings }>()
app.all('/*', viteMiddleware())
serve({ fetch: app.fetch, port: 3000 }, () => {
console.log('Listening on http://localhost:3000')
})
// Library
import { createServer, type ViteDevServer } from 'vite'
import { IncomingMessage, ServerResponse } from 'http'
import react from '@vitejs/plugin-react'
import { HttpBindings } from '@hono/node-server'
import { createMiddleware } from 'hono/factory'
let server: ViteDevServer
export async function getViteServer() {
if (!server) {
server = await createServer({
...
appType: 'spa',
plugins: [react()],
})
}
return server
}
export function viteMiddleware() {
return createMiddleware<{ Bindings: HttpBindings }>(async (ctx, next) => {
const vite = await getViteServer()
return new Promise((resolve) => {
// Node.js
// @ts-expect-error
if (typeof Bun === 'undefined') {
vite.middlewares(ctx.env.incoming, ctx.env.outgoing, () =>
resolve(next())
)
return
}
// Bun
let sent = false
const headers = new Headers()
vite.middlewares(
{
url: new URL(ctx.req.raw.url, 'http://localhost').pathname,
method: ctx.req.raw.method,
headers: Object.fromEntries(
// @ts-expect-error
ctx.req.raw.headers
),
} as IncomingMessage,
{
setHeader(name, value: any) {
headers.set(name, value)
return this
},
end(body) {
sent = true
resolve(
ctx.body(body, {
status: this.statusCode,
statusText: this.statusMessage,
headers,
})
)
},
} as ServerResponse,
() => sent || resolve(next())
)
})
})
}
What is the feature you are proposing?
I'm trying to perform SSR using React + Vite in Hono instead of Express, as explained in all online examples. The problem is that Hono middlewares are not compatible with Connect instances, so it's not possible to achieve the same goal.
Vite server provides a
vite.middlewares
which is a Connect instance, good for Express but not for Hono 'cause it expects asreq
an IncomingMessage that Hono context doesn't provide.Is there any plan to make Hono middlewares fully compatible with Connect or is there any walkaround to get compatibility or any example to follow?
Thanks