在 Bun 环境下使用 Next. Js 和 Elysia 创建一个复杂计算器是一个有趣的挑战。由于 Next. Js 主要是为 Node. Js 环境设计的,而 Elysia 是专为 Bun 优化的 web 框架,我们需要稍微调整一下方案。我们可以使用 Elysia 作为主要的后端框架,然后用 React 来处理前端渲染。这样我们就可以在 Bun 环境中充分利用 Elysia 的性能优势,同时保持类似 Next.Js 的 SSR 能力。
以下是一个实现方案:
- 后端 (Elysia):
创建一个 server.ts 文件:
import { Elysia } from 'elysia'
import { staticPlugin } from '@elysiajs/static'
import { html } from '@elysiajs/html'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { Calculator } from './components/Calculator'
const app = new Elysia()
.use(staticPlugin())
.use(html())
app.get('/', ({ html }) => {
const calculatorHtml = renderToString(React.createElement(Calculator))
return html(
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Complex Calculator</title>
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">${calculatorHtml}</div>
<script type="text/babel" src="/static/client.js"></script>
</body>
</html>`
)
})
app.post('/calculate', ({ body }) => {
const { operation, values } = body as { operation: string, values: number[] }
let result: number
switch (operation) {
case 'sin':
result = Math.sin(values[0])
break
case 'cos':
result = Math.cos(values[0])
break
case 'tan':
result = Math.tan(values[0])
break
case 'mean':
result = values.reduce((a, b) => a + b, 0) / values.length
break
case 'median':
const sorted = [...values].sort((a, b) => a - b)
const mid = Math.floor(sorted.length / 2)
result = sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2
break
default:
throw new Error('Invalid operation')
}
return { result }
})
app.listen(3000)
console.log('Server is running on http://localhost:3000')- 前端 (React):
创建一个 components/Calculator.tsx 文件:
import React, { useState } from 'react'
export const Calculator: React.FC = () => {
const [operation, setOperation] = useState('')
const [values, setValues] = useState('')
const [result, setResult] = useState<number | null>(null)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
const response = await fetch('/calculate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ operation, values: values.split(',').map(Number) }),
})
const data = await response.json()
setResult(data.result)
}
return (
<div>
<h1>Complex Calculator</h1>
<form onSubmit={handleSubmit}>
<select value={operation} onChange={(e) => setOperation(e.target.value)}>
<option value="">Select operation</option>
<option value="sin">Sin</option>
<option value="cos">Cos</option>
<option value="tan">Tan</option>
<option value="mean">Mean</option>
<option value="median">Median</option>
</select>
<input
type="text"
value={values}
onChange={(e) => setValues(e.target.value)}
placeholder="Enter values (comma-separated)"
/>
<button type="submit">Calculate</button>
</form>
{result !== null && <p>Result: {result}</p>}
</div>
)
}- 客户端脚本:
创建一个 static/client.js 文件:
ReactDOM.hydrate(
React.createElement(Calculator),
document.getElementById('root')
)- 项目设置:
创建一个 package.json 文件:
{
"name": "complex-calculator",
"version": "1.0.0",
"scripts": {
"start": "bun run server.ts"
},
"dependencies": {
"elysia": "latest",
"@elysiajs/static": "latest",
"@elysiajs/html": "latest",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11"
}
}- 运行应用:
bun install
bun start这个设置提供了一个在 Bun 环境中运行的复杂计算器,具有以下特点:
- 使用 Elysia 作为后端框架,处理路由和 API 请求。
- 使用 React 进行前端渲染,支持服务端渲染(SSR)。
- 提供三角函数(sin, cos, tan)和统计函数(mean, median)功能。
- 客户端水合(hydration)以实现交互性。
这个方案结合了 Elysia 的高性能和 React 的灵活性,同时保持了服务端渲染的能力。你可以根据需要进一步扩展功能,比如添加更多的数学运算,改进错误处理,或者优化用户界面。