aks扑克教学平台

基于express封装轻量级mvc框架chanjs

2024-09-18 13:11:08 阅读(88)

背景

基于国内koa2封装的thinkjs和eggjs基本都黄了,或者不更新了。而且koa2的市场占有量的确不如express,加上本人不喜欢typescript和nestjs风格,所以就想实现一个mvc框架。

chanjs介绍

Chanjs 基于express 纯js研发的轻量级mvc框架。基于函数式编程思想,性能优越,代码清晰,流程易读,可持续维护高。

核心功能

配置文件多模块mvc数据库支持路由控制art-template模板静态资源cookie日志功能参考

thinkjs多模块eggjs约定优于配置原则约定结构

|- app

|- config 配置

|- module 模块1

|- module1 模块1

|- controller 控制器

|- service 服务模型

|- view 视图模板

|- router.js 路由

|- module2 模块2

|- controller 控制器

|- service 服务模型

|- view 视图模板

|- router.js路由

|- extend 扩展

|- middleware 中间件

|- plugin 插件

|- public 静态文件

|- index.js

初始化流程

框架加载默认约定结构,动态加载模块,分为以下几个流程:

- 初始化

- 加载配置

- 加载模块

- 加载service

- 加载controller

- 加载router

- 加载extend

- 加载plugin

- beforeStart() 挂在从数据库获取的配置合并到配置文件中

- run() 启动服务

核心代码实现

const express = require("express");

const config = require("./lib/config/config.js");

const path = require("path");

const fs = require("fs");

const core = require("./lib/core.js");

/**

* @description 基于express封装的mvc框架,遵循约定优于配置原则

*/

class Chan {

constructor(options={}) {

//配置

Chan.config = Object.assign(config, options);

//模块

Chan.modules ={};

//工具

Chan.helper ={};

//应用实例

this.app = express();

this.app.config = Chan.config;

this.router = express.Router();

//加载配置

this.loadConfig();

//加载扩展

this.loadExtends();

//加载核心(日志、favicon 图标、cookie、json、url、模板引擎、静态资源)

this.loadCore();

//加载实例化数据库

this.loadKnex();

//生命周期钩子:开始启动

this.beforeStart();

//加载模块

this.loadModules();

//生命周期:初始化完成

this.start()

}

// 加载配置

loadConfig() {

const configPath = path.join(config.APP_PATH, "config/index.js");

if (fs.existsSync(configPath)) {

const config = require(configPath);

Chan.config = Object.assign(Chan.config, config);

}

}

// 加载扩展

loadExtends() {

const extendPath = path.join(config.APP_PATH, "extend");

if (fs.existsSync(extendPath)) {

let controllers = fs

.readdirSync(extendPath)

.filter((file) => file.endsWith(".js"));

for (let i = 0, file; i < controllers.length; i++) {

file = controllers[i];

const helper = require(path.join(extendPath, file));

const fileName = file.replace(".js", "");

Chan.helper[fileName] = helper;

}

}

}

//数据库操作

loadKnex(){

// 连接数据库

const {host,port,user,password,database,client,charset} = Chan.config.database;

const knex = require("knex")({

client: "mysql2",

connection: {

host,

port,

user,

password,

database,

charset,

},

debug: config.debug, //指明是否开启debug模式,默认为true表示开启

pool: {

//指明数据库连接池的大小,默认为{min: 2, max: 10}

min: 0,

max: 2,

},

log: {

warn(message) {

console.error("[knex warn]", message);

},

error(message) {

console.error("[knex error]", message);

},

},

});

Chan.knex = knex;

}

//开始启动

beforeStart(cb) {

// 初始化一些配置

cb && cb();

}

//启动

start(cb){

// 初始化一些配置

cb && cb();

}

// 加载插件

loadPlugins() {

const configPath = path.join(config.APP_PATH, "plugin");

if (fs.existsSync(configPath)) {

const dirs = fs

.readdirSync(configPath, { withFileTypes: true })

.filter((dirent) => dirent.isDirectory())

.map((dirent) => dirent.name);

this.plugins = dirs;

} else {

this.plugins = [];

}

}

/**

* @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源

*/

loadCore(){

core(this.app);

}

/**

* @description 模块加载入口(路由&控制器& 服务)

*/

loadModules() {

const configPath = path.join(config.APP_PATH, "modules");

if (fs.existsSync(configPath)) {

const dirs = fs

.readdirSync(configPath, { withFileTypes: true })

.filter((dirent) => dirent.isDirectory())

.map((dirent) => dirent.name);

this.modulesDir = dirs;

for(let i=0,item;i 

item = dirs[i];

Chan.modules[item] = {

controller: {},

service: {},

};

this.loadModule(item);

}

//通用路由,加载错误处理和500路由和爬虫处理

const baseRouterPath = path.join(config.APP_PATH, "router.js");

if (fs.existsSync(baseRouterPath)) {

const _router = require(baseRouterPath);

_router(this.app, this.router);

}

}

}

/**

* @description 加载模块,包括 controller service router

* @param {String} moduleName 模块名称

*/

loadModule(moduleName) {

const moduleDir = path.join(config.APP_PATH, "modules", moduleName);

this.loadServices(moduleDir,moduleName);

this.loadControllers(moduleDir,moduleName);

this.loadRoutes(moduleDir,moduleName);

}

/**

* @description 扫描模块下所有service

* @param {*} moduleDir 模块路径

* @param {*} moduleName 模块名称

*/

loadServices(moduleDir,moduleName) {

const servicesDir = path.join(moduleDir, "service");

if (fs.existsSync(servicesDir)) {

let services = fs

.readdirSync(servicesDir)

.filter((file) => file.endsWith(".js"));

for (let i = 0, file; i < services.length; i++) {

file= services[i]

const Service = require(path.join(servicesDir, file));

const serviceName = file.replace(".js", "");

Chan.modules[moduleName].service[serviceName] = {};

Chan.modules[moduleName].service[serviceName] = Service;

}

}

}

/**

* @description 扫描模块下所有controller

* @param {*} moduleDir 模块路径

* @param {*} moduleName 模块名称

*/

loadControllers(moduleDir,moduleName) {

const controllersDir = path.join(moduleDir, "controller");

if (fs.existsSync(controllersDir)) {

let controllers = fs

.readdirSync(controllersDir)

.filter((file) => file.endsWith(".js"));

for (let i = 0, file; i < controllers.length; i++) {

file= controllers[i]

const controller = require(path.join(controllersDir, file));

const controllerName = file.replace(".js", "");

Chan.modules[moduleName].controller[controllerName] = {};

Chan.modules[moduleName].controller[controllerName] = controller;

}

}

}

/**

* @description 扫描模块下所有router.js

* @param {*} moduleDir 模块路径

* @param {*} moduleName 模块名称

*/

loadRoutes(moduleDir,moduleName) {

const routersDir = path.join(moduleDir, "router.js");

if (fs.existsSync(routersDir)) {

const routes = require(routersDir);

routes({router:this.router,modules:Chan.modules,app:this.app});

}

}

loadPlusins() {

// 加载插件

}

run(port) {

this.app.listen(port, () => {

console.log(`Server is running on port ${port}`);

});

}

}

module.exports = Chan;

案例

基于chanjs实现chancms管理系统。

禅CMS是一款基于Express和MySQL研发的高质量实用型CMS管理系统。它具备多种类型网站开发,易扩展、基于模块化和插件化开发模式,适用于商用企业级程序开发。

上一篇: 真的没有了

下一篇: 真的没有了

ChanCMS 当前页面数据:

site-> {"id":1,"name":"aks扑克教学平台","domain":"www.aks.poker","email":"623340786@qq.com","wx":null,"icp":"蜀ICP备2023002137号-3","code":"","json":"","title":"aks.poker","keywords":"扑克","description":"专业的扑克教学平台,提供各种扑克游戏的教学、策略等技巧,提高你的博弈水平","template":null,"appid":null,"secret":null,"createdAt":null,"updatedAt":"2024-08-28T00:26:38.000Z"}

nav-> [{"id":9,"pid":0,"name":"首页","pinyin":"home","path":"/home","sort":1,"target":"0","status":"0","list_view":"index.html","article_view":"index.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1},{"id":1,"pid":0,"name":"前端","pinyin":"qianduan","path":"/qianduan","sort":2,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"前端开发","seo_keywords":"前端开发,es6,es5,javascript,js,css3,微信小程序","seo_description":"前端开发常用知识,包括es6,es5,javascript,js,css3,微信小程序等常见开发。","type":"0","level":1},{"id":2,"pid":0,"name":"nodejs","pinyin":"nodejs","path":"/nodejs","sort":3,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","children":[{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":7,"pid":2,"name":"mysql","pinyin":"mysql","path":"/mysql","sort":8,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1}],"level":1},{"id":3,"pid":0,"name":"文档","pinyin":"wendang","path":"/wendang","sort":4,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":5,"pid":0,"name":"案例","pinyin":"anli","path":"/anli","sort":5,"target":"0","status":"0","list_view":"list.html","article_view":"chanyue.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1},{"id":8,"pid":0,"name":"作者","pinyin":"about","path":"/about","sort":6,"target":"0","status":"0","list_view":"list.html","article_view":"message.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1}]

category-> [{"id":9,"pid":0,"name":"首页","pinyin":"home","path":"/home","sort":1,"target":"0","status":"0","list_view":"index.html","article_view":"index.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1},{"id":1,"pid":0,"name":"前端","pinyin":"qianduan","path":"/qianduan","sort":2,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"前端开发","seo_keywords":"前端开发,es6,es5,javascript,js,css3,微信小程序","seo_description":"前端开发常用知识,包括es6,es5,javascript,js,css3,微信小程序等常见开发。","type":"0","level":1},{"id":2,"pid":0,"name":"nodejs","pinyin":"nodejs","path":"/nodejs","sort":3,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","children":[{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":7,"pid":2,"name":"mysql","pinyin":"mysql","path":"/mysql","sort":8,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1}],"level":1},{"id":3,"pid":0,"name":"文档","pinyin":"wendang","path":"/wendang","sort":4,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":5,"pid":0,"name":"案例","pinyin":"anli","path":"/anli","sort":5,"target":"0","status":"0","list_view":"list.html","article_view":"chanyue.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1},{"id":8,"pid":0,"name":"作者","pinyin":"about","path":"/about","sort":6,"target":"0","status":"0","list_view":"list.html","article_view":"message.html","seo_title":"","seo_keywords":"","seo_description":"","type":"1","level":1},{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":7,"pid":2,"name":"mysql","pinyin":"mysql","path":"/mysql","sort":8,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1}]

friendlink-> [{"id":1,"title":"ChanCMS","link":"https://www.chancms.top","sort":0,"createdAt":"2023-07-22T14:59:55.000Z","updatedAt":"2024-04-04T00:55:24.000Z"}]

base_url-> /public/template/default

frag--->{"homeSlide":"<p><img src=\"/public/template/angke/img/banner.jpg\" alt=\"\"></p>","footer-guanyu":"<div class=\"col-6\">\n<h4 class=\"f-15 pb-10\">关于</h4>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">关于我们</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">最新动态</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">联系作者</a></p>\n</div>","footer-chanyue":"<div class=\"col-6\">\n<h4 class=\"f-15 pb-10\">ChanCMS</h4>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">文档</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">视频</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">模板</a></p>\n</div>","footer-nodejs":"<div class=\"col-6\">\n<h4 class=\"f-15 pb-10\">nodejs</h4>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">express</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">mysql</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">knex</a></p>\n</div>","footer-fe":"<div class=\"col-6\">\n<h4 class=\"f-15 pb-10\">前端</h4>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">JavaScript</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">vue2/vue3</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">react18</a></p>\n<p class=\"f-13 pt-3 pb-3\"><a class=\"c-595959\">css3</a></p>\n</div>","chanyue-introduce":"<h3 class=\"m-title border-dashed f-16 row justify-between\">ChanCms</h3>\n<p class=\"mt-10 f-14 lh-24\">ChanCms内容管理系统,基于nodejs、express、mysql、 knex、jwt、vue3、element-plus 进行开发的一套实用轻量cms系统,同时支持无头cms和模板共存,为需要SEO的网站提供模板支持,为app 、wap、微信小程序提供丰富的接口。满足于常用企业网站,微信小程序,图片网站,新闻资讯,软件下载网站,博客,文章等诸多文章类型网站开发,经过多年开发和升级迭代,是nodejs开发者最佳选择之一。<a title=\"\" href=\"https://www.chancms.top\" target=\"_blank\" rel=\"noopener\">[详情]</a></p>","copyright":"<p class=\"f-13 text-c c-bfbfbf\">自豪的采用 <a href=\"https://www.chancms.top\" target=\"_blank\" rel=\"noopener\">ChanCMS</a></p>","ad":"<p>ChanCMS是一款基于Express(一个流行的Node.js web应用框架)和MySQL(一个广泛使用的开源关系型数据库管理系统)构建的轻量级、高质量内容管理系统(CMS)。以下是对这款CMS系统可能具备的特性和功能的概述:</p>\n<ol>\n<li>\n<p><strong>轻量化架构</strong>:ChanCMS采用Express作为后端框架,以其简洁、灵活、高效的特性实现快速响应的API开发。结合MySQL数据库,提供稳定、高效的数据存储与查询能力。整体设计注重性能优化和资源高效利用,确保系统在有限的硬件资源下仍能保持良好的运行效率。</p>\n</li>\n<li>\n<p><strong>模块化设计</strong>:系统采用模块化架构,各功能模块如用户管理、权限控制、内容发布、媒体管理、模板引擎等独立且可扩展,便于开发者根据实际需求进行定制和二次开发。</p>\n</li>\n<li>\n<p><strong>内容管理</strong>:提供便捷的内容编辑、分类、标签管理功能,支持富文本编辑器,方便用户创建、编辑和发布各类图文、视频等内容。满足不同内容管理场景需求。</p>\n</li>\n<li>\n<p><strong>用户与权限管理</strong>:内置完善的用户注册、登录、角色分配及权限控制系统。支持多用户协作,可根据角色设定不同的操作权限,确保系统数据安全。</p>\n</li>\n<li>\n<p><strong>SEO友好</strong>:内置SEO优化机制,支持自定义页面标题、描述、关键词等SEO元素,生成利于搜索引擎收录的URL结构,提升网站在搜索引擎中的排名。</p>\n</li>\n<li>\n<p><strong>模板与主题系统</strong>:采用灵活的模板引擎,支持自定义前端主题和布局,允许用户或设计师根据品牌风格轻松调整网站外观,无需深入代码即可实现界面个性化。</p>\n</li>\n<li>\n<p><strong>插件与扩展</strong>:提供插件接口,用户或开发者可以开发并安装各种功能插件,如评论系统、统计分析、社交媒体集成等,以扩展系统的功能,满足多样化需求。</p>\n</li>\n<li>\n<p><strong>API支持</strong>:提供RESTful API接口,方便与其他系统(如移动应用、第三方服务等)进行数据交互和集成。</p>\n</li>\n<li>\n<p><strong>文档与社区支持</strong>:提供详尽的用户手册、开发者文档以及活跃的技术社区支持,帮助用户快速上手、解决问题并持续学习。</p>\n</li>\n</ol>\n<p data-spm-anchor-id=\"5176.28103460.0.i5.297c3f99fjQmkZ\">综上所述,ChanCMS作为一款基于Express+MySQL的轻量级CMS管理系统,以其灵活、易用、可扩展的特性,<span>它具备多种类型网站开发,公司,企业,学校,政府,图片,下载,产品等各类型网站建设。</span></p>"}

tag--->[{"id":11,"name":"mysql","path":"mysql"},{"id":10,"name":"react","path":"react"},{"id":9,"name":"vue","path":"vue"},{"id":8,"name":"js","path":"js"},{"id":7,"name":"css","path":"css"},{"id":6,"name":"nodejs","path":"nodejs"},{"id":1,"name":"ChanCMS","path":"ChanCMS"}]

position------>[{"id":2,"pid":0,"name":"nodejs","pinyin":"nodejs","path":"/nodejs","sort":3,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","children":[{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},{"id":7,"pid":2,"name":"mysql","pinyin":"mysql","path":"/mysql","sort":8,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1}],"level":1},{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1}]

navSub------>{"cate":{"id":6,"pid":2,"name":"express","pinyin":"express","path":"/nodejs/express","sort":7,"target":"0","status":"0","list_view":"list.html","article_view":"article.html","seo_title":"","seo_keywords":"","seo_description":"","type":"0","level":1},"id":6}

article------>{"id":84,"cid":6,"sub_cid":null,"title":"基于express封装轻量级mvc框架chanjs","short_title":"","tag_id":"","attr":"","seo_title":"","seo_keywords":"","seo_description":"","source":"","author":"","description":"","img":"","content":"<h2>背景</h2>\n<p>基于国内koa2封装的thinkjs和eggjs基本都黄了,或者不更新了。而且koa2的市场占有量的确不如express,加上本人不喜欢typescript和nestjs风格,所以就想实现一个mvc框架。</p>\n<h2>chanjs介绍</h2>\n<p>Chanjs 基于express 纯js研发的轻量级mvc框架。基于函数式编程思想,性能优越,代码清晰,流程易读,可持续维护高。</p>\n<p>核心功能</p>\n<p>配置文件多模块mvc数据库支持路由控制art-template模板静态资源cookie日志功能参考</p>\n<p>thinkjs多模块eggjs约定优于配置原则约定结构</p>\n<pre class=\"language-markup\"><code>|- app\n\n|- config 配置\n\n|- module 模块1\n\n|- module1 模块1\n\n|- controller 控制器\n\n|- service 服务模型\n\n|- view 视图模板\n\n|- router.js 路由\n\n|- module2 模块2\n\n|- controller 控制器\n\n|- service 服务模型\n\n|- view 视图模板\n\n|- router.js路由\n\n|- extend 扩展\n\n|- middleware 中间件\n\n|- plugin 插件\n\n|- public 静态文件\n\n|- index.js</code></pre>\n<p>初始化流程</p>\n<p>框架加载默认约定结构,动态加载模块,分为以下几个流程:</p>\n<pre class=\"language-markup\"><code>- 初始化\n\n- 加载配置\n\n- 加载模块\n\n- 加载service\n\n- 加载controller\n\n- 加载router\n\n- 加载extend\n\n- 加载plugin\n\n- beforeStart() 挂在从数据库获取的配置合并到配置文件中\n\n- run() 启动服务</code></pre>\n<p>核心代码实现</p>\n<pre class=\"language-javascript\"><code>const express = require(\"express\");\n\nconst config = require(\"./lib/config/config.js\");\n\nconst path = require(\"path\");\n\nconst fs = require(\"fs\");\n\nconst core = require(\"./lib/core.js\");\n\n/**\n\n* @description 基于express封装的mvc框架,遵循约定优于配置原则\n\n*/\n\nclass Chan {\n\nconstructor(options={}) {\n\n//配置\n\nChan.config = Object.assign(config, options);\n\n//模块\n\nChan.modules ={};\n\n//工具\n\nChan.helper ={};\n\n//应用实例\n\nthis.app = express();\n\nthis.app.config = Chan.config;\n\nthis.router = express.Router();\n\n//加载配置\n\nthis.loadConfig();\n\n//加载扩展\n\nthis.loadExtends();\n\n//加载核心(日志、favicon 图标、cookie、json、url、模板引擎、静态资源)\n\nthis.loadCore();\n\n//加载实例化数据库\n\nthis.loadKnex();\n\n//生命周期钩子:开始启动\n\nthis.beforeStart();\n\n//加载模块\n\nthis.loadModules();\n\n//生命周期:初始化完成\n\nthis.start()\n\n}\n\n// 加载配置\n\nloadConfig() {\n\nconst configPath = path.join(config.APP_PATH, \"config/index.js\");\n\nif (fs.existsSync(configPath)) {\n\nconst config = require(configPath);\n\nChan.config = Object.assign(Chan.config, config);\n\n}\n\n}\n\n// 加载扩展\n\nloadExtends() {\n\nconst extendPath = path.join(config.APP_PATH, \"extend\");\n\nif (fs.existsSync(extendPath)) {\n\nlet controllers = fs\n\n.readdirSync(extendPath)\n\n.filter((file) => file.endsWith(\".js\"));\n\nfor (let i = 0, file; i < controllers.length; i++) {\n\nfile = controllers[i];\n\nconst helper = require(path.join(extendPath, file));\n\nconst fileName = file.replace(\".js\", \"\");\n\nChan.helper[fileName] = helper;\n\n}\n\n}\n\n}\n\n//数据库操作\n\nloadKnex(){\n\n// 连接数据库\n\nconst {host,port,user,password,database,client,charset} = Chan.config.database;\n\nconst knex = require(\"knex\")({\n\nclient: \"mysql2\",\n\nconnection: {\n\nhost,\n\nport,\n\nuser,\n\npassword,\n\ndatabase,\n\ncharset,\n\n},\n\ndebug: config.debug, //指明是否开启debug模式,默认为true表示开启\n\npool: {\n\n//指明数据库连接池的大小,默认为{min: 2, max: 10}\n\nmin: 0,\n\nmax: 2,\n\n},\n\nlog: {\n\nwarn(message) {\n\nconsole.error(\"[knex warn]\", message);\n\n},\n\nerror(message) {\n\nconsole.error(\"[knex error]\", message);\n\n},\n\n},\n\n});\n\nChan.knex = knex;\n\n}\n\n//开始启动\n\nbeforeStart(cb) {\n\n// 初始化一些配置\n\ncb && cb();\n\n}\n\n//启动\n\nstart(cb){\n\n// 初始化一些配置\n\ncb && cb();\n\n}\n\n// 加载插件\n\nloadPlugins() {\n\nconst configPath = path.join(config.APP_PATH, \"plugin\");\n\nif (fs.existsSync(configPath)) {\n\nconst dirs = fs\n\n.readdirSync(configPath, { withFileTypes: true })\n\n.filter((dirent) => dirent.isDirectory())\n\n.map((dirent) => dirent.name);\n\nthis.plugins = dirs;\n\n} else {\n\nthis.plugins = [];\n\n}\n\n}\n\n/**\n\n* @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源\n\n*/\n\nloadCore(){\n\ncore(this.app);\n\n}\n\n/**\n\n* @description 模块加载入口(路由&控制器& 服务)\n\n*/\n\nloadModules() {\n\nconst configPath = path.join(config.APP_PATH, \"modules\");\n\nif (fs.existsSync(configPath)) {\n\nconst dirs = fs\n\n.readdirSync(configPath, { withFileTypes: true })\n\n.filter((dirent) => dirent.isDirectory())\n\n.map((dirent) => dirent.name);\n\nthis.modulesDir = dirs;\n\nfor(let i=0,item;i \n\nitem = dirs[i];\n\nChan.modules[item] = {\n\ncontroller: {},\n\nservice: {},\n\n};\n\nthis.loadModule(item);\n\n}\n\n//通用路由,加载错误处理和500路由和爬虫处理\n\nconst baseRouterPath = path.join(config.APP_PATH, \"router.js\");\n\nif (fs.existsSync(baseRouterPath)) {\n\nconst _router = require(baseRouterPath);\n\n_router(this.app, this.router);\n\n}\n\n}\n\n}\n\n/**\n\n* @description 加载模块,包括 controller service router\n\n* @param {String} moduleName 模块名称\n\n*/\n\nloadModule(moduleName) {\n\nconst moduleDir = path.join(config.APP_PATH, \"modules\", moduleName);\n\nthis.loadServices(moduleDir,moduleName);\n\nthis.loadControllers(moduleDir,moduleName);\n\nthis.loadRoutes(moduleDir,moduleName);\n\n}\n\n/**\n\n* @description 扫描模块下所有service\n\n* @param {*} moduleDir 模块路径\n\n* @param {*} moduleName 模块名称\n\n*/\n\nloadServices(moduleDir,moduleName) {\n\nconst servicesDir = path.join(moduleDir, \"service\");\n\nif (fs.existsSync(servicesDir)) {\n\nlet services = fs\n\n.readdirSync(servicesDir)\n\n.filter((file) => file.endsWith(\".js\"));\n\nfor (let i = 0, file; i < services.length; i++) {\n\nfile= services[i]\n\nconst Service = require(path.join(servicesDir, file));\n\nconst serviceName = file.replace(\".js\", \"\");\n\nChan.modules[moduleName].service[serviceName] = {};\n\nChan.modules[moduleName].service[serviceName] = Service;\n\n}\n\n}\n\n}\n\n/**\n\n* @description 扫描模块下所有controller\n\n* @param {*} moduleDir 模块路径\n\n* @param {*} moduleName 模块名称\n\n*/\n\nloadControllers(moduleDir,moduleName) {\n\nconst controllersDir = path.join(moduleDir, \"controller\");\n\nif (fs.existsSync(controllersDir)) {\n\nlet controllers = fs\n\n.readdirSync(controllersDir)\n\n.filter((file) => file.endsWith(\".js\"));\n\nfor (let i = 0, file; i < controllers.length; i++) {\n\nfile= controllers[i]\n\nconst controller = require(path.join(controllersDir, file));\n\nconst controllerName = file.replace(\".js\", \"\");\n\nChan.modules[moduleName].controller[controllerName] = {};\n\nChan.modules[moduleName].controller[controllerName] = controller;\n\n}\n\n}\n\n}\n\n/**\n\n* @description 扫描模块下所有router.js\n\n* @param {*} moduleDir 模块路径\n\n* @param {*} moduleName 模块名称\n\n*/\n\nloadRoutes(moduleDir,moduleName) {\n\nconst routersDir = path.join(moduleDir, \"router.js\");\n\nif (fs.existsSync(routersDir)) {\n\nconst routes = require(routersDir);\n\nroutes({router:this.router,modules:Chan.modules,app:this.app});\n\n}\n\n}\n\nloadPlusins() {\n\n// 加载插件\n\n}\n\nrun(port) {\n\nthis.app.listen(port, () => {\n\nconsole.log(`Server is running on port ${port}`);\n\n});\n\n}\n\n}\n\nmodule.exports = Chan;</code></pre>\n<h2>案例</h2>\n<p></p>\n<p>基于chanjs实现chancms管理系统。</p>\n<p>禅CMS是一款基于Express和MySQL研发的高质量实用型CMS管理系统。它具备多种类型网站开发,易扩展、基于模块化和插件化开发模式,适用于商用企业级程序开发。</p>","status":0,"pv":88,"link":"","createdAt":"2024-04-04 08:56:42","updatedAt":"2024-09-18 13:11:08","field":{},"tags":[]}

article.tags------>[]

news------>[{"id":84,"title":"基于express封装轻量级mvc框架chanjs","short_title":"","img":"","createdAt":"2024-04-04T00:56:42.000Z","description":"","pinyin":"express","name":"express","path":"/nodejs/express"}]

hot------>[{"id":84,"title":"基于express封装轻量级mvc框架chanjs","path":"/nodejs/express"}]

imgs------>[]

pre------>

next------>