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/assert 的 assert 或 assertEquals。

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.