koa-web-app / api /app.ts
3v324v23's picture
chore: minor code optimization for SPA routing
111d66b
import Koa from 'koa'
import bodyParser from 'koa-bodyparser'
import logger from 'koa-logger'
import cors from '@koa/cors'
import serve from 'koa-static'
import path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'
import systemRouter from './routes/system.js'
import dataRouter from './routes/data.js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const app = new Koa()
// 中间件配置
app.use(cors())
app.use(logger())
app.use(bodyParser({
jsonLimit: '10mb',
formLimit: '10mb'
}))
// 错误处理
app.use(async (ctx, next) => {
try {
await next()
} catch (err: unknown) {
const error = err as { status?: number; message?: string }
ctx.status = error.status || 500
ctx.body = {
success: false,
error: error.message || '服务器内部错误'
}
ctx.app.emit('error', err, ctx)
}
})
// 路由注册
app.use(systemRouter.routes()).use(systemRouter.allowedMethods())
app.use(dataRouter.routes()).use(dataRouter.allowedMethods())
// 生产环境下托管静态文件
if (process.env.NODE_ENV === 'production') {
const distPath = path.resolve(__dirname, '../dist')
app.use(serve(distPath))
// 处理 SPA 路由
app.use(async (ctx, next) => {
if (ctx.status === 404 && !ctx.path.startsWith('/api')) {
ctx.type = 'html'
ctx.body = fs.readFileSync(path.join(distPath, 'index.html'))
} else {
await next()
}
})
}
// 404 处理
app.use(async (ctx) => {
if (ctx.status === 404) {
ctx.body = {
success: false,
error: '接口未找到'
}
}
})
export default app