chanjs
v2.6.12
Published
chanjs基于express5 纯js研发的轻量级mvc框架。
Downloads
1,714
Maintainers
Readme
Chanjs
Chanjs 是一个基于 Express 5+ 构建的轻量级 MVC 框架,完全使用 JavaScript 开发。它体现了函数式编程的概念,提供了卓越的性能、清晰的代码和易于遵循的过程,确保了高可维护性。
ChanJS 是一个基于 Express 5+ 构建的轻量级 MVC 框架,完全使用纯 JavaScript 开发,强调函数式编程理念,具有高性能、代码清晰、易维护等特点。
特点
核心架构
- ✅ Express 5+ 原生
- ✅ Node.js 24+
- ✅ ES Modules (import / export)
- ✅ 多模块 MVC 架构
- ✅ 轻量级内核
- ✅ 约定优于配置
模块化
- ✅ 多模块路由
- ✅ 模块化 views
- ✅ 模块化 controllers
- ✅ 模块化 services
- ✅ 模块化 middleware
数据库
- ✅ Knex.js 查询构建器
- ✅ SQLite / MySQL / PostgreSQL
- ✅ 连接池
- ✅ 事务
- ✅ 自动时间格式化
安全能力
- ✅ WAF 防火墙
- ✅ XSS 防护
- ✅ 关键词过滤
- ✅ 请求限流
- ✅ 路由白名单
- ✅ Cookie 安全
中间件生态
- ✅ CORS
- ✅ 请求解析
- ✅ Cookie
- ✅ 静态资源
- ✅ 日志
- ✅ Art-template 模板引擎
高级特性
- ✅ DI 依赖注入(Map 实现)
- ✅ AOP 切面(before/after/error)
- ✅ 事件系统
- ✅ 自动加载控制器
- ✅ 定时任务
- ✅ WebSocket
- ✅ 缓存系统(Redis 和 内存缓存 map 实现)
- ✅ 分页器
- ✅ 国际化 i18n
- ✅ 请求验证器
- ✅ 全局异常处理
- ✅ 接口文档自动生成
- ✅ 文件上传 / OSS 扩展口
开发体验
- ✅ 多环境配置
- ✅ 统一响应
- ✅ 工具函数
约定优于配置
|- app
|- common
|- helper
|- middleware
|- modules
|- module1
|- controller
|- service
|- middleware
|- router.js
|- module2
|- controller
|- service
|- router.js
|- plugins
|- plugin1
|- controller
|- router.js
|- router.js
|- config
|- data
|- doc
|- public
|- view
|- app.js
|-.env.dev
|-.env.prd
|- pm2.json
|- package.jsonnpm 包参考
{
"art-template": "^4.13.4",
"body-parser": "^2.2.0",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^17.2.1",
"dayjs": "^1.11.13",
"express": "^5.1.0",
"express-art-template": "^1.0.1",
"knex": "^3.1.0",
"morgan": "^1.10.0",
"mysql2": "^3.14.1",
"marked": "^17.0.3",
"adm-zip": "^0.5.16",
"bcryptjs": "^3.0.2",
"better-sqlite3": "^12.8.0",
"chanjs": "^2.6.10",
"cheerio": "^1.1.2",
"crypto-js": "^4.2.0",
"iconv-lite": "^0.6.3",
"jsonwebtoken": "^9.0.2",
"multer": "^2.0.2",
"nodemailer": "^7.0.6",
"qiniu": "^7.14.0",
"serve-favicon": "^2.5.1",
"xml2js": "^0.6.2",
"xss": "^1.0.15",
"zod": "^4.1.11"
}初始化过程
初始化流程:
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ 初始化 │───▶│ 加载配置 │───▶│ 加载数据库│───▶│ 加载扩展 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
│
┌─────────┐ ┌─────────┐ │
│ 加载服务 │ │ 加载控制器│ │
└────▲────┘ └────▲────┘ │
│ │ │
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──┴──────┐
│ 应用路由 │◀───│加载公共路由│◀───│加载模块路由│◀───│加载中间件│
└────┬────┘ └─────────┘ └────┬────┘ └─────────┘
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐
└───▶│设置错误处理│───▶│beforeStart│───▶│ run启动 │
└─────────┘ └─────────┘ └─────────┘核心功能
1. 依赖注入(DI)
Chanjs 提供了轻量级的依赖注入容器,支持 Service 和 Controller 的自动加载。
使用方式
import { Service, Controller } from "chanjs";
class UserService extends Service {
constructor() {
super("user");
}
}
class UserController extends Controller {
constructor() {
super();
}
async getUser(req, res, next) {
}
}2. 面向切面编程(AOP)
Chanjs 提供了 AOP(面向切面编程)支持,可以在方法执行前后添加切面逻辑。
支持的切面类型
before- 方法执行前after- 方法执行后error- 方法执行异常时
使用方式
import { aop } from "chanjs";
// 注册切面函数
aop.set("logBefore", async ({ ctx, methodName, args }) => {
console.log(`[Before] ${methodName} 被调用,参数:`, args);
});
aop.set("logAfter", async ({ ctx, methodName, result }) => {
console.log(`[After] ${methodName} 执行完成,结果:`, result);
});
aop.set("logError", async ({ ctx, methodName, error }) => {
console.error(`[Error] ${methodName} 执行失败:`, error);
});
// 绑定切面到实例方法
const controller = new UserController();
aop.wrap(controller, {
getUser: [
{ type: "before", logBefore: true },
{ type: "after", logAfter: true },
{ type: "error", logError: true }
]
});
// 调用方法时会自动执行切面
await controller.getUser(1);切面配置选项
aop.wrap(instance, {
methodName: [
{ type: "before", enabled: true, customParam: "value" },
{ type: "after", enabled: true },
{ type: "error", enabled: false }
]
});type- 切面类型(before/after/error)enabled- 是否启用该切面(默认 true)- 其他自定义参数会传递给切面函数
3. 事件系统
Chanjs 提供了基于 Node.js EventEmitter 的事件系统,支持应用内的事件发布订阅。
使用方式
import { event } from "chanjs";
// 监听事件
event.on("user.login", (data) => {
console.log("用户登录:", data);
});
event.on("user.logout", (data) => {
console.log("用户退出:", data);
});
// 触发事件
event.emit("user.login", { userId: 1, username: "admin" });
// 移除监听器
event.off("user.login", listener);
// 移除所有监听器
event.removeAllListeners("user.login");4. 自动加载控制器
Chanjs 提供了 loadController 辅助函数,可以自动加载指定模块下的所有控制器。
使用方式
import { helper } from "chanjs";
// 加载 member 模块下的所有控制器
const controller = await helper.loadController("member");
// 使用控制器
controller.Member.getUser();
controller.Comment.getComments();
controller.Favorite.getFavorites();目录结构
member/
controller/
Member.js
Comment.js
Favorite.js
service/
Member.js
Comment.js
Favorite.js
router.jsloadController("member") 会自动加载 member/controller/ 目录下的所有文件,并返回一个对象:
{
Member: MemberController实例,
Comment: CommentController实例,
Favorite: FavoriteController实例
}运行
import Chanjs from "chanjs";
const chan = new Chanjs();
// 前置钩子
chan.beforeStart(fn);
// 开始加载
await chan.start();
// 启动服务器
chan.run((port) => {
console.log(`ChanCMS is running on ${port}`);
});完整示例
import Chanjs from "chanjs";
import { aop, event } from "chanjs";
const app = new Chanjs();
// 注册切面
aop.set("logBefore", async ({ ctx, methodName, args }) => {
console.log(`[Before] ${methodName} 被调用`);
});
// 监听事件
event.on("app.start", () => {
console.log("应用启动");
});
// 启动应用
await app.start();
// 运行
app.run((port) => {
event.emit("app.start", { port });
console.log(`Server running on port ${port}`);
});该框架专为寻求简单与功能之间平衡的开发者设计,为构建 Web 应用程序提供了一个强大的基础。
