Bun
Bun はもう一つの JavaScript ランタイムです。 Node.js でも Deno でもありません。 Bun はトランスコンパイラが内蔵されており、 TypeScript でコードを書くことが出来ます。 Hono はもちろん Bun でも動作します。
1. Bun のインストール
bun
コマンドをインストールするために公式サイトを確認してください。
2. セットアップ
2.1. Setup a new project
スターターは Bun でも使用できます。 "bun create" コマンドでプロジェクトを作成してください。 選択肢は bun
を選んでください。
bun create hono my-app
my-app
に移動し、依存関係をインストールします。
cd my-app
bun install
2.2. Setup an existing project
On an existing Bun project, we only need to install hono
dependencies on the project root directory via
bun add hono
3. Hello World
"Hello World" スクリプトは以下の通りです。 他のプラットフォームと良く似ていますね。
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))
export default app
4. Run
以下のコマンドを実行します。
bun run dev
次に、ブラウザで http://localhost:3000
へアクセスします。
ポートを変える
エクスポート時に port
を指定できます。
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))
export default app
export default {
port: 3000,
fetch: app.fetch,
}
静的ファイルの提供
静的ファイルを提供するために hono/bun
から serveStatic
をインポートして使用してください、
import { serveStatic } from 'hono/bun'
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' }))
上のコードはこのようなディレクトリ構成で機能します。
./
├── favicon.ico
├── src
└── static
├── demo
│ └── index.html
├── fallback.txt
├── hello.txt
└── images
└── dinotocat.png
rewriteRequestPath
http://localhost:3000/static/*
を ./statics
にマップしたい場合、 rewriteRequestPath
オプションを使用できます:
app.get(
'/static/*',
serveStatic({
root: './',
rewriteRequestPath: (path) =>
path.replace(/^\/static/, '/statics'),
})
)
mimes
MIME タイプを mimes
で追加できます:
app.get(
'/static/*',
serveStatic({
mimes: {
m3u8: 'application/vnd.apple.mpegurl',
ts: 'video/mp2t',
},
})
)
onFound
You can specify handling when the requested file is found with 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
The precompressed
option checks if files with extensions like .br
or .gz
are available and serves them based on the Accept-Encoding
header. It prioritizes Brotli, then Zstd, and Gzip. If none are available, it serves the original file.
app.get(
'/static/*',
serveStatic({
precompressed: true,
})
)
テスト
bun:test
を使用し、 Bun でテストできます。
import { describe, expect, it } from 'bun:test'
import app from '.'
describe('My first test', () => {
it('Should return 200 Response', async () => {
const req = new Request('http://localhost/')
const res = await app.fetch(req)
expect(res.status).toBe(200)
})
})
次に、このコマンドを実行します。
bun test index.test.ts