Skip to content

Deno

Deno 是一个基于 V8 构建的 JavaScript 运行时。它不是 Node.js。 Hono 也可以在 Deno 上运行。

你可以使用 Hono,用 TypeScript 编写代码,使用 deno 命令运行应用程序,并将其部署到 "Deno Deploy"。

1. 安装 Deno

首先,安装 deno 命令。 请参考 官方文档

2. 设置

Deno 有一个入门模板可用。 使用 deno init 命令开始你的项目。

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

进入 my-app。对于 Deno,你不需要显式安装 Hono。

sh
cd my-app

3. 你好世界

编辑 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. 运行

在本地运行开发服务器。然后,在 Web 浏览器中访问 http://localhost:8000

sh
deno task start

更改端口号

你可以通过更新 main.tsDeno.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 应用程序的无服务器平台。 它提供了一个管理平面,支持通过 GitHub 部署等集成来部署和运行应用程序。

Hono 也可以在 Deno Deploy 上运行。请参考 官方文档

测试

在 Deno 上测试应用程序很简单。 你可以使用 Deno.test 编写测试,并使用 @std/assert 中的 assertassertEquals

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

npm 和 JSR

Hono 在 npmJSR(JavaScript Registry)上均可用。你可以在 deno.json 中使用 npm:honojsr:@hono/hono

json
{
  "imports": {
    "hono": "jsr:@hono/hono"
    "hono": "npm:hono"
  }
}

要使用中间件,你需要在导入中使用 Deno 目录 语法。

json
{
  "imports": {
    "hono/": "npm:/hono/"
  }
}

使用第三方中间件时,为了正确的 TypeScript 类型推断,你可能需要使用与中间件相同注册表的 Hono。例如,如果使用来自 npm 的中间件,你也应该使用来自 npm 的 Hono:

json
{
  "imports": {
    "hono": "npm:hono",
    "zod": "npm:zod",
    "@hono/zod-validator": "npm:@hono/zod-validator"
  }
}

我们在 JSR 上也提供了许多第三方中间件包。当使用 JSR 上的中间件时,请使用来自 JSR 的 Hono:

json
{
  "imports": {
    "hono": "jsr:@hono/hono",
    "zod": "npm:zod",
    "@hono/zod-validator": "jsr:@hono/zod-validator"
  }
}