Skip to content

Commit d644460

Browse files
committed
dev ssr
1 parent e734563 commit d644460

File tree

17 files changed

+149
-11
lines changed

17 files changed

+149
-11
lines changed

packages/core/build.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const builds = [
3030
{ entryPoints: ['src/index.ts'], format: 'cjs', outfile: 'dist/index.js', platform: 'browser' },
3131
{ entryPoints: ['src/server.ts'], format: 'esm', outfile: 'dist/server.esm.js', platform: 'node' },
3232
{ entryPoints: ['src/server.ts'], format: 'cjs', outfile: 'dist/server.js', platform: 'node' },
33+
{ entryPoints: ['src/vite.ts'], format: 'esm', outfile: 'dist/vite.js', platform: 'node' },
3334
]
3435

3536
builds.forEach(async (build) => {

packages/core/package.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
"types": "./types/server.d.ts",
3535
"import": "./dist/server.esm.js",
3636
"require": "./dist/server.js"
37+
},
38+
"./vite": {
39+
"types": "./types/vite.d.ts",
40+
"default": "./dist/vite.js"
3741
}
3842
},
3943
"typesVersions": {
@@ -54,13 +58,22 @@
5458
"es-toolkit": "^1.34.1",
5559
"qs": "^6.9.0"
5660
},
61+
"peerDependencies": {
62+
"vite": "^6.0.0"
63+
},
64+
"peerDependenciesMeta": {
65+
"vite": {
66+
"optional": true
67+
}
68+
},
5769
"devDependencies": {
5870
"@types/deepmerge": "^2.2.0",
5971
"@types/node": "^18.4",
6072
"@types/nprogress": "^0.2.0",
6173
"@types/qs": "^6.9.0",
6274
"esbuild": "^0.25.0",
6375
"esbuild-node-externals": "^1.6.0",
64-
"typescript": "^4.9.4"
76+
"typescript": "^4.9.4",
77+
"vite": "^5.4.8"
6578
}
6679
}

packages/core/src/server.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,18 @@ import { createServer, IncomingMessage } from 'http'
22
import cluster from 'node:cluster'
33
import { availableParallelism } from 'node:os'
44
import * as process from 'process'
5-
import { InertiaAppResponse, Page } from './types'
5+
import { readableToString } from './serverUtils'
6+
import type { InertiaAppResponse, Page } from './types'
7+
8+
export type AppCallback = (page: Page) => InertiaAppResponse
69

7-
type AppCallback = (page: Page) => InertiaAppResponse
810
type RouteHandler = (request: IncomingMessage) => Promise<unknown>
911
type ServerOptions = {
1012
port?: number
1113
cluster?: boolean
1214
}
1315
type Port = number
1416

15-
const readableToString: (readable: IncomingMessage) => Promise<string> = (readable) =>
16-
new Promise((resolve, reject) => {
17-
let data = ''
18-
readable.on('data', (chunk) => (data += chunk))
19-
readable.on('end', () => resolve(data))
20-
readable.on('error', (err) => reject(err))
21-
})
22-
2317
export default (render: AppCallback, options?: Port | ServerOptions): void => {
2418
const _port = typeof options === 'number' ? options : (options?.port ?? 13714)
2519
const _useCluster = typeof options === 'object' && options?.cluster !== undefined ? options.cluster : false

packages/core/src/serverUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { IncomingMessage } from 'http'
2+
3+
export const readableToString: (readable: IncomingMessage) => Promise<string> = (readable) =>
4+
new Promise((resolve, reject) => {
5+
let data = ''
6+
readable.on('data', (chunk) => (data += chunk))
7+
readable.on('end', () => resolve(data))
8+
readable.on('error', (err) => reject(err))
9+
})

packages/core/src/vite.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { Plugin } from 'vite'
2+
import { readableToString } from './serverUtils'
3+
4+
interface PluginConfig {
5+
renderer: string
6+
}
7+
8+
export default function inertia(config: string | PluginConfig): Plugin {
9+
const resolvedConfig = resolveConfig(config)
10+
11+
return {
12+
name: '@inertiajs/core/vite',
13+
async configureServer(server) {
14+
return () =>
15+
server.middlewares.use(async (req, res, next) => {
16+
if (req.url !== '/render') {
17+
next()
18+
}
19+
20+
const { default: render } = await server.ssrLoadModule(resolvedConfig.renderer)
21+
const response = await render(JSON.parse(await readableToString(req)))
22+
res.writeHead(200, { 'Content-Type': 'application/json' })
23+
res.end(JSON.stringify(response))
24+
})
25+
},
26+
}
27+
}
28+
29+
function resolveConfig(config: string | PluginConfig) {
30+
if (typeof config === 'undefined') {
31+
throw new Error('@inertiajs/core/vite: missing configuration.')
32+
}
33+
34+
if (typeof config === 'string') {
35+
return { renderer: config }
36+
}
37+
38+
if (typeof config.renderer === 'undefined') {
39+
throw new Error('@inertiajs/core/vite: missing configuration for "renderer".')
40+
}
41+
42+
return config
43+
}

packages/react/src/server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
export * from '@inertiajs/core/server'
12
export { default as default } from '@inertiajs/core/server'

packages/svelte/src/server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
export * from '@inertiajs/core/server'
12
export { default as default } from '@inertiajs/core/server'

packages/vue3/src/server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
export * from '@inertiajs/core/server'
12
export { default as default } from '@inertiajs/core/server'
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { createInertiaApp } from '@inertiajs/react'
2+
import type { AppCallback } from '@inertiajs/react/server'
3+
import * as ReactDOMServer from 'react-dom/server'
4+
5+
const render: AppCallback = (page) =>
6+
createInertiaApp({
7+
page,
8+
render: ReactDOMServer.renderToString,
9+
title: (title) => `${title} - React Playground`,
10+
resolve: (name) => import(`./Pages/${name}.tsx`),
11+
setup: ({ App, props }) => <App {...props} />,
12+
})
13+
14+
export default render

playgrounds/react/vite.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import inertia from '@inertiajs/core/vite'
12
import tailwindcss from '@tailwindcss/vite'
23
import react from '@vitejs/plugin-react'
34
import laravel from 'laravel-vite-plugin'
@@ -13,6 +14,7 @@ export default defineConfig({
1314
ssr: 'resources/js/ssr.tsx',
1415
refresh: true,
1516
}),
17+
inertia('resources/js/viteSsr.tsx'),
1618
react(),
1719
tailwindcss(),
1820
],

0 commit comments

Comments
 (0)