Skip to content

Bun ​

Bun 是另一款 JavaScript 运行时,它不是 Node.js,也不是 Deno。Bun 内置转译器,可以直接编写 TypeScript 代码,Hono 也能运行在 Bun 上。

1. 安装 Bun ​

请根据官方网站中的说明安装 bun 命令。

2. 环境准备 ​

2.1 创建新项目 ​

Bun 提供了对应的启动模板,可以通过 bun create 命令初始化项目。本示例选择 bun 模板。

sh
bun create hono@latest 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

然后在浏览器访问 http://localhost: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 ​

如果需要将 http://localhost: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 中可以使用 bun:test 编写测试。

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

然后执行:

sh
bun test index.test.ts

Released under the MIT License.