Skip to content

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-app
sh
yarn create hono my-app
sh
pnpm create hono my-app
sh
bun create hono@latest my-app
sh
deno init --npm hono my-app

进入 my-app 目录并安装依赖。

sh
cd my-app
npm i
sh
cd my-app
yarn
sh
cd my-app
pnpm i
sh
cd my-app
bun i

2. 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)

3. 运行

在本地运行开发服务器。然后在浏览器中访问 http://localhost:3000

sh
npm run dev
sh
yarn dev
sh
pnpm dev

修改端口号

你可以通过 port 选项指定端口号。

ts
serve({
  fetch: app.fetch,
  port: 8787,
})

访问原生 Node.js API

你可以通过 c.env.incomingc.env.outgoing 访问 Node.js API。

ts
import { Hono } from 'hono'
import { serve, type HttpBindings } from '@hono/node-server'
// 如果使用 HTTP2,则使用 `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 从本地文件系统提供静态文件服务。例如,假设目录结构如下:

sh
./
├── 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: './' }))

使用 path 选项来提供根目录下的 favicon.ico

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'),
  })
)

http2

你可以在 Node.js http2 服务器 上运行 Hono。

非加密 http2

ts
import { createServer } from 'node:http2'

const server = serve({
  fetch: app.fetch,
  createServer,
})

加密 http2

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

以下是 Dockerfile 的示例。

Dockerfile
FROM node:20-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"]

使用前需要进行以下准备工作:

  1. tsconfig.jsoncompilerOptions 部分添加 "outDir": "./dist"
  2. tsconfig.json 中添加 "exclude": ["node_modules"]
  3. package.jsonscript 部分添加 "build": "tsc"
  4. 运行 npm install typescript --save-dev
  5. package.json 中添加 "type": "module"

Released under the MIT License.