跳至正文
Wener Notes

Hono

约 2 分钟阅读
    • Fast, Lightweight, Web-standards
    • 支持环境
      • Cloudflare Workers
      • Cloudflare Pages
      • Fastly Compute
      • Deno
      • Bun
      • Lagon
      • Vercel
      • AWS Lambda
      • Lambda@Edge
    • used by:
bash
npm add hono @hono/node-server @hono/zod-openapi @hono/trpc-server
npm add -D typescript @types/node vitest

# MISC
npm add dotenv @nestjs/common @wener/nestjs @wener/utils

# for Bun
npm add -D @types/bun

# for Dev
npm add -D ts-node esbuild @swc/cli

npm node --loader ts-node/esm --watch ./src/main.ts

# build
# =====================
# swc support decorate
pnpm swc ./src -d ./dist/out
# bundle all deps
pnpm esbuild ./dist/out/main.js --external:{http,fs,path,stream,crypto,os,node:\*} --define:process.env.NODE_ENV=\"production\" --bundle --format=esm --outdir=dist/app --minify-syntax --charset=utf8 --target=es2022,node20 --sourcemap=external --legal-comments=external

cat << EOF
FROM wener/node:20

WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nodejs

COPY rootfs /

RUN mkdir -p /app && chown -R nodejs:nodejs /app
USER nodejs
# for Native Addon
#RUN --mount=type=cache,target=/home/nodejs/.npm,uid=1001,gid=1001 \
#    npm i sharp pg mysql2 --platform=linuxmusl

COPY --chown=nodejs:nodejs dist/app/ /app/

CMD [ "node" , "--enable-source-maps", "main.mj" ]
EOF

echo '{"name": "server","type": "module"}' > dist/app/package.json
docker buildx build -t server --load --platform linux/amd64 .
依赖包
TypeScript
import { serve } from '@hono/node-server';
import { Hono } from 'hono';

const app = new Hono();
app.get('/', (c) => c.text('Hono meets Node.js'));

// for NodeJS
serve(app, (info) => {
  console.log(`Listening on http://localhost:${info.port}`); // Listening on http://localhost:3000
});
TypeScript
// for tRPC

import { trpcServer } from '@hono/trpc-server';
import { appRouter } from './router';

const app = new Hono();

app.use(
  '/trpc/*',
  trpcServer({
    router: appRouter,
  }),
);

Notes

  • App - Hono
  • Routing
    • /posts/:id/comment/:comment_id
    • /api/animal/:type? - 可选
    • /post/:date{[0-9]+}/:title{[a-z]+} - 正则
    • /posts/:filename{.+\\.png$} - 包含 slash
    • *
    • /wild/*/card
  • /api/foo/* 这种方式无法获取 param('*'), 使用 /api/foo/:target{.+} 可以获取 param
TypeScript
const app = new Hono({
  // 处理带 Host
  getPath: (req) => req.url.replace(/^https?:\/(.+?)$/, '$1'),
});

app.get('/www1.example.com/hello', (c) => c.text('hello www1'));
app.get('/www2.example.com/hello', (c) => c.text('hello www2'));

html

  1. 配置 tsconfig
json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx"
  }
}
  1. 使用 pragma directive
TypeScript
/** @jsx jsx */
/** @jsxFrag Fragment */
import { jsx, Fragment } from 'hono/jsx';

FAQ

Hijack

  • 如果已经处理,则返回 RESPONSE_ALREADY_SENT
TypeScript
import { serve } from '@hono/node-server';
import type { HttpBindings } from '@hono/node-server';
import { RESPONSE_ALREADY_SENT } from '@hono/node-server/utils/response';
import { Hono } from 'hono';

const app = new Hono<{ Bindings: HttpBindings }>();

app.get('/', (c) => {
  const { outgoing } = c.env;
  outgoing.writeHead(200, { 'Content-Type': 'text/plain' });
  outgoing.end('Hello World\n');

  return RESPONSE_ALREADY_SENT;
});

OpenAPI Type Error

bash
pnpm add @asteasolutions/zod-to-openapi openapi3-ts

Nest Adaptor

关联信息

反向链接、本文链接的其他页面和外部资料。

反向链接

  • elysia
    笔记 · hono

    elysiajs/elysia · 基于 bun 的 Web 框架 · 使用 @sinclair/typebox · 代码量很少,逻辑简单 · AOT · 生成代码来进行 route · route 变成一个大 switch · 与 hono 非常相似,但面向 bun 为主

参考资料

GitHub5 条
其他外链3 条
最近更新commit affb38b编辑