终于,出现了一个不是怪物的 Bun 面向对象框架

发布: (2026年1月2日 GMT+8 04:06)
8 min read
原文: Dev.to

Source: Dev.to

Bun 以惊人的性能数据把门踢开。大家争相测试 Bun.serve(),而第一波框架(Elysia、Hono)则高度聚焦于函数式、极简的 “裸金属” 风格。

它们确实很棒,别误会。但我感觉少了点什么。

来自 .NET、Java,甚至是 Node 中的 NestJS 生态系统时,我们已经习惯了某些模式:依赖注入(DI)装饰器以及组织成类的控制器。我想要那种稳健的架构,却不想承受一个启动需要 5 秒的框架的重量。我想要 NestJS 的结构,却拥有 Bun 的原始速度。

就在这时,我发现(并开始使用)Carno.js

什么是 Carno.js?

Carno.js 将自己定义为 “性能优先的框架”,原生运行于 Bun。

它不试图重新发明轮子;它试图 组织 轮子。Carno.js 带来:

  • 控制器与装饰器@Get@Post@Body …),你已经熟悉。
  • 依赖注入,原生且轻量。
  • 自定义 ORM —— 一个轻量级 ORM,配备 自定义 SQL 构建器(没有 Knex,没有外部查询构建器——只有原始、优化的性能)。
  • 真正的模块化 —— 核心体积小。仅在真正需要时安装 @carno.js/orm@carno.js/queue

它适用于希望在不牺牲 Bun 原始性能的前提下,构建可扩展、组织良好的 API 的开发者。

安装与要求

  1. 安装 Bun(v1.0+)。

  2. 创建文件夹并初始化项目:

    mkdir my-carno-project
    cd my-carno-project
    bun init
  3. 安装框架核心:

    bun add @carno.js/core
  4. 启用装饰器 – Carno 使用经典的装饰器语法,因此请更新 tsconfig.json

    {
      "compilerOptions": {
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
        // ...other options
      }
    }

从零创建项目(逐步指南)

1. 文件夹结构

为了简单起步,保持布局最小化:

src/
├── controllers/
│   └── user.controller.ts
├── services/
│   └── user.service.ts
└── index.ts

2. 创建服务(依赖注入)

Carno 自带内置 DI 容器——无需外部库。

// src/services/user.service.ts
import { Service } from '@carno.js/core';

@Service()
export class UserService {
  private users = [
    { id: 1, name: 'Myron' },
    { id: 2, name: 'Bun User' }
  ];

  findAll() {
    return this users;
  }

  create(name: string) {
    const newUser = { id: this.users.length + 1, name };
    this.users.push(newUser);
    return newUser;
  }
}

3. 创建控制器

如果你使用过 NestJS 或 Spring,这会很熟悉。注意构造函数中对 UserService 的注入。

// src/controllers/user.controller.ts
import { Controller, Get, Post, Body } from '@carno.js/core';
import { UserService } from '../services/user.service';

@Controller('/users')
export class UserController {
  constructor(private userService: UserService) {}

  @Get()
  getUsers() {
    return this.userService.findAll();
  }

  @Post()
  createUser(@Body('name') name: string) {
    // Basic validation
    if (!name) {
      throw new Error('Name is required');
    }
    return this.userService.create(name);
  }
}

4. 入口点

index.ts 中将所有内容关联起来。Carno 需要知道你打算使用的控制器和提供者(服务)。

// src/index.ts
import { Carno } from '@carno.js/core';
import { UserController } from './controllers/user.controller';
import { UserService } from './services/user.service';

const app = new Carno({
  providers: [
    UserService,     // Register the service
    UserController   // Register the controller
  ]
});

const port = 3000; // Default port 3000 or whatever you pass
app.listen(port);

5. 运行

bun run src/index.ts

完成。没有复杂的构建步骤,也没有慢速的转译。即时运行。

完整示例:模块化

Carno 支持 嵌套路由(子控制器)。当你的 API 规模扩大时,你不需要一个庞大的路由文件。

// Example of a versioned API controller
import { Controller } from '@carno.js/core';
import { UserController } from './controllers/user.controller';
import { ProductController } from './controllers/product.controller';

@Controller({
  path: '/api/v1',
  children: [UserController, ProductController]
})
export class ApiV1Controller {}

这使得 API 版本管理变得轻而易举。

好处与权衡

✅ 好处

  • DX (Developer Experience): 编写类和装饰器对大型团队来说非常易读。
  • Performance: 底层使用 Bun.serve——快速。非常快。
  • Integrated Ecosystem: @carno.js/orm@carno.js/queue 遵循相同的模式,因而无需手动拼接不同的库。

⚠️ 权衡

  • Maturity: 它比 Express 或 NestJS 更新。你可能会错过在旧项目中依赖的某些冷门插件。
  • Bun‑Only: 如果公司政策要求使用 Node.js,Carno 目前(尚)不是选项。
  • Community Size: 目前社区规模小于 Hono 或 Elysia,所以你可能需要偶尔阅读源码(说实话,源码相当整洁)。

Practical Performance Tips in Carno

  • 使用单例: 默认情况下,服务是单例的。除非绝对必要(例如每个请求的租户数据),否则避免使用 REQUEST 范围(ProviderScope.REQUEST),因为实例化类会消耗 CPU。
  • JSON 序列化: Carno 会自动序列化对象。控制器中返回普通对象(POJO)而不是带有循环方法的复杂类。
  • 缓存: Carno 提供良好的缓存集成。如果某个端点开销大,给它加缓存。
  • 关注日志: 在生产环境中使用异步日志记录器(Carno 内部使用 pino;请配置它以避免阻塞主线程)。
  • 避免沉重的中间件: Carno 的中间件模型很灵活,但每个中间件都会为请求增加一次“跳转”。保持中间件轻量化。

快速比较

框架风格何时使用?
Carno.js面向对象,装饰器,结构化如果你喜欢 NestJS/Java/.NET,但想要 Bun 的速度以及自定义、轻量级的 ORM。
Elysia / Hono函数式,极简超轻量微服务、边缘函数,或如果你偏好函数式编程。
NestJS面向对象,意见化,大型如果你需要庞大的企业生态系统并在 Node.js 上运行。
Express传统旧项目。对于新项目,请避免使用(慢且开发体验过时)。

快速常见问题

1. 我可以在 SQL 数据库中使用它吗?
是的!@carno.js/orm 是推荐的方式。它专为此生态系统构建,不带旧查询构建器的负担。

2. 它支持 Validation 吗?
是的,它原生使用 class-validatorclass-transformer。你可以使用 @IsString() 等装饰器创建 DTO。

3. 它如何与 Testing 配合使用?
Bun 有原生测试运行器(bun test)。由于 Carno 使用依赖注入,在控制器单元测试中“mock”服务非常简单。

4. 它兼容 Node 库吗?
大多数情况下兼容,归功于 Bun 的兼容性。建议使用不依赖晦涩原生 Node API 的库。

5. 我可以在 Serverless 环境中使用它吗?
可以,但 Carno 在容器/长运行进程中更能发挥优势,因为 DI 和结构在此处收益更大。

结论

Carno.js 填补了一个重要空白:结构稳健且不慢。如果你一直在寻找将那个慢速的 Node API 迁移到 Bun 的借口,但又担心失去代码组织结构,不妨试试 Carno。

有用链接

喜欢这个提示吗?你在 Bun 中尝试过任何面向对象的框架吗?在评论中告诉我吧!

Back to Blog

相关文章

阅读更多 »

别再像2015年那样写API

我们已经进入2025年,仍有许多代码库把 API 视为简单的“返回 JSON 的端点”。如果你的 API 设计仍停留在基本的 CRUD 路由上,你正……