# Chanjs **Repository Path**: chancms/Chanjs ## Basic Information - **Project Name**: Chanjs - **Description**: Chan.js 基于express 纯js研发的轻量级mvc框架。基于函数式编程思想,流程清晰,代码易读,可持续维护高。 - **Primary Language**: NodeJS - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 13 - **Forks**: 13 - **Created**: 2024-01-06 - **Last Updated**: 2026-04-30 ## Categories & Tags **Categories**: webframework **Tags**: None ## 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 扩展口 ### 开发体验 - ✅ 多环境配置 - ✅ 统一响应 - ✅ 工具函数 ## 约定优于配置 ```code |- 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.json ``` ## npm 包参考 ```json { "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 的自动加载。 #### 使用方式 ```javascript 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` - 方法执行异常时 #### 使用方式 ```javascript 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); ``` #### 切面配置选项 ```javascript 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 的事件系统,支持应用内的事件发布订阅。 #### 使用方式 ```javascript 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` 辅助函数,可以自动加载指定模块下的所有控制器。 #### 使用方式 ```javascript 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.js ``` `loadController("member")` 会自动加载 `member/controller/` 目录下的所有文件,并返回一个对象: ```javascript { Member: MemberController实例, Comment: CommentController实例, Favorite: FavoriteController实例 } ``` ## 运行 ```javascript import Chanjs from "chanjs"; const chan = new Chanjs(); // 前置钩子 chan.beforeStart(fn); // 开始加载 await chan.start(); // 启动服务器 chan.run((port) => { console.log(`ChanCMS is running on ${port}`); }); ``` ## 完整示例 ```javascript 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 应用程序提供了一个强大的基础。