Skip to content

Bun ​

Bun 是另一个 JavaScript 运行时。它不是 Node.js 也不是 Deno。Bun 包含一个转译器,因此我们可以使用 TypeScript 或普通 JavaScript 编写代码。 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

然后将 dev 命令添加到现有的 package.json 中。

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

查看 Bun 启动模板 以获取最小化设置示例。这是运行 bun create hono@latest 的输出。

3. 你好世界 ​

“Hello World” 脚本如下。几乎与在其他平台上编写的一样。

ts
import { Hono } from 'hono'

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

export default app

如果你是在现有项目中设置 Hono,bun run dev 命令期望将 “Hello World” 脚本放在 src/index.ts 中

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('你可以访问:/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} 未找到,你访问的是 ${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('我的第一个测试', () => {
  it('应返回 200 响应', async () => {
    const req = new Request('http://localhost/')
    const res = await app.fetch(req)
    expect(res.status).toBe(200)
  })
})

然后,运行命令。

sh
bun test index.test.ts