Bun
Bun 是另一种 JavaScript 运行时,区别于 Node.js 和 Deno。Bun 内置转译器,因此可以使用 TypeScript 或普通 JavaScript 编写代码。 Hono 也能在 Bun 上运行。
1. 安装 Bun
要安装 bun 命令,请按照官方网站上的说明操作。
2. 初始化
2.1. 初始化新项目
Bun 有可用的项目模板。使用「bun create」命令开始创建项目。 本示例选择 bun 模板。
bun create hono@latest my-app进入 my-app 并安装依赖。
cd my-app
bun install2.2. 配置现有项目
对于现有的 Bun 项目,只需在项目根目录下执行以下命令安装 hono 依赖:
bun add hono然后在现有的 package.json 中添加 dev 命令。
{
"scripts": {
"dev": "bun run --hot src/index.ts"
}
}最小配置示例可参见 Bun 项目模板。这是运行 bun create hono@latest 后生成的内容。
3. Hello World
下面是「Hello World」脚本,与其他平台上的写法基本相同。
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. 运行
运行以下命令。
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。
bun add @hono/bunimport { 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.pngrewriteRequestPath
如果要将 http://localhost:3000/static/* 映射到 ./statics,可以使用 rewriteRequestPath 选项:
app.get(
'/static/*',
serveStatic({
root: './',
rewriteRequestPath: (path) =>
path.replace(/^\/static/, '/statics'),
})
)mimes
可以使用 mimes 添加 MIME 类型:
app.get(
'/static/*',
serveStatic({
mimes: {
m3u8: 'application/vnd.apple.mpegurl',
ts: 'video/mp2t',
},
})
)onFound
可以使用 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
precompressed 选项会检查是否存在扩展名为 .br 或 .gz 等的文件,并根据 Accept-Encoding 标头提供相应文件。优先顺序是 Brotli、Zstd、Gzip。如果都不存在,则提供原始文件。
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