Skip to content

Deno

Deno 是基于 V8 构建的 JavaScript 运行时,与 Node.js 不同。Hono 也能运行在 Deno 上。

你可以使用 TypeScript 编写 Hono 应用,借助 deno 命令运行,并部署到 Deno Deploy。

1. 安装 Deno

首先安装 deno 命令,具体方法请参考官方文档

2. 环境准备

Deno 提供了启动模板,可使用 deno init 命令创建项目:

sh
deno init --npm hono my-app --template=deno

进入 my-app 目录。Deno 会按需拉取依赖,无需显式安装 Hono。

sh
cd my-app

3. Hello World

编辑 main.ts

main.ts
ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno!'))

Deno.serve(app.fetch)

4. 运行

在本地启动开发服务器,然后访问 http://localhost:8000

sh
deno task start

修改端口

可以在 main.ts 中通过 Deno.serve 指定端口:

ts
Deno.serve(app.fetch) 
Deno.serve({ port: 8787 }, app.fetch) 

提供静态文件

hono/deno 引入 serveStatic 即可提供静态文件:

ts
import { Hono } from 'hono'
import { serveStatic } from 'hono/deno'

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

Deno.serve(app.fetch)

上述代码可搭配以下目录结构使用:

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

rewriteRequestPath

若需将 http://localhost:8000/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,
  })
)

Deno Deploy

Deno Deploy 是面向 JavaScript/TypeScript 应用的 Serverless 平台,支持 GitHub 等集成方式快速部署。Hono 同样适用于 Deno Deploy,详情请参见官方文档

测试

在 Deno 中测试非常简单,可以使用 Deno.test 搭配 @std/assertassertassertEquals

sh
deno add jsr:@std/assert
hello.ts
ts
import { Hono } from 'hono'
import { assertEquals } from '@std/assert'

Deno.test('Hello World', async () => {
  const app = new Hono()
  app.get('/', (c) => c.text('Please test me'))

  const res = await app.request('http://localhost/')
  assertEquals(res.status, 200)
})

执行以下命令运行测试:

sh
deno test hello.ts

Released under the MIT License.