在 Bun 环境下使用 Next. Js 和 Elysia 创建一个复杂计算器是一个有趣的挑战。由于 Next. Js 主要是为 Node. Js 环境设计的,而 Elysia 是专为 Bun 优化的 web 框架,我们需要稍微调整一下方案。我们可以使用 Elysia 作为主要的后端框架,然后用 React 来处理前端渲染。这样我们就可以在 Bun 环境中充分利用 Elysia 的性能优势,同时保持类似 Next.Js 的 SSR 能力。

以下是一个实现方案:

  1. 后端 (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')
  1. 前端 (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>
  )
}
  1. 客户端脚本:

创建一个 static/client.js 文件:

ReactDOM.hydrate(
  React.createElement(Calculator),
  document.getElementById('root')
)
  1. 项目设置:

创建一个 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"
  }
}
  1. 运行应用:
bun install
bun start

这个设置提供了一个在 Bun 环境中运行的复杂计算器,具有以下特点:

  1. 使用 Elysia 作为后端框架,处理路由和 API 请求。
  2. 使用 React 进行前端渲染,支持服务端渲染(SSR)。
  3. 提供三角函数(sin, cos, tan)和统计函数(mean, median)功能。
  4. 客户端水合(hydration)以实现交互性。

这个方案结合了 Elysia 的高性能和 React 的灵活性,同时保持了服务端渲染的能力。你可以根据需要进一步扩展功能,比如添加更多的数学运算,改进错误处理,或者优化用户界面。