@hestjs/core
HestJS 核心包 - 基于 Hono 构建的现代化 TypeScript 后端库,提供装饰器驱动的开发体验和依赖注入系统。
🎯 核心理念
- 🔓 拒绝过度封装:用户直接控制 Hono 实例,保留所有底层功能和灵活性
- ✈️ 零配置:你看不到类似
hestjs.config.ts这样的配置文件,无需任何配置
- 🎯 装饰器驱动:提供熟悉的 NestJS 风格开发体验
- 💉 轻量依赖注入:基于 TSyringe 的简洁 DI 容器
- ⚡ 极致性能:基于 Hono 和 Bun 的高性能运行时
- 🌊 原生中间件:直接使用 Hono 中间件,无需额外抽象层
📦 安装
npm install @hestjs/core
yarn add @hestjs/core
bun add @hestjs/core
🚀 快速开始
1. 创建基础应用
在此之前你应该在tsconfig中添加以下内容:
{
"compilerOptions": {
...
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true
}
}
import { Controller, Get, HestFactory, Module } from "@hestjs/core";
import { Hono } from "hono";
import { cors } from "hono/cors";
@Controller("/")
export class WelcomeController {
@Get("/welcome")
async welcome() {
return "Welcome to HestJS!";
}
}
@Module({
controllers: [WelcomeController],
providers: [],
imports: [],
exports: [],
})
export class AppModule {}
async function bootstrap() {
const hono = new Hono();
hono.use(cors());
const app = await HestFactory.create(hono, AppModule);
Bun.serve({
port: 3000,
fetch: hono.fetch,
});
}
bootstrap();
2. 异常处理中间件
替代全局异常过滤器,直接使用 Hono 中间件处理异常:
import type { Context, Next } from 'hono';
const exceptionMiddleware = async (c: Context, next: Next) => {
try {
await next();
} catch (error: any) {
const status = error.status || 500;
return c.json({
statusCode: status,
timestamp: new Date().toISOString(),
path: c.req.url,
message: error.message || 'Internal Server Error',
}, status);
}
};
const hono = new Hono();
hono.use('*', exceptionMiddleware);
hono.use(cors());
const app = await HestFactory.create(hono, AppModule);
3. 定义控制器
import { Controller, Get, Post, Context, Body, Param } from "@hestjs/core";
import type { HestContext } from "@hestjs/core";
@Controller("/users")
export class UsersController {
@Get("/")
async getAllUsers() {
return { message: "Get all users" };
}
@Get("/:id")
async getUser(@Param("id") id: string, @Context() c: HestContext) {
return { id, message: `Get user ${id}` };
}
@Post("/")
async createUser(@Body() body: any, @Context() c: HestContext) {
return { message: "User created", data: body };
}
}
4. 创建模块
import { Module } from "@hestjs/core";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
@Module({
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
5. 创建服务
import { injectable } from "@hestjs/core";
@injectable()
export class UsersService {
findAll() {
return [
{ id: 1, name: "John" },
{ id: 2, name: "Jane" },
];
}
findOne(id: number) {
return { id, name: `User ${id}` };
}
}
🏗️ 架构概览
核心模块
HestJS Core 包含以下主要模块:
@hestjs/core/
├── application/ # 应用工厂和实例
│ ├── HestFactory # 应用工厂
│ └── HestApplicationInstance # 应用实例
├── decorators/ # 装饰器系统
│ ├── @Controller # 控制器装饰器
│ ├── @Module # 模块装饰器
│ ├── @injectable # 可注入装饰器
│ └── 路由装饰器 # @Get, @Post, @Put, @Delete, @Patch
├── container/ # 依赖注入容器
├── router/ # 路由系统
├── exceptions/ # 异常处理
├── interceptors/ # 拦截器
├── interfaces/ # 类型定义
└── utils/ # 工具函数
📚 API 参考
🏭 应用工厂
HestFactory.create(moduleClass)
创建应用实例的静态方法。
import { HestFactory } from "@hestjs/core";
import { AppModule } from "./app.module";
const app = await HestFactory.create(AppModule);
🎮 控制器装饰器
@Controller(path?: string)
定义控制器类和基础路径。
@Controller("/api/users")
export class UsersController {
}
🛣️ 路由装饰器
HTTP 方法装饰器
@Get(path?: string) - GET 请求
@Post(path?: string) - POST 请求
@Put(path?: string) - PUT 请求
@Delete(path?: string) - DELETE 请求
@Patch(path?: string) - PATCH 请求
@Controller('/users')
export class UsersController {
@Get('/')
@Get('/:id')
@Post('/')
@Put('/:id')
@Delete('/:id')
@Patch('/:id')
}
📥 参数装饰器
@Context()
获取完整的 Hono Context 对象。
@Get('/')
async getUsers(@Context() c: HestContext) {
const userAgent = c.req.header('User-Agent');
return c.json({ message: 'Hello' });
}
@Body()
获取请求体数据。
@Post('/')
async createUser(@Body() userData: CreateUserDto) {
return userData;
}
@Param(key?: string)
获取路径参数。
@Get('/:id')
async getUser(@Param('id') id: string) {
return { id };
}
@Query(key?: string)
获取查询参数。
@Get('/')
async getUsers(@Query('page') page: string) {
return { page };
}
获取请求头。
@Get('/')
async getUsers(@Header('authorization') auth: string) {
return { auth };
}
🏗️ 模块系统
@Module(options)
定义模块和依赖关系。
interface ModuleOptions {
imports?: any[];
controllers?: any[];
providers?: any[];
exports?: any[];
}
@Module({
imports: [DatabaseModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}
💉 依赖注入
@injectable()
标记类为可注入的服务。
@injectable()
export class UsersService {
constructor(private readonly databaseService: DatabaseService) {}
}
🌐 直接访问 Hono
HestJS 不会封装 Hono,你可以直接使用所有 Hono 功能:
const app = await HestFactory.create(AppModule);
const honoApp = app.hono();
honoApp.use(cors());
honoApp.use("/api/*", async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
});
honoApp.get("/health", (c) => c.text("OK"));
🧪 类型系统
HestContext
提供完整的 Hono Context 类型安全:
import type { HestContext } from '@hestjs/core';
@Get('/')
async handler(@Context() c: HestContext) {
const method = c.req.method;
const url = c.req.url;
const headers = c.req.header();
return c.json({ method, url });
}
🔮 未来路线图
v0.2.x - 增强功能
v0.3.x - 性能优化
v0.4.x - 生态系统
v0.5.x - 企业级功能
v1.0.x - 稳定版本
📋 当前功能状态
✅ 已实现功能
🔄 重构说明
v0.2.0 重大更新 - 移除过度封装
为了提供更大的灵活性和更好的性能,我们进行了一次重要的架构重构:
🗑️ 移除的功能
- 全局异常过滤器 - 使用 Hono 中间件替代
- 拦截器系统 - 使用 Hono 中间件替代
app.hono() 方法 - 用户直接控制 Hono 实例
app.useGlobalFilters() 方法 - 使用中间件实现
✨ 新的设计理念
- 用户控制 - 用户手动创建
new Hono() 实例
- 原生中间件 - 直接使用 Hono 的中间件生态
- 零抽象层 - 减少性能开销和学习成本
- 最大灵活性 - 保留 Hono 的所有原生功能
🚀 迁移指南
旧的方式:
const app = await HestFactory.create(AppModule);
app.useGlobalFilters(new ExceptionFilter());
const hono = app.hono();
新的方式:
const hono = new Hono();
hono.use('*', exceptionMiddleware);
const app = await HestFactory.create(hono, AppModule);
这种设计让 HestJS 真正成为"基于 Hono 的 OOP 框架",而不是"包装 Hono 的框架"。
🚧 开发中功能
💡 设计原则
- 最小封装 - 不隐藏底层框架的功能
- 类型安全 - 完整的 TypeScript 支持
- 性能优先 - 基于高性能的 Hono 和 Bun
- 开发体验 - 熟悉的装饰器语法
- 渐进式 - 可以逐步采用各种功能
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT
更多信息: