Factory 助手
Factory 助手提供了一些便捷函数,用于创建 Hono 的组件(例如中间件)。在某些场景下手动设置合适的 TypeScript 类型比较麻烦,该助手可以简化操作。
导入
ts
import { Hono } from 'hono'
import { createFactory, createMiddleware } from 'hono/factory'createFactory()
createFactory() 会创建一个 Factory 类的实例。
ts
import { createFactory } from 'hono/factory'
const factory = createFactory()你可以通过泛型参数传入自定义的 Env 类型:
ts
type Env = {
Variables: {
foo: string
}
}
const factory = createFactory<Env>()配置项
optional defaultAppOptions: HonoOptions
createApp() 创建 Hono 应用时所使用的默认配置。
ts
const factory = createFactory({
defaultAppOptions: { strict: false },
})
const app = factory.createApp() // 会应用 `strict: false`createMiddleware()
createMiddleware() 是 factory.createMiddleware() 的简化用法,用于创建自定义中间件。
ts
const messageMiddleware = createMiddleware(async (c, next) => {
await next()
c.res.headers.set('X-Message', 'Good morning!')
})提示:若需要传入类似 message 的参数,可以将其封装成函数。
ts
const messageMiddleware = (message: string) => {
return createMiddleware(async (c, next) => {
await next()
c.res.headers.set('X-Message', message)
})
}
app.use(messageMiddleware('Good evening!'))factory.createHandlers()
createHandlers() 可以让你在 app.get('/') 之外的地方定义处理函数。
ts
import { createFactory } from 'hono/factory'
import { logger } from 'hono/logger'
// ...
const factory = createFactory()
const middleware = factory.createMiddleware(async (c, next) => {
c.set('foo', 'bar')
await next()
})
const handlers = factory.createHandlers(logger(), middleware, (c) => {
return c.json(c.var.foo)
})
app.get('/api', ...handlers)factory.createApp()
createApp() 用于创建带有正确类型的 Hono 实例。如果你搭配 createFactory() 使用,可以避免重复声明 Env 类型。
如果直接编写如下代码,就需要在两个地方设置 Env:
ts
import { createMiddleware } from 'hono/factory'
type Env = {
Variables: {
myVar: string
}
}
// 1. 在 `new Hono()` 上设置 `Env`
const app = new Hono<Env>()
// 2. 在 `createMiddleware()` 上设置 `Env`
const mw = createMiddleware<Env>(async (c, next) => {
await next()
})
app.use(mw)使用 createFactory() 与 createApp() 后,只需在一个位置指定 Env:
ts
import { createFactory } from 'hono/factory'
// ...
// 将 `Env` 传入 `createFactory()`
const factory = createFactory<Env>()
const app = factory.createApp()
// factory 同时提供 `createMiddleware()`
const mw = factory.createMiddleware(async (c, next) => {
await next()
})createFactory() 还可以通过 initApp 选项对 createApp() 创建的实例进行初始化。以下示例展示了如何在应用中注入数据库实例。
ts
// factory-with-db.ts
type Env = {
Bindings: {
MY_DB: D1Database
}
Variables: {
db: DrizzleD1Database
}
}
export default createFactory<Env>({
initApp: (app) => {
app.use(async (c, next) => {
const db = drizzle(c.env.MY_DB)
c.set('db', db)
await next()
})
},
})ts
// crud.ts
import factoryWithDB from './factory-with-db'
const app = factoryWithDB.createApp()
app.post('/posts', (c) => {
c.var.db.insert()
// ...
})