# Bindings 与环境变量

URL: https://caijiao.org/hono/03-typescript/02-bindings-env
Source: docs/hono/03-typescript/02-bindings-env.md
Description: 学习 Hono 中 Bindings 的类型声明方式，以及在 Cloudflare Workers 和 Node.js 中读取环境变量的差异。

Hono 的 `Bindings` 用来描述运行时提供给应用的环境变量和平台绑定。这个概念在 Cloudflare Workers 中尤其常见。

## Cloudflare Workers Bindings

在 Workers 中，环境变量、KV、D1、R2 等绑定都通过 `c.env` 访问：

```ts
import { Hono } from 'hono'

type Bindings = {
  API_TOKEN: string
  DB: D1Database
}

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

app.get('/config', (c) => {
  return c.json({
    hasToken: Boolean(c.env.API_TOKEN),
  })
})

app.get('/users', async (c) => {
  const result = await c.env.DB.prepare('SELECT id, name FROM users').all()
  return c.json(result.results)
})

export default app
```

`Bindings` 不会创建变量，它只是告诉 TypeScript 这些绑定应该存在。实际配置仍然要写在 `wrangler.jsonc` 或 Cloudflare 控制台中。

## wrangler 配置示例

```jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-hono-api",
  "main": "src/index.ts",
  "compatibility_date": "2026-09-29",
  "vars": {
    "API_TOKEN": "dev-token"
  },
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "my-db",
      "database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
  ]
}
```

本地开发时，敏感值应该放在 `.dev.vars`，不要提交到 Git：

```text
API_TOKEN=local-secret
```

## Node.js 环境变量

Node.js 项目通常从 `process.env` 读取环境变量：

```ts
const port = Number(process.env.PORT ?? '3000')
const jwtSecret = process.env.JWT_SECRET

if (!jwtSecret) {
  throw new Error('JWT_SECRET is required')
}
```

然后传给应用工厂：

```ts
import { Hono } from 'hono'

type AppOptions = {
  jwtSecret: string
}

export function createApp(options: AppOptions) {
  const app = new Hono()

  app.get('/health', (c) => {
    return c.json({ ok: true, auth: Boolean(options.jwtSecret) })
  })

  return app
}
```

入口：

```ts
import { serve } from '@hono/node-server'
import { createApp } from './app'

const app = createApp({
  jwtSecret: process.env.JWT_SECRET ?? '',
})

serve({
  fetch: app.fetch,
  port: Number(process.env.PORT ?? '3000'),
})
```

## 不同运行时的建议

| 场景 | 建议 |
| --- | --- |
| Cloudflare Workers | 使用 `c.env`，通过 `Bindings` 声明类型。 |
| Node.js | 在入口读取 `process.env`，整理为配置对象传入应用。 |
| 多运行时共享代码 | 把环境读取放到平台入口，业务路由只依赖显式传入的配置。 |

避免在所有业务函数里直接读取环境变量。集中读取和校验配置，更容易测试和迁移。
