45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import Elysia from 'elysia';
|
|
import { connect } from 'elysia-connect-middleware';
|
|
import { createElement } from 'react';
|
|
import { renderToReadableStream } from 'react-dom/server';
|
|
import { createServer } from 'vite';
|
|
import { App } from './src/App';
|
|
|
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
const base = process.env.BASE || '/';
|
|
|
|
let template = '';
|
|
if (!isProduction) {
|
|
const templateFile = Bun.file('index.html');
|
|
template = await templateFile.text();
|
|
}
|
|
|
|
const app = new Elysia();
|
|
const vite = await createServer({
|
|
server: { middlewareMode: true },
|
|
appType: 'custom',
|
|
});
|
|
app.use(connect(vite.middlewares));
|
|
app.get('/', async ({ request }) => {
|
|
const url = request.url.replace(base, '');
|
|
const app = createElement(App);
|
|
const rootComponent = await renderToReadableStream(app);
|
|
const rootComponentString = await Bun.readableStreamToText(rootComponent);
|
|
|
|
if (!isProduction) {
|
|
template = await vite.transformIndexHtml(url, template);
|
|
}
|
|
|
|
const html = template.replace(`<!--ssr-outlet-->`, () => rootComponentString);
|
|
|
|
return new Response(html, {
|
|
headers: {
|
|
'Content-Type': 'text/html',
|
|
},
|
|
});
|
|
});
|
|
|
|
app.listen(8000);
|
|
|
|
console.log(`Server running at http://${app.server?.hostname}:${app.server?.port}`);
|