跳转到正文

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. 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。

sh
deno add jsr:@hono/deno
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 中的 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

npm 和 JSR ​

Hono 同时发布在 npm 和 JSR(JavaScript Registry)上。可以在 deno.json 中使用 npm:hono 或 jsr:@hono/hono:

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

要使用中间件,需要在 import 中使用 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"
  }
}

基于 MIT 许可证发布。