Zum Inhalt springen

Bun ​

Bun ist eine weitere JavaScript-Laufzeitumgebung, die sich von Node.js und Deno unterscheidet. Bun enthält einen Transcompiler, sodass wir den Code in TypeScript oder gewöhnlichem JavaScript schreiben können. Hono funktioniert auch auf Bun.

1. Bun installieren ​

Um den Befehl bun zu installieren, folge der Anleitung auf der offiziellen Website.

2. Einrichtung ​

2.1. Ein neues Projekt einrichten ​

Für Bun steht eine Projektvorlage zur Verfügung. Starte dein Projekt mit dem Befehl „bun create“. Wähle für dieses Beispiel die Vorlage bun aus.

sh
bun create hono@latest my-app

Wechsle nach my-app und installiere die Abhängigkeiten.

sh
cd my-app
bun install

2.2. Ein vorhandenes Projekt einrichten ​

In einem vorhandenen Bun-Projekt müssen wir lediglich im Stammverzeichnis des Projekts die Abhängigkeit hono installieren:

sh
bun add hono

Füge anschließend den Befehl dev zu deiner bestehenden package.json hinzu.

json
{
  "scripts": {
    "dev": "bun run --hot src/index.ts"
  }
}

Die Bun-Projektvorlage zeigt eine minimale Beispielkonfiguration. Sie entspricht dem Ergebnis von bun create hono@latest.

3. Hello World ​

Unten findest du das „Hello World“-Skript. Es entspricht weitgehend dem Code auf anderen Plattformen.

ts
import { Hono } from 'hono'

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

export default app

Wenn du Hono in einem vorhandenen Projekt einrichtest, erwartet der Befehl bun run dev, dass das „Hello World“-Skript in src/index.ts liegt.

4. Ausführen ​

Führe den Befehl aus.

sh
bun run dev

Öffne anschließend http://localhost:3000 in deinem Browser.

Portnummer ändern ​

Du kannst die Portnummer angeben, indem du port exportierst.

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, 
} 

Statische Dateien ausliefern ​

Um statische Dateien auszuliefern, verwende serveStatic aus dem Paket @hono/bun.

sh
bun add @hono/bun
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' }))

Der obige Code funktioniert mit der folgenden Verzeichnisstruktur.

./
├── favicon.ico
├── src
└── static
    ├── demo
    │   └── index.html
    ├── fallback.txt
    ├── hello.txt
    └── images
        └── dinotocat.png

rewriteRequestPath ​

Wenn du http://localhost:3000/static/* auf ./statics abbilden möchtest, kannst du die Option rewriteRequestPath verwenden:

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

mimes ​

Mit mimes kannst du MIME-Typen hinzufügen:

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

onFound ​

Mit onFound kannst du festlegen, was passieren soll, wenn die angeforderte Datei gefunden wird:

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

onNotFound ​

Mit onNotFound kannst du festlegen, was passieren soll, wenn die angeforderte Datei nicht gefunden wird:

ts
app.get(
  '/static/*',
  serveStatic({
    onNotFound: (path, c) => {
      console.log(`${path} is not found, you access ${c.req.path}`)
    },
  })
)

precompressed ​

Die Option precompressed prüft, ob Dateien mit Erweiterungen wie .br oder .gz verfügbar sind, und liefert sie anhand des Headers Accept-Encoding aus. Dabei wird Brotli bevorzugt, gefolgt von Zstd und Gzip. Ist keine dieser Varianten verfügbar, wird die ursprüngliche Datei ausgeliefert.

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

Tests ​

Für Tests auf Bun kannst du bun:test verwenden.

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('http://localhost/')
    const res = await app.fetch(req)
    expect(res.status).toBe(200)
  })
})

Führe anschließend den Befehl aus.

sh
bun test index.test.ts

Veröffentlicht unter der MIT-Lizenz.