跳至內容

Bun

Bun 是另一個 JavaScript 執行環境。它不是 Node.js 或 Deno。Bun 包含一個轉譯器,我們可以用 TypeScript 編寫程式碼。Hono 也可在 Bun 上運作。

1. 安裝 Bun

若要安裝 bun 命令,請依照官方網站上的指示進行。

2. 設定

2.1. 建立新專案

Bun 有可用的入門範本。使用 "bun create" 命令開始您的專案。在此範例中,請選擇 bun 範本。

sh
bun create hono my-app

移至 my-app 並安裝相依性。

sh
cd my-app
bun install

2.2. 設定現有專案

在現有的 Bun 專案中,我們只需要透過以下方式在專案根目錄中安裝 hono 相依性

sh
bun add hono

3. Hello World

「Hello World」腳本如下。幾乎與在其他平台上編寫相同。

ts
import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))

export default app

4. 執行

執行命令。

sh
bun run dev

然後,在您的瀏覽器中存取 https://127.0.0.1:3000

變更連接埠號碼

您可以使用匯出 port 來指定連接埠號碼。

ts
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

ts
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

如果您想要將 https://127.0.0.1:3000/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,
  })
)

測試

您可以使用 bun:test 在 Bun 上進行測試。

ts
import { describe, expect, it } from 'bun:test'
import app from '.'

describe('My first test', () => {
  it('Should return 200 Response', async () => {
    const req = new Request('https://127.0.0.1/')
    const res = await app.fetch(req)
    expect(res.status).toBe(200)
  })
})

然後,執行命令。

sh
bun test index.test.ts

以 MIT 授權發佈。