Hono——一个小型,简单且超快的Edges Web框架

news2024/11/18 23:22:48

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.ioFastly Compute@Edge提供必要的浏览器填充的 CDN 服务。Hono被用作核心服务器。
UltraDeno一个 React/Deno 框架。Hono 用于内部服务器。
Deno BenchmarksDeno基于 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],
				},
			});
		},
	}),
);

现在,可以通过 getSessionStoragegetSession 方法来获取会话对象了。

注意:如果 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 }));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1059663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Leetcode】滑动窗口合集

这里写目录标题 209.长度最小的子数组题目思路代码 3. 无重复字符的最长子串&#xff08;medium&#xff09;题目思路 11. 最大连续 1 的个数 III题目思路 1658. 将 x 减到 0 的最⼩操作数题目思路代码 904. 水果成篮题目思路代码 438.找到字符串中所有字母的异位词题目思路代码…

政治与科技

作者&#xff1a;Hal Finney, 1994.1.2 今天政府可以禁书吗&#xff1f;当然不&#xff0c;至少在一个人将其输入或扫描到计算机中之后不能。技术成果是永久性的。政治手段只能作为一种战术武器&#xff0c;在技术解决方案到位之前阻止它们。如果你想改变世界&#xff0c;就不要…

Pytorch目标分类深度学习自定义数据集训练

目录 一&#xff0c;Pytorch简介&#xff1b; 二&#xff0c;环境配置&#xff1b; 三&#xff0c;自定义数据集&#xff1b; 四&#xff0c;模型训练&#xff1b; 五&#xff0c;模型验证&#xff1b; 一&#xff0c;Pytorch简介&#xff1b; PyTorch是一个开源的Python机…

python二次开发CATIA:为选中元素上色

先打开一个零件文档&#xff0c;然后用鼠标选中元素&#xff0c;再运行如下python程序&#xff1a; import win32com.client import pywintypes # 导入pywintypes模块 import random # 启动CATIA应用 catia win32com.client.Dispatch(CATIA.Application) catia.visible1try:…

在OpenWrt中配置使用FTP文件服务

安装&#xff1a;opkg install vsftpd 配置&#xff1a;vim /etc/vsftpd.conf 在其中增加一行&#xff1a;local_root/tmp 重启&#xff1a;service vsftpd restart

基于B2B平台的医疗病历交互系统

目录 前言 一、技术栈 二、系统功能介绍 医院管理 医院注册 医院文章 医生信息 医院注册 医疗安排 院区注册 医院公告 医院工作人员 病人病历 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 进入21世纪&#xff0c;计算机技术迅速向着网络化的、集…

pytorch最后一步安装失败显示false怎么办?

这两天在安装pytorch&#xff0c;可谓是吃了不少苦&#xff0c;安了整整一天才安装好。 本来按照安装步骤&#xff0c;一步一步都进行的很好&#xff0c;可是最后一步却显示false。 我的解决方案是&#xff0c;先更新显卡驱动&#xff08;注意我的是英伟达显卡&#xff0c;安…

什么是向量嵌入?

一、说明 在所有关于生成式AI的讨论中&#xff0c;为生成式AI提供动力背后的概念可能有点压倒性。在这篇文章中&#xff0c;我们将重点介绍一个功能概念&#xff0c;它为人工智能的潜在认知能力提供支持&#xff0c;并为机器学习模型提供学习和成长的能力&#xff1a;向量嵌入。…

【C语言】浅谈代码运行效率及内存优化

【C语言】浅谈代码运行效率及内存优化 C语言作为一种高效率的编译语言 常用来写单片机等讲究时序性的设备 而只有代码优化得好 才能提高运行效率 当然这里的代码优化 并不是编译器优化 而是人为的代码习惯 文章目录 代码效率条件判断if else语句 抛弃边缘状态中断函数串口解析…

算法基础学习|排序

快速排序 模板 void quick_sort(int q[], int l, int r) {if (l > r) return;int i l - 1, j r 1, x q[l r >> 1];while (i < j){do i ; while (q[i] < x);do j -- ; while (q[j] > x);if (i < j) swap(q[i], q[j]);}quick_sort(q, l, j)&#xf…

希尔排序(C++实现)

文章目录 前言1. 基础概念2. 动图演示3. 代码实现4. 排序过程5. 效率分析6. 总结 前言 上篇文章讲了直接插入排序算法。 首先&#xff0c;在待排序的数组中&#xff0c;元素本身就是有序的情况下&#xff0c;就不需要移动任何元素&#xff0c;所以直接插入排序最好情况时间复…

Javascript 事件的动态绑定

动态绑定事件&#xff0c;是指在代码执行过程中&#xff0c;通过Javascript代码来绑定事件。这种技术可以大大增强网页的交互性和用户体验。上一期介绍的是通过事件监听器 EventListener 去实现元素颜色的变化。这一期将通过动态绑定方法去实现&#xff0c;对象.事件 匿名函数…

哈希/散列--哈希表[思想到结构]

文章目录 1.何为哈希?1.1百度搜索1.2自身理解1.3哈希方法/散列方法1.4哈希冲突/哈希碰撞1.5如何解决?哈希函数的设计 2.闭散列和开散列2.1闭散列/开放定址法2.2开散列/链地址法/开链法1.概念2.容量问题 3.代码实现[配备详细注释]3.1闭散列3.2开散列 1.何为哈希? 1.1百度搜索…

【工具】idea 设置自动渲染注释

前言 需求&#xff1a;自动渲染文档注释&#xff0c;看源码更加舒服。 已知 crtl alt Q 可以 设置 尝试搜索 render&#xff0c;发现有启用 “渲染文档注释” 的地方 坐标 &#xff1a; Settings -> Editor-> Appearance

CSS3与HTML5

box-sizing content-box&#xff1a;默认&#xff0c;宽高包不含边框和内边距 border-box&#xff1a;也叫怪异盒子&#xff0c;宽高包含边框和内边距 动画&#xff1a;移动translate&#xff0c;旋转、transform等等 走马灯&#xff1a;利用动画实现animation&#xff1a;from…

分布式锁:jvm本地加锁解决商品超卖的方案

一 分布式锁 1.1 分布式锁的作用 在多线程高并发场景下&#xff0c;为了保证资源的线程安全问题&#xff0c;jdk为我们提供了synchronized关键字和ReentrantLock可重入锁&#xff0c;但是它们只能保证一个工程内的线程安全。在分布式集群、微服务、云原生横行的当下&#xff…

python二次开发CATIA:根据已知数据点创建曲线

已知数据点存于Coords.txt文件如下&#xff1a; 8.67155477658819,20.4471021292557,0 41.2016126836927,20.4471021292557,0 15.9568941320569,-2.93388599177698,0 42.2181532110364,-6.15301746150354,0 43.0652906622083,-26.4843096139083,0 -31.6617679595947,-131.1513…

Java基本数据类型和变量

目录 一、基本数据类型 1.1 整型 1.1.1 byte 1.1.2 short 1.1.3 int 1.1.4 long 1.2 浮点型 1.2.1 float 1.2.2 double 1.3 字符型 1.4 布尔型 二、变量 2.1 变量的概念 2.2 语法格式 2.3 整型变量 2.3.1 整型变量 2.3.2 长整型变量 2.3.3 短整型变量 2.3.…

【Unity2022】Unity实现在两个物体之间连出一条线

文章目录 Line Renderer组件添加Line Renderer组件重要属性Positions&#xff08;位置&#xff09;Width &#xff08;宽度&#xff09;Material&#xff08;材质&#xff09;其他属性 使用脚本绘制直线绳子运行结果其他文章 Line Renderer组件 我们可以使用LineRenderer组件来…