Node.js
Node.js 是一个开源、跨平台的 JavaScript 运行时环境。
Hono 最初并未专为 Node.js 设计,但借助 Node.js 适配器 也可以在 Node.js 上运行。
INFO
适配器支持 Node.js 18.x 及以上版本,具体要求如下:
- 18.x => 18.14.1+
- 19.x => 19.7.0+
- 20.x => 20.0.0+
总体而言,建议直接使用各大版本的最新版本。
1. 环境准备
Node.js 提供启动模板,可通过 create-hono 命令初始化项目。本示例选择 nodejs 模板。
sh
npm create hono@latest my-appsh
yarn create hono my-appsh
pnpm create hono my-appsh
bun create hono@latest my-appsh
deno init --npm hono my-app进入 my-app 并安装依赖:
sh
cd my-app
npm ish
cd my-app
yarnsh
cd my-app
pnpm ish
cd my-app
bun i2. Hello World
编辑 src/index.ts:
ts
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node.js!'))
serve(app)如果需要优雅地关闭服务,可写成:
ts
const server = serve(app)
// graceful shutdown
process.on('SIGINT', () => {
server.close()
process.exit(0)
})
process.on('SIGTERM', () => {
server.close((err) => {
if (err) {
console.error(err)
process.exit(1)
}
process.exit(0)
})
})3. 运行
在本地启动开发服务器,并访问 http://localhost:3000。
sh
npm run devsh
yarn devsh
pnpm dev修改端口
可以通过 port 选项指定端口:
ts
serve({
fetch: app.fetch,
port: 8787,
})访问原生 Node.js API
可以通过 c.env.incoming 与 c.env.outgoing 获取 Node.js 原生对象:
ts
import { Hono } from 'hono'
import { serve, type HttpBindings } from '@hono/node-server'
// 如果使用 HTTP/2,请改用 Http2Bindings
type Bindings = HttpBindings & {
/* ... */
}
const app = new Hono<{ Bindings: Bindings }>()
app.get('/', (c) => {
return c.json({
remoteAddress: c.env.incoming.socket.remoteAddress,
})
})
serve(app)提供静态文件
可以使用 serveStatic 从本地文件系统提供静态资源。假设目录结构如下:
./
├── favicon.ico
├── index.ts
└── static
├── hello.txt
└── image.png若想让 /static/* 路径对应 ./static 下的文件,可编写:
ts
import { serveStatic } from '@hono/node-server/serve-static'
app.use('/static/*', serveStatic({ root: './' }))若要提供根目录的 favicon.ico,可使用 path 选项:
ts
app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))若希望 /hello.txt 或 /image.png 映射到 ./static/hello.txt、./static/image.png,可以:
ts
app.use('*', serveStatic({ root: './static' }))rewriteRequestPath
如果需要将 http://localhost:3000/static/* 映射到 ./statics,可以启用 rewriteRequestPath:
ts
app.get(
'/static/*',
serveStatic({
root: './',
rewriteRequestPath: (path) =>
path.replace(/^\/static/, '/statics'),
})
)HTTP/2
Hono 也可以运行在 Node.js http2 服务器 上。
未加密的 HTTP/2
ts
import { createServer } from 'node:http2'
const server = serve({
fetch: app.fetch,
createServer,
})加密的 HTTP/2
ts
import { createSecureServer } from 'node:http2'
import { readFileSync } from 'node:fs'
const server = serve({
fetch: app.fetch,
createServer: createSecureServer,
serverOptions: {
key: readFileSync('localhost-privkey.pem'),
cert: readFileSync('localhost-cert.pem'),
},
})构建与部署
Dockerfile
以下是示例 Node.js Dockerfile:
Dockerfile
FROM node:22-alpine AS base
FROM base AS builder
RUN apk add --no-cache gcompat
WORKDIR /app
COPY package*json tsconfig.json src ./
RUN npm ci && \
npm run build && \
npm prune --production
FROM base AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 hono
COPY --from=builder --chown=hono:nodejs /app/node_modules /app/node_modules
COPY --from=builder --chown=hono:nodejs /app/dist /app/dist
COPY --from=builder --chown=hono:nodejs /app/package.json /app/package.json
USER hono
EXPOSE 3000
CMD ["node", "/app/dist/index.js"]