Hono - [炎]在日语中的意思是火焰🔥 - 是一个小型,简单且超快的Edges Web框架。它适用于任何JavaScript运行时:Cloudflare Workers,Fastly Compute@Edge,Deno,Bun,Vercel,Netlify,Lagon,AWS Lambda,Lambda@Edge和Node.js。
快,但不仅快。
文章目录
- 快速入门
- 特征
- 用例
- 谁在使用Hono?
- 示例
- 超快
- 轻
- Remix + Hono 示例
- Session 会话管理
- 静态资源
- HTTPS Only
- trailingSlash
快速入门
npm i --save hono
只需运行这个:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hono!'))
export default app
特征
- 超快 🚀 - 路由器
RegExpRouter
真的很快。不使用线性循环。快。 - 轻量级 🪶 -
hono/tiny
预设小于 12kB。Hono 的依赖关系为零,仅使用 Web 标准 API。 - 多运行时 🌍 - 适用于Cloudflare Workers,Fastly Compute@Edge,Deno,Bun,Lagon,AWS Lambda或Node.js。相同的代码在所有平台上运行。
- 能力🔋 - Hono 具有内置中间件、自定义中间件、第三方中间件和助手。包括电池。
- 令人愉快的DX 🛠️ - 超级干净的API。一流的 TypeScript 支持。现在,我们有“类型”。
用例
Hono是一个简单的Web应用程序框架,类似于Express,没有前端。但它在 CDN Edge 上运行,允许您在与中间件结合使用时构建更大的应用程序。以下是一些用例示例:
- 构建网络接口
- 后端服务器代理
- CDN 前端
- 边缘应用
- 库的基本服务器
- 全栈应用
谁在使用Hono?
项目 | 平台 | 用途 |
---|---|---|
cdnjs API 服务器 | Cloudflare Workers | 免费的开源 CDN 服务。Hono用于他们的API服务。 |
Polyfill.io | Fastly Compute@Edge | 提供必要的浏览器填充的 CDN 服务。Hono被用作核心服务器。 |
Ultra | Deno | 一个 React/Deno 框架。Hono 用于内部服务器。 |
Deno Benchmarks | Deno | 基于 V8 构建的安全 TypeScript 运行时。Hono用于基准测试。 |
Cloudflare 博客 | Cloudflare Workers | 文章中介绍的一些应用程序使用 Hono。 |
示例
使用 Hono 为 Cloudflare Workers 创建应用程序的演示。
超快
Hono是最快的,与Cloudflare Workers的其他路由器相比。
Hono x 402,820 ops/sec ±4.78% (80 runs sampled)
itty-router x 212,598 ops/sec ±3.11% (87 runs sampled)
sunder x 297,036 ops/sec ±4.76% (77 runs sampled)
worktop x 197,345 ops/sec ±2.40% (88 runs sampled)
Fastest is Hono
✨ Done in 28.06s.
查看更多基准测试: https://hono.dev/concepts/benchmarks
轻
Hono 太小了。使用 hono/tiny
预设时,其大小在缩小时小于 12KB。有许多中间件和适配器,但它们仅在使用时才捆绑在一起。对于上下文,Express 的大小为 572KB。
$ npx wrangler dev --minify ./src/index.ts
⛅️ wrangler 2.20.0
--------------------
⬣ Listening at http://0.0.0.0:8787
- http://127.0.0.1:8787
- http://192.168.128.165:8787
Total Upload: 11.47 KiB / gzip: 4.34 KiB
Remix + Hono 示例
安装包:
npm add remix-hono
然后创建你的 Remix 服务器:
import { logDevReady } from "@remix-run/cloudflare";
import * as build from "@remix-run/dev/server-build";
import { Hono } from "hono";
// You can also use it with other runtimes
import { handle } from "hono/cloudflare-pages";
import { remix } from "remix-hono/handler";
if (process.env.NODE_ENV === "development") logDevReady(build);
/* type your Cloudflare bindings here */
type Bindings = {};
/* type your Hono variables (used with ctx.get/ctx.set) here */
type Variables = {};
type ContextEnv = { Bindings: Bindings; Variables: Variables };
const server = new Hono<ContextEnv>();
// Add the Remix middleware to your Hono server
server.use(
"*",
remix({
build,
mode: process.env.NODE_ENV as "development" | "production",
// getLoadContext is optional, the default function is the same as here
getLoadContext(ctx) {
return ctx.env;
},
}),
);
// Create a Cloudflare Pages request handler for your Hono server
export const onRequest = handle(server);
现在,你可以添加 Hono 中间件了,比如基本的登录认证:
import { basicAuth } from "hono/basic-auth";
server.use(
"*",
basicAuth({ username: "hono", password: "remix" }),
// Ensure Remix request handler is the last one
remix(options),
);
Session 会话管理
有三种常见方法来管理 Cloudflare 上的会话。
第一种,使用 Worker KV 持久化会话。
import { session } from "remix-hono/session";
// Install the `@remix-run/*` package for your server adapter to grab the
// factory functions for session storage
import { createWorkerKVSessionStorage } from "@remix-run/cloudflare";
server.use(
"*",
session({
autoCommit: true,
createSessionStorage(context) {
return createWorkersKVSessionStorage({
kv: context.env.MY_KV_BINDING,
cookie: {
name: "session",
httpOnly: true,
secrets: [context.SESSION_SECRET],
},
});
},
}),
);
现在,可以通过 getSessionStorage
和 getSession
方法来获取会话对象了。
注意:如果
autoCommit
设置为 false, 你需要手动调用sessionStorage.getSession()
import { getSessionStorage, getSession } from "remix-hono/session";
server.use(
"*",
remix<ContextEnv>({
build,
mode: process.env.NODE_ENV as "development" | "production",
// getLoadContext is optional, the default function is the same as here
getLoadContext(ctx) {
let sessionStorage = getSessionStorage(ctx);
let session = getSession(ctx);
// Return them here to access them in your loaders and actions
return { ...ctx.env, sessionStorage, session };
},
}),
);
第二种,使用 workerKVSession
来替代。
import { workerKVSession } from "remix-hono/cloudflare";
server.use(
"*",
workerKVSession({
autoCommit: true, // same as in the session middleware
cookie: {
name: "session", // all cookie options as in createWorkerKVSessionStorage
// In this function, you can access context.env to get the session secret
secrets(context) {
return [context.env.SECRET];
},
},
// The name of the binding using for the KVNamespace
binding: "KV_BINDING",
}),
);
第三种,使用cookieSession
。
import { cookieSession } from "remix-hono/cloudflare";
server.use(
"*",
cookieSession({
autoCommit: true, // same as in the session middleware
cookie: {
name: "session", // all cookie options as in createCookieSessionStorage
// In this function, you can access context.env to get the session secret
secrets(context) {
return [context.env.SECRET];
},
},
}),
);
静态资源
如果需要将 public
目录下的(除了 public/build
之外)资源通过服务提供,可以使用这样的中间件:
import { staticAssets } from "remix-hono/cloudflare";
import { remix } from "remix-hono/handler";
server.use(
"*",
staticAssets(),
// Add Remix request handler as the last middleware
remix(options),
);
HTTPS Only
强制使用 HTTPS:
import { httpsOnly } from "remix-hono/security";
server.use("*", httpsOnly());
trailingSlash
尾部 /
处理:
import { trailingSlash } from "remix-hono/trailing-slash";
// By default, trailing slashes are disabled, so `https://company.tld/about/`
// will be redirect to `https://company.tld/about`
server.use("*", trailingSlash());
server.use("*", trailingSlash({ enabled: false }));
// You can also enable trailing slashes, so `https://company.tld/about` will be
// redirect to `https://company.tld/about/` instead
server.use("*", trailingSlash({ enabled: true }));