IP地址检测
视频播放器
输入关键词搜索
登录
hono配置动态路由

hono配置动态路由

2025-01-27
编程开发

文件夹结构

index.ts

import {serve} from '@hono/node-server'
import {Hono} from 'hono'
import * as fs from "node:fs";
import * as path from "node:path";
import {logger} from 'hono/logger'

async function traverseRoutesDir(dirPath: string, handler: (routePath: string) => Promise<void>) {
    for (let file of fs.readdirSync(dirPath)) {
        const filePath = path.join(dirPath, file);
        if (fs.statSync(filePath).isDirectory()) {
            await traverseRoutesDir(filePath, handler)
        } else {
            await handler(filePath)
        }
    }
}

async function startServer() {
    const app = new Hono()

    // 如果网址不是以/结尾,就加一下/
    app.use(async (c, next) => {
        const url = new URL(c.req.url);
        if (!url.pathname.endsWith('/')) {
            url.pathname = url.pathname + '/'
            return c.redirect(url.href, 308); // 308 - Permanent Redirect for POST
        }
        await next();
    });
    
    // hono官方还提供了很多中间件
    app.use('*', logger()); // https://hono.dev/docs/middleware/builtin/logger

    // 动态配置路由核心代码
    const routesPath = path.join(import.meta.dirname, 'routes');
    await traverseRoutesDir(routesPath, async (routePath) => {
        const url = routePath.replace(routesPath, '').slice(0, 0 - (routePath.split('/').pop() || '').length)
        const allowMethods = ["GET", "POST"]

        // routeModule的内容,包含了定义的HTTP方法
        // [Module: null prototype] {
        //   GET: [AsyncFunction: GET],
        //   POST: [AsyncFunction: POST]
        // }
        const routeModule = await import(routePath)

        for (let method in routeModule) {
            if (allowMethods.includes(method)) {
                console.log(`${url} - ${method}`);
                const handler = routeModule[method] as AsyncGeneratorFunction
                (app[method.toLowerCase() as keyof Hono] as Function)(url, handler)
            } else {
                console.error(`${url} - 不支持${method}方法`)
            }
        }
    })

    return app
}

const PORT = 3000

startServer().then((app) => {
    console.log(`Server is running on http://localhost:${PORT}`)
    serve({
        fetch: app.fetch,
        port: PORT
    })
})

route.ts

import type {Context} from "hono";

export async function GET(c: Context) {
    return c.text('Hello Hono!')
}

export async function POST(c: Context) {
    return c.text('Hello Hono!')
}
THE END
0/500
暂无评论
📢网站公告
欢迎来到这里
⚙️实用工具
html转pdfmarkdown编辑器
本站推荐:腾讯云服务器仅需2.3折 (点击直达)
用户协议
隐私政策
Build Time: 2025-02-06 16:15:33