Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Переменные окружения и bindings

Переменные окружения — настройки, которые передаются программе снаружи, а не пишутся в коде: порт, секретный ключ, путь к базе данных. Так один и тот же код работает с разными настройками на вашем компьютере и на сервере, а секреты не попадают в Git.

Файл .env

Создайте в корне проекта файл .env:

PORT=3000
JWT_SECRET=dev-secret-change-me
DB_FILE=blog.db

Добавьте его в .gitignore, если его там нет. Рядом удобно положить .env.example с теми же именами, но без настоящих значений — по нему другой разработчик поймёт, что нужно заполнить.

Загрузка в Node.js

Node.js 22 умеет читать такой файл сам, через флаг --env-file. Поменяйте скрипты в package.json:

{
  "scripts": {
    "dev": "tsx watch --env-file=.env src/index.ts",
    "build": "tsc",
    "start": "node --env-file=.env dist/index.js"
  }
}

После перезапуска npm run dev значения доступны через process.env:

// src/index.ts
const port = Number(process.env.PORT ?? 3000)
 
serve({ fetch: app.fetch, port })

Сервер запустится на порту из .env. Значение переменной всегда строка, поэтому порт переводится в число.

Функция env()

process.env есть только в Node.js. Чтобы код маршрутов работал на любой платформе, Hono предлагает функцию env():

// src/routes/admin.ts
import { Hono } from 'hono'
import { env } from 'hono/adapter'
 
const admin = new Hono()
 
admin.get('/config', (c) => {
  const { DB_FILE } = env<{ DB_FILE: string }>(c)
  return c.json({ database: DB_FILE })
})
 
export default admin

На Node.js env(c) читает process.env, на Cloudflare Workers — настройки воркера, на Deno — Deno.env. Тип в угловых скобках сообщает TypeScript, какие переменные ожидаются.

Bindings и c.env

На Cloudflare Workers переменные и подключённые сервисы — база D1, хранилище KV — называются bindings и приходят в c.env. Их тип указывают при создании приложения:

// src/index.ts
type Bindings = {
  JWT_SECRET: string
}
 
const app = new Hono<{ Bindings: Bindings }>()
 
app.get('/secret-length', (c) => c.text(String(c.env.JWT_SECRET.length)))

На Node.js в c.env лежат служебные объекты сервера, а не ваши переменные, поэтому в курсе используется process.env или env(c).

ПлатформаГде переменные
Node.jsprocess.env или env(c)
Bunprocess.env, Bun.env или env(c)
DenoDeno.env.get() или env(c)
Cloudflare Workersc.env или env(c)

Частая ошибка

Секрет читают в момент загрузки модуля и подставляют значение по умолчанию:

// src/auth.ts
export const secret = process.env.JWT_SECRET ?? 'secret'

Если на сервере забыть задать переменную, приложение молча запустится со слабым ключом secret. Для секретов значения по умолчанию быть не должно: проверьте переменную при старте и остановите программу с понятной ошибкой, если её нет.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.