コンテンツへスキップ

Deno

Deno は V8 上に構築された JavaScript ランタイムです。Node.js ではありません。Hono は Deno でも動作します。

Hono を使用し、TypeScript でコードを記述し、deno コマンドでアプリケーションを実行し、「Deno Deploy」にデプロイすることができます。

1. Deno のインストール

まず、deno コマンドをインストールします。詳しくは公式ドキュメントを参照してください。

2. セットアップ

Deno 用のスターターが用意されています。「create-hono」コマンドでプロジェクトを開始します。

sh
deno run -A npm:create-hono my-app

この例では、deno テンプレートを選択してください。

my-app に移動します。Deno の場合、Hono を明示的にインストールする必要はありません。

sh
cd my-app

3. Hello World

最初のアプリケーションを記述します。

ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno!'))

Deno.serve(app.fetch)

4. 実行

このコマンドだけで実行できます

sh
deno task start

ポート番号の変更

main.tsDeno.serve の引数を更新することで、ポート番号を指定できます。

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

静的ファイルの配信

静的ファイルを配信するには、hono/middleware.ts からインポートされた serveStatic を使用します。

ts
import { 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.png

rewriteRequestPath

http://localhost:8000/static/*./statics にマッピングする場合は、rewriteRequestPath オプションを使用できます。

ts
app.get(
  '/static/*',
  serveStatic({
    root: './',
    rewriteRequestPath: (path) =>
      path.replace(/^\/static/, '/statics'),
  })
)

mimes

mimes を使用して MIME タイプを追加できます。

ts
app.get(
  '/static/*',
  serveStatic({
    mimes: {
      m3u8: 'application/vnd.apple.mpegurl',
      ts: 'video/mp2t',
    },
  })
)

onFound

リクエストされたファイルが見つかった場合の処理を onFound で指定できます。

ts
app.get(
  '/static/*',
  serveStatic({
    // ...
    onFound: (_path, c) => {
      c.header('Cache-Control', `public, immutable, max-age=31536000`)
    },
  })
)

onNotFound

リクエストされたファイルが見つからなかった場合の処理を onNotFound で指定できます。

ts
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 を優先します。利用可能なものがない場合は、元のファイルを提供します。

ts
app.get(
  '/static/*',
  serveStatic({
    precompressed: true,
  })
)

Deno Deploy

Deno Deploy は、Deno 用のエッジランタイムプラットフォームです。Deno Deploy でアプリケーションを世界中に公開できます。

Hono は Deno Deploy もサポートしています。公式ドキュメントを参照してください。

テスト

Deno でのアプリケーションのテストは簡単です。Deno.test で記述し、@std/assert から assert または assertEquals を使用できます。

sh
deno add @std/assert
ts
import { 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)
})

次に、次のコマンドを実行します。

sh
deno test hello.ts

npm: 指定子

npm:hono も利用可能です。deno.json を修正することで使用できます。

json
{
  "imports": {
    "hono": "jsr:@hono/hono"
    "hono": "npm:hono"
  }
}

npm:hono または jsr:@hono/hono のどちらかを使用できます。

TypeScript の型推論で npm:@hono/zod-validator などのサードパーティミドルウェアを使用する場合は、npm: 指定子を使用する必要があります。

json
{
  "imports": {
    "hono": "npm:hono",
    "zod": "npm:zod",
    "@hono/zod-validator": "npm:@hono/zod-validator"
  }
}

MITライセンスでリリースされています。