# Monk.Node **Repository Path**: KingRain.NET/Monk.Node ## Basic Information - **Project Name**: Monk.Node - **Description**: 基于 Node.JS 一套 Web MVC 应用解决方案。 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 88 - **Created**: 2017-01-13 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Monk.Node Monk.Node:基于 Node.JS 一套 Web MVC 应用解决方案。 ## 作者信息 - 原创作者:`百小僧` - 开源协议:`MIT License` - 开发时间:`2016年12月06日` - 当前版本:`2.2.7`,2017年01月12日 - 项目名称:`Monk.Node` - 版权所有:[百签软件(中山)有限公司](http://www.baisoft.org) - 联系方式:QQ群:`18863883`,作者QQ:`8020292` - 开发理念:`一切从简,只为了更懒` - 码云地址:[http://git.oschina.net/baisoft_org/Monk.Node](http://git.oschina.net/baisoft_org/Monk.Node) - Github :[https://github.com/MonkSoul/Monk.Node](https://github.com/MonkSoul/Monk.Node) ## 框架特点 - 基于Node.js平台开发,Javascript作为主要编写语言 - 极易入门,前后端开发者都能快速上手 - 目录清晰,代码规范 - 采用目前主流的MVC思想编写,并支持多区域,多站点开发(**这是Express 4.x 所没有的**) - 底层采用主流的Express.js 4.x Web框架进行开发,拓展性极强,第三方模块丰富,并完全兼容Express.js 4.x功能 - 集成强大的Nodejs数据库ORM组件:Sequelize.js,支持目前所有主流数据库 - 集成强大的ejs模板引擎 - 支持强大的全局数据注入器(**类似ASP.NET MVC中的ViewData**) - 支持日志记录,日志输出 - 支持多视图设置(**这是Express 4.x 所没有的**) - 支持跨域 - 支持typescript编写 - 支持Session,Cookies会话操作 - 支持RESTful API开发 - 支持过滤器,中间件,支持权限控制再也不是什么难题 - 支持redis存储 - 支持实时通信WebSocket开发,已集成主流的Socket.io模块 - 支持文件上传 - 支持数据库表模型生成工具 - 支持开发、测试、生成环境数据库切换 - 安全性高,防止CSURF攻击 - 拓展性强,完美支持Node.js原生模块 - 更多强大功能后续陆续集成 ## 视频教程 1. [Monk.Node 简介&安装](http://url.cn/42W06hK) 2. [Monk.Node 控制器](http://url.cn/42W06hK) 3. [Monk.Node 视图引擎](http://url.cn/42W06hK) 4. [Monk.Node 区域](http://url.cn/42W06hK) 5. [Monk.Node 静态资源](http://url.cn/42W06hK) **(项目已调整,请按照最新文档)** 6. [Monk.Node 模型](http://url.cn/42W06hK) 7. [Monk.Node ORM](http://url.cn/42W06hK) 8. [Monk.Node 会话](http://url.cn/42W06hK) 9. [Monk.Node 过滤器](http://url.cn/42W06hK) 10. [Monk.Node 文件上传](http://url.cn/42W06hK) 11. Monk.Node Redis(未更新) 12. Monk.Node WebSocket(未更新) 13. Monk.Node 入口文件(未更新) 14. Monk.Node RESTful(未更新) ## 更新记录 ``` ============ 2017.01.12 V2.2.7 ============ - [更新] package.json依赖模块 ============ 2016.12.23 V2.2.6 ============ - [更新] app.js 入口文件,将ejs模板引擎文件名改为.html(重点更新) ============ 2016.12.22 V2.2.5 ============ - [新增] locals文件夹,定义全局数据注入,类似ASP.NET MVC的ViewData数据 - [新增] utils/locals.js 模块,全局注入核心模块 - [更新] app.js 核心代码,使其支持全局数据注入 - [更新] utils/route.js 模型,使其支持局部数据注入 - [更新] 使用文档 - [更新] sequelize模块 - [更新] debug模块 - [优化] utils/route.js代码 - [修复] 表单 enctype="multipart/form-data" 数据无法获取问题 ============ 2016.12.20 V2.2.3 ============ - [新增] utils/route.js 默认路由区域设置,默认控制器,默认Action路由支持 如:http://localhost:3000 == http://localhost:3000/frontend == http://localhost:3000/frontend/home == http://localhost:3000/frontend/home/index - [更新] app.js 核心代码 - [更新] multer 文件上传模块 - [更新] debug 调试模块 - [优化] utils/route.js 核心代码 - [删除] app.js 默认首页设置代码,调整为默认区域设置,默认首页由 默认区域,默认控制器,默认Action组成 - [修复] utils/route.js 路由解析 由于node.js版本低导致路由解析报404错误 - [修复] 文档错误问题 ============ 2016.12.16 V2.2.1 ============ - [新增] 验证码模块,并编写验证码类库:utils/captcha.js - [新增] 验证码演示示例,http://localhost:3000/backend/ - [删除] 删除所有区域下的assets资源文件 - [删除] core文件夹,并将db.js,route.js转移到utils目录下 - [更新] 错误提示页面,显示更多错误信息 - [更新] 设置根目录下的public为资源文件,保持和express.js兼容 (重要调整) - [更新] core/db.js 加载模块代码,新增可配置的加载项 - [更新] 基本示例 - [更新] 静态资源文档 ============ 2016.12.15 V2.1.2 ============ - [新增] 数据库操作db全局对象,无需通过 require进来了(**重点更新**) - [新增] utils/gmodels/js 模块 - [新增] 轻量级的images库,支持图片处理,包括水印,调整大小等等 - [新增] 定时任务node-schedule模块 - [新增] 邮件发送nodemailer模块 - [新增] lodash模块,提供非常方便的JavaScript工具操作库 - [新增] 视频教程 - [优化] 路由核心类库 - [更新] debug模块 - [更新] app.js 错误日志保存方法,以天为单位 - [更新] 默认示例 - [更新] ORM文档 ============ 2016.12.14 V2.1.1 ============ - [优化] 全面优化app.js 代码 - [新增] 全局路由过滤器 - [重构] 重构express.js单视图引擎,实现多视图引擎 - [更新] 目录结构,移除根目录下的assets,views文件夹,新增share文件夹 - [更新] postgres 版本 - [更新] socket.io 版本 - [更新] 使用文档 - [修复] Session和Cookie无作用bug - [修复] core/db.js 加载模型错误 ============ 2016.12.13 V2.0.1 ============ - [新增] cors跨域支持 - [新增] 防止csurf攻击支持,提供更安全的开发环境 - [新增] typescript 支持,可以用typescript开发nodejs模块 - [新增] logs/access和logs/error 用于保存日志记录 - [新增] 写入访问日志功能 - [新增] 写入错误日志功能 - [新增] 日志切割功能 - [新增] 支持日志写入文件和写入数据库功能 - [新增] package.json模块依赖 file-stream-rotator - [优化] app.js 入口文件,提高访问性能 - [更新] 控制台日志输出为combined,之前版本为dev - [更新] 开发文档,新增防止CSURF攻击示例 ============ 2016.12.10 V2.0.0 ============ - [新增] app.js 入口文件默认应用首页设置 - [新增] 支持设置默认控制器,默认Action - [新增] 区域目录,支持多站点项目开发,默认包含backend(后台),frontend(前台)两个区域 - [新增] core文件夹,将models/index.js模块移动到core/db.js模块 - [调整] public名称为assets,,默认包含backend(后台),frontend(前台),vendor(第三方插件)三个资源目录 - [调整] views视图子目录,默认包含backend(后台),frontend(前台)两个区域视图 - [调整] utils/socketServer.js名称为utils/socket.js - [优化] app.js 代码,提高加载性能,只支持设置默认区域,默认控制器,默认Action - [去除] express-controller模块,通过自定义实现更强大的功能 ============ 2016.12.08 V1.0.2 ============ - [新增] 即时通讯、聊天示例(推荐) - [新增] socket.io 支持 - [新增] redis 支持 - [新增] multer 文件上传 - [新增] uploads 文件夹 - [优化] app.js 入口文件 端口和静态文件,用户上传文件代码 - [优化] 代码注释,代码架构 - [修复] package.json 中 mysql依赖包错误 ============ 2016.12.07 V1.0.1 ============ - [新增] 演示站点 - [新增] 默认控制器,默认控制器为Home,默认行为为Index - [新增] model代码生成器 - [新增] package.json 依赖 sequelize-auto - [优化] 目录解构 - [修复] app.js 入口文件bug ============ 2016.12.06 V1.0.0 ============ - [发布] v1.0.0 版本 ``` ## 目录结构 初始化目录结构 ``` www WEB部署目录 ├─area 区域目录 │ ├─backend 后台区域目录 │ │ ├─controllers 后台控制器目录 │ │ │ ├─homeController.js 后台默认控制器 │ │ ├─views 后台视图目录 │ ├─frontend 前台区域目录 │ │ ├─controllers 前台控制器目录 │ │ │ ├─homeController.js 前台默认控制器 │ │ ├─views 前台视图目录 │ ├─tools 工具区域目录 │ │ ├─controllers 前台控制器目录 │ │ │ ├─generateController.js 数据库模型生成 控制器 │ │ ├─views 后台视图目录 ├─config 配置目录 │ ├─db.json 数据库配置文件 ├─filters 过滤器,中间件目录 ├─locals 全局数据注入目录,支持.json文件和.js模块 ├─logs 日志保存目录 │ ├─access 访问日志 │ ├─error 错误日志 ├─models 数据库表对应模型目录 ├─public 静态资源目录 │ ├─favicon.ico 网站收藏图标 ├─uploads 用户上传文件存放目录 ├─utils 工具类库目录 │ ├─socket.js Socket.io 服务器演示代码 │ ├─db.js 数据库模型操作核心库 │ ├─route.js 路由解析核心库 ├─app.js 入口文件 ├─package.json 包配置文件 ``` ## 使用教程 ### 安装 - `git` 方式 ``` $ git clone https://git.oschina.net/baisoft_org/Monk.Node.git $ cd Monk.Node $ npm install $ npm start 浏览器:http://localhost:3000/ ``` - `zip` 下载 ``` 浏览器访问:http://git.oschina.net/baisoft_org/Monk.Node $ cd Monk.Node $ npm install $ npm start 浏览器:http://localhost:3000/ ``` ### **全局数据注入(v2.2.5 支持)** 全局数据注入 表示可以在 `locals`目录下定义`.json`或者`.js`模块文件,这个文件中暴露的数据或者接口可以在 **整个请求,整个控制器,整个Action和整个视图模板(ejs)中使用** 例如:在locals文件夹下定义 `setting.js`模块文件 ``` module.exports = { "name": "Monk.Node", "version": "2.2.5", "author": "百小僧", "company": "百签软件(中山)有限公司" }; ``` - 在控制器中的使用:res.locals.文件名 ``` module.exports={ get_index:function(req,res){ var setting=res.locals.setting; // setting就是文件名 var name= setting.name; // => Monk.Node var version= setting.version; // => 2.2.5 } }; ``` - 在视图页面ejs中使用 _locals.文件名 ``` <%=_locals.setting.name %> <%=_locals.setting.version %> <%=_locals.setting.company %> ``` 当然,我们也可以定义局部数据注入,局部数据注入通常在`action`中定义的 ``` module.exports={ get_index:function(req,res){ res.locals.abc="我是局部的。。。。。"; } }; ``` - 在视图页面ejs中使用 ``` <%=_locals.abc %> ``` 全局数据注入使用非常灵活,可以结合数据库操作,最终通过 `module.exports`返回`json对象`数据即可 ### 入口配置 - 设置视图模板引擎 ``` app.set('view engine', 'ejs'); ``` - 设置静态资源目录 ``` app.use(express.static(path.join(__dirname, 'public'))); ``` - 设置Cookie,Session配置信息 ``` // cookie处理 app.use(cookieParser()); // session处理 app.use(session({ secret: 'monknode', cookie: { maxAge: 60000 }, resave: true, saveUninitialized: true })); ``` - 设置默认区域,控制器,Action目录及路由 ``` // 设置控制器文件夹并绑定到路由 resolve .setRouteDirectory({ areaDirectory: __dirname + '/areas', controllerDirname: 'controllers', defautController: 'home', defautAction: 'index' }) .bind(router); ``` - 设置404,500错误处理 ``` // 错误处理 // 404处理 app.use(function (req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // 错误或者服务器500异常处理 app.use(function (err, req, res, next) { var error = (req.app.get('env') === 'development') ? err : {}; //写错误日志 var errorMes = '[' + Date() + ']' + req.url + '\n' + '[' + error.stack + ']' + '\n'; errorLogStream.write(errorMes); var status = err.status || 500; res.status(status); res.send('
' + status + ' ' + err.message + '\n' + errorMes + ''); }); ``` - 设置网站监听端口,默认是`3000` ``` app.set('port', process.env.PORT || 3000); ``` - 设置WebSocket启动,并设置服务端处理逻辑 ``` require(path.join(__dirname, 'utils', 'socket')).listen(server); ``` ### 区域 > 区域是对网站和代码进行高度组装,如前台,后台。目前区域只支持控制器逻辑的编写。 - 新增区域 只需要在 `areas`目录下创建一个文件夹即可,并在此文件夹下创建`controllers`目录。如:`areas/api/controllers` 默认已经包含`backend`(后台),`frontend`(前台)两个区域 - 访问区域,默认访问的是 `homeController`控制器中的`get_index` Action。 ``` http://localhost:3000/backend/ http://localhost:3000/frontend/ http://localhost:3000/api/ ``` ### 控制器 > 控制器是整个框架能够在浏览器上正确访问的基础单元,可以说是灵魂。注:控制器中命名为`homeController`的控制器为默认控制器,该控制器中的`get_index`为默认Action,此控制器有且只能包含一个Action,也就是`get_index` - 创建控制器,控制器文件命名必须以`Controller`结尾,如在`frontend`区域中添加`controllers/aboutController.js` ``` module.exports={ }; ``` - 在控制器中创建Action,也就是路由,路由遵循 `method_action`格式。在`aboutController.js`中定义 ``` module.exports={ // 访问地址:http://localhost:3000/frontend/about/ get_index:function(req,res){ res.send("ok"); }, // 提交地址:http://localhost:3000/frontend/about/create post_create:function(req,res){ res.send("ok"); }, // 访问地址:http://localhost:3000/frontend/about/company/baisoft get_company_baisoft:function(req,res){ res.send("ok"); }, // 访问地址:http://localhost:3000/frontend/about/company/10 get_company_id:function(req,res,id){ res.send("ok") }, // 访问地址:http://localhost:3000/frontend/about/company/10/百小僧 get_company_id_name:function(req,res,id,name){ res.send("ok"); }, // 访问地址:http://localhost:3000/frontend/about/百小僧/company get_name_company:function(req,res,name){ res.send("ok"); }, // 过滤器 get_admin:[function(req,res,next){ if(未登录){ res.redirect("登录页面"); } else{ next(); } },function(req,res){ res.send("ok"); }], // 多个过滤器 get_admin:[function(req,res,next){ console.log("日志记录"); next(); },function(req,res,next){ if(未登录){ res.redirect("登录页面"); } else{ next(); } },function(req,res){ res.send("ok"); }], }; ``` ### 视图模板引擎 > 视图模板引擎采用的是`ejs`模板引擎,默认视图目录为:区域下的`views`文件夹。[ejs详细文档](https://www.npmjs.com/package/ejs) - 基础语法 ``` <% if (user) { %>
第 ' + req.session.isVisit + '次来此页面
'); } else { req.session.isVisit = 1; res.send("欢迎第一次来这里"); console.log(req.session); } } } ``` - Cookies 使用 ``` module.exports={ get_index:function(req,res){ // 如果请求中的 cookie 存在 isVisit, 则输出 cookie // 否则,设置 cookie 字段 isVisit, 并设置过期时间为1分钟 if (req.cookies.isVisit) { console.log(req.cookies); res.send("再次欢迎访问"); } else { res.cookie('isVisit', 1, {maxAge: 60 * 1000}); res.send("欢迎第一次访问"); } } } ``` ### 过滤器、中间件 > 过滤器,中间件主要对请求进行过滤的 - 在控制器中直接使用 ``` module.exports={ get_admin:[function(req,res,next){ if(未登录){ res.redirect("登录页面"); } else{ next(); } },function(req,res){ res.send("ok"); }] }; ``` - 全局过滤器,将过滤器定义到`filters`文件夹下,如创建一个`loginFilter.js` ``` module.exports = function (req, res, next) { if(未登录){ res.redirect("登录页面"); } else{ next(); } }; ``` 在控制器中使用 ``` var loginFilter = require("../../../filters/loginFilter"); module.exports={ get_admin:[loginFilter,function(req,res){ res.send("ok"); }] } ``` - 多个过滤器 ``` module.exports={ get_admin:[function(req,res,next){ console.log("日志记录"); next(); },function(req,res,next){ if(未登录){ res.redirect("登录页面"); } else{ next(); } },function(req,res){ res.send("ok"); }] }; ``` ### 表单提交 - 视图布局: ```