Skip to content

Commit

Permalink
wip vercel edge
Browse files Browse the repository at this point in the history
  • Loading branch information
nitedani committed Aug 11, 2024
1 parent 66fdf6f commit 022aa1c
Show file tree
Hide file tree
Showing 25 changed files with 416 additions and 63 deletions.
2 changes: 2 additions & 0 deletions examples/hono-react-vercel-edge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules/
/dist/
8 changes: 8 additions & 0 deletions examples/hono-react-vercel-edge/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const runtime = 'edge'

// Import the built server entry from dist, so import.meta.env and other Vite features
// are available in the server entry (Vite already processed this file)
import fetch from '../dist/server/index.mjs'

export const GET = fetch
export const POST = fetch
20 changes: 20 additions & 0 deletions examples/hono-react-vercel-edge/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"scripts": {
"dev": "vite dev",
"build": "vite build",
"prod": "cross-env NODE_ENV=production node dist/server/index.mjs"
},
"dependencies": {
"@vitejs/plugin-react": "^4.3.1",
"hono": "^4.5.5",
"@hono/node-server": "^1.12.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"vike": "^0.4.181",
"vike-node": "^0.1.9",
"vike-react": "^0.4.18",
"vite": "^5.3.5",
"cross-env": "^7.0.3"
},
"type": "module"
}
70 changes: 70 additions & 0 deletions examples/hono-react-vercel-edge/pages/+Layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
export { Layout }

import React from 'react'
import './Layout.css'

function Layout({ children }) {
return (
<PageLayout>
<Sidebar>
<a className="navitem" href="/">
Pre-rendered
</a>
<a className="navitem" href="/dynamic">
Dynamic
</a>
<a className="navitem" href="/static">
Static
</a>
</Sidebar>
<Content>{children}</Content>
</PageLayout>
)
}

function PageLayout({ children }) {
return (
<div
style={{
display: 'flex',
maxWidth: 900,
margin: 'auto'
}}
>
{children}
</div>
)
}

function Sidebar({ children }) {
return (
<div
style={{
padding: 20,
paddingTop: 42,
flexShrink: 0,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
lineHeight: '1.8em'
}}
>
{children}
</div>
)
}

function Content({ children }) {
return (
<div
style={{
padding: 20,
paddingBottom: 50,
borderLeft: '2px solid #eee',
minHeight: '100vh'
}}
>
{children}
</div>
)
}
9 changes: 9 additions & 0 deletions examples/hono-react-vercel-edge/pages/+config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { config }

import vikeReact from 'vike-react/config'

const config = {
// https://vike.dev/extends
extends: vikeReact,
prerender: false
}
14 changes: 14 additions & 0 deletions examples/hono-react-vercel-edge/pages/Layout.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
body {
margin: 0;
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
a {
text-decoration: none;
}

.navitem {
padding: 3px;
}
27 changes: 27 additions & 0 deletions examples/hono-react-vercel-edge/pages/dynamic/+Page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export default Page

import React, { useState } from 'react'

function Page() {
return (
<>
<h1>Welcome</h1>
This page is:
<ul>
<li>Dynamic</li>
<li>No static html generated</li>
<li>Interactive</li>
</ul>
<Counter />
</>
)
}

function Counter() {
const [count, setCount] = useState(0)
return (
<button type="button" onClick={() => setCount((count) => count + 1)}>
Counter {count}
</button>
)
}
27 changes: 27 additions & 0 deletions examples/hono-react-vercel-edge/pages/index/+Page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export default Page

import React, { useState } from 'react'

function Page() {
return (
<>
<h1>Welcome</h1>
This page is:
<ul>
<li>Pre-rendered</li>
<li>Static html generated</li>
<li>Interactive</li>
</ul>
<Counter />
</>
)
}

function Counter() {
const [count, setCount] = useState(0)
return (
<button type="button" onClick={() => setCount((count) => count + 1)}>
Counter {count}
</button>
)
}
3 changes: 3 additions & 0 deletions examples/hono-react-vercel-edge/pages/index/+config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
prerender: true
}
27 changes: 27 additions & 0 deletions examples/hono-react-vercel-edge/pages/static/+Page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export default Page

import React, { useState } from 'react'

function Page() {
return (
<>
<h1>Welcome</h1>
This page is:
<ul>
<li>Pre-rendered</li>
<li>Static html generated</li>
<li>Not interactive (no javascript is downloaded for this page)</li>
</ul>
<Counter />
</>
)
}

function Counter() {
const [count, setCount] = useState(0)
return (
<button type="button" onClick={() => setCount((count) => count + 1)}>
Counter {count}
</button>
)
}
10 changes: 10 additions & 0 deletions examples/hono-react-vercel-edge/pages/static/+config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// https://vike.dev/render-modes#html-only

export default {
prerender: true,
meta: {
Page: {
env: { server: true, client: false }
}
}
}
14 changes: 14 additions & 0 deletions examples/hono-react-vercel-edge/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Minimal example of using `vike-node` and `vike-react`.

```bash
git clone [email protected]:vikejs/vike-node
cd vike-node/examples/hono-react-vercel-edge/
npm install
npm run dev
```

## One-Click Deploy

Deploy the example using [Vercel](https://vercel.com):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vikejs/vike-node/tree/main/examples/hono-react-vercel-edge&project-name=hono-react&repository-name=hono-react)
21 changes: 21 additions & 0 deletions examples/hono-react-vercel-edge/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import vike from 'vike-node/hono'

export default startServer()

function startServer() {
const app = new Hono()
app.use(vike())
const port = process.env.PORT || 3000
serve(
{
fetch: app.fetch,
port: +port,
// Needed for Bun
overrideGlobalObjects: false
},
() => console.log(`Server running at http://localhost:${port}`)
)
return app.fetch
}
9 changes: 9 additions & 0 deletions examples/hono-react-vercel-edge/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"outputDirectory": "dist/client",
"rewrites": [
{
"source": "/((?!assets/).*)",
"destination": "/api"
}
]
}
7 changes: 7 additions & 0 deletions examples/hono-react-vercel-edge/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import react from '@vitejs/plugin-react'
import vike from 'vike/plugin'
import vikeNode from 'vike-node/plugin'

export default {
plugins: [react(), vike({ prerender: true }), vikeNode('server/index.js')]
}
3 changes: 1 addition & 2 deletions packages/vike-node/src/runtime/adapters/connectToWeb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ export { connectToWeb }

import type { IncomingMessage } from 'node:http'
import { Readable } from 'node:stream'
import type { ConnectMiddleware } from '../types.js'
import type { ConnectMiddleware, WebHandler } from '../types.js'
import { flattenHeaders } from '../utils/header-utils.js'
import { createServerResponse } from './createServerResponse.js'

/** Type definition for a web-compatible request handler */
type WebHandler = (request: Request) => Response | undefined | Promise<Response | undefined>

const statusCodesWithoutBody = [
100, // Continue
Expand Down
18 changes: 5 additions & 13 deletions packages/vike-node/src/runtime/frameworks/elysia.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
export { vike }

import { Elysia, NotFoundError } from 'elysia'
import { connectToWeb } from '../adapters/connectToWeb.js'
import { createHandler } from '../handler.js'
import { Context, Elysia, NotFoundError } from 'elysia'
import { createHandler } from '../handler-web.js'
import type { VikeOptions } from '../types.js'

/**
* Creates an Elysia plugin to handle Vike requests.
*
* @param {VikeOptions<Request>} [options] - Configuration options for Vike.
* @param {VikeOptions<Context>} [options] - Configuration options for Vike.
*
* @returns {Elysia} An Elysia plugin that handles all GET requests and processes them with Vike.
*
Expand All @@ -29,19 +28,12 @@ import type { VikeOptions } from '../types.js'
*
* @throws {NotFoundError} Thrown when Vike doesn't handle the request, allowing Elysia to manage 404 responses.
*/
function vike(options?: VikeOptions<Request>): Elysia {
function vike(options?: VikeOptions<Context>): Elysia {
const handler = createHandler(options)
return new Elysia({
name: 'vike-node:elysia'
}).get('*', async (ctx) => {
const response = await connectToWeb((req, res, next) =>
handler({
req,
res,
next,
platformRequest: ctx.request
})
)(ctx.request)
const response = await handler({ request: ctx.request, platformRequest: ctx })

if (response) {
return response
Expand Down
28 changes: 13 additions & 15 deletions packages/vike-node/src/runtime/frameworks/hono.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
export { vike }

import type { HonoRequest, MiddlewareHandler } from 'hono'
import type { IncomingMessage, ServerResponse } from 'http'
import { connectToWeb } from '../adapters/connectToWeb.js'
import type { Context, MiddlewareHandler } from 'hono'
import type { IncomingMessage } from 'http'
import { globalStore } from '../globalStore.js'
import { createHandler } from '../handler.js'
import { createHandler } from '../handler-web.js'
import type { VikeOptions } from '../types.js'

/**
Expand Down Expand Up @@ -33,19 +32,18 @@ import type { VikeOptions } from '../types.js'
* ```
*
*/
function vike(options?: VikeOptions<HonoRequest>): MiddlewareHandler {
function vike(options?: VikeOptions<Context>): MiddlewareHandler {
const handler = createHandler(options)
return async function middleware(ctx, next) {
const req = ctx.env.incoming as IncomingMessage
globalStore.setupHMRProxy(req)
const response = await connectToWeb((req, res, next) =>
handler({
req,
res,
next,
platformRequest: ctx.req
})
)(ctx.req.raw)
if (ctx.env.incoming) {
const req = ctx.env.incoming as IncomingMessage
globalStore.setupHMRProxy(req)
}

const response = await handler({
request: ctx.req.raw,
platformRequest: ctx
})

if (response) {
return response
Expand Down
Loading

0 comments on commit 022aa1c

Please sign in to comment.