Deno
Deno は V8 を基盤とする JavaScript ランタイムで、Node.js とは異なります。 Hono は Deno 上でも動作します。
Hono を使って TypeScript でコードを記述し、deno コマンドで実行して、「Deno Deploy」にデプロイできます。
1. Deno のインストール
まず、deno コマンドをインストールします。 公式ドキュメントを参照してください。
2. セットアップ
Deno 向けのスターターテンプレートがあります。 deno init コマンドでプロジェクトを開始します。
deno init --npm hono --template=deno my-appmy-app に移動します。Deno では Hono を明示的にインストールする必要はありません。
cd my-app3. Hello World
main.ts を編集します。
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Deno!'))
Deno.serve(app.fetch)4. 実行
開発サーバーをローカルで起動し、Web ブラウザーで http://localhost:8000 にアクセスします。
deno task startポート番号の変更
main.ts の Deno.serve の引数を変更すると、ポート番号を指定できます。
Deno.serve(app.fetch)
Deno.serve({ port: 8787 }, app.fetch) 静的ファイルの配信
静的ファイルを配信するには、@hono/deno パッケージの serveStatic を使います。
deno add jsr:@hono/denoimport { Hono } from 'hono'
import { serveStatic } from '@hono/deno'
const app = new Hono()
app.use('/static/*', serveStatic({ root: './' }))
app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))
app.get('/', (c) => c.text('You can access: /static/hello.txt'))
app.get('*', serveStatic({ path: './static/fallback.txt' }))
Deno.serve(app.fetch)上記のコードは、次のディレクトリ構成で動作します。
./
├── favicon.ico
├── index.ts
└── static
├── demo
│ └── index.html
├── fallback.txt
├── hello.txt
└── images
└── dinotocat.pngrewriteRequestPath
http://localhost:8000/static/* を ./statics に対応させるには、rewriteRequestPath オプションを使います。
app.get(
'/static/*',
serveStatic({
root: './',
rewriteRequestPath: (path) =>
path.replace(/^\/static/, '/statics'),
})
)mimes
mimes で MIME タイプを追加できます。
app.get(
'/static/*',
serveStatic({
mimes: {
m3u8: 'application/vnd.apple.mpegurl',
ts: 'video/mp2t',
},
})
)onFound
onFound で、リクエストされたファイルが見つかった場合の処理を指定できます。
app.get(
'/static/*',
serveStatic({
// ...
onFound: (_path, c) => {
c.header('Cache-Control', `public, immutable, max-age=31536000`)
},
})
)onNotFound
onNotFound で、リクエストされたファイルが見つからなかった場合の処理を指定できます。
app.get(
'/static/*',
serveStatic({
onNotFound: (path, c) => {
console.log(`${path} is not found, you access ${c.req.path}`)
},
})
)precompressed
precompressed オプションは、.br や .gz などの拡張子を持つファイルがあるかを確認し、Accept-Encoding ヘッダーに応じて配信します。Brotli、Zstd、Gzip の順に優先され、いずれもなければ元のファイルを配信します。
app.get(
'/static/*',
serveStatic({
precompressed: true,
})
)Deno Deploy
Deno Deploy は、クラウドで JavaScript と TypeScript のアプリケーションを実行するサーバーレスプラットフォームです。 GitHub デプロイなどの連携を通じて、アプリケーションをデプロイし実行するための管理基盤を提供します。
Hono は Deno Deploy 上でも動作します。公式ドキュメントを参照してください。
テスト
Deno 上でアプリケーションをテストするのは簡単です。 Deno.test でテストを記述し、@std/assert の assert や assertEquals を使えます。
deno add jsr:@std/assertimport { Hono } from 'hono'
import { assertEquals } from '@std/assert'
Deno.test('Hello World', async () => {
const app = new Hono()
app.get('/', (c) => c.text('Please test me'))
const res = await app.request('http://localhost/')
assertEquals(res.status, 200)
})続いて、次のコマンドを実行します。
deno test hello.tsnpm と JSR
Hono は npm と JSR(JavaScript Registry)の両方で提供されています。deno.json で npm:hono または jsr:@hono/hono を使えます。
{
"imports": {
"hono": "jsr:@hono/hono"
"hono": "npm:hono"
}
}ミドルウェアを使うには、インポートに Deno ディレクトリの構文を使う必要があります。
{
"imports": {
"hono/": "npm:/hono/"
}
}サードパーティのミドルウェアを使う場合、TypeScript の型を正しく推論するため、ミドルウェアと同じレジストリの Hono を使う必要がある場合があります。たとえば、npm のミドルウェアを使うなら、Hono も npm から使います。
{
"imports": {
"hono": "npm:hono",
"zod": "npm:zod",
"@hono/zod-validator": "npm:@hono/zod-validator"
}
}JSR でも多数のサードパーティのミドルウェアパッケージを提供しています。JSR のミドルウェアを使う場合は、Hono も JSR から使います。
{
"imports": {
"hono": "jsr:@hono/hono",
"zod": "npm:zod",
"@hono/zod-validator": "jsr:@hono/zod-validator"
}
}