npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chanjs

v2.6.12

Published

chanjs基于express5 纯js研发的轻量级mvc框架。

Downloads

1,714

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.json

npm 包参考

{
  "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.js

loadController("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 应用程序提供了一个强大的基础。