Node.js 国产 MVC 框架 ThinkJS 开发 入门
2017-07-14 00:00
1041 查看
ThinkJS (官网 https://thinkjs.org) 是一款非常优秀的 Node.js 国产 MVC 开发框架,下面摘自官网的介绍:
ThinkJS 是一款使用 ES6/7 特性全新开发的 Node.js MVC 框架,使用 ES7 中 async/await,或者 ES6 中的 */yield 特性彻底解决了 Node.js 中异步嵌套的问题。同时吸收了国内外众多框架的设计理念和思想,让开发 Node.js 项目更加简单、高效。
使用 ES6/7 特性来开发项目可以大大提高开发效率,是趋势所在。并且新版的 Node.js 对 ES6 特性也有了较好的支持,即使有些特性还没有支持,也可以借助 Babel 编译来支持。
目前 ThinkJS 版本发布到了 v2.2.19 (更新日志),并且 v3.0beta 版本已经进入公测阶段。
本系列教程以 v2.x 版本为例进行介绍,教程以实际操作为主,ThinkJS 的安装详见官网文档说明。
原创:荆秀网 网页即时推送 https://xxuyou.com | 转载请注明出处
链接:https://blog.xxuyou.com/nodejs-thinkjs-study-start/
官网提供了创建一个空项目,以及空项目的代码结构介绍,这里不再赘述。以下是一些官网没有提到的小技巧,先做个了解~
新项目
为了确保用户错误操作导致现有文件被覆盖,thinkjs new命令仅适用于文件夹不存在的,或者空文件夹。否则会收到类似如下的错误提示:
path `/data/www/demo` is already a thinkjs project.
实现这一特性其实是依赖一个项目根目录下的隐藏文件
.thinkjsrc,使用
ls -a可以查看隐藏文件,打开这个文件可以看到如下内容:
{ "createAt": "2017-02-12 19:08:38", "mode": "module", "es": true }
按模块分解
创建项目之后,基本的代码框架已经建立起来了(详见 https://thinkjs.org/zh-cn/doc/2.2/app_structure.html),其中默认的home和
common肯定是无法满足要求的。我们需要给自己的项目建立起相关的层次结构。
以下是几个较为典型的项目模块结构参考。
简单网站
例如官方网站、博客、社区等,这类系统结构较为简单,通常一个前端一个后端管理即可满足要求。模块结构如下:
src/ src/common/ # 通用模块,放置主配置参数、boostrap adapter middleware service 等相关组件 src/home/ # 前端默认模块 src/backend/ # 后端管理模块 src/util/ # 系统工具类
电商平台
电商平台系统主要考虑到入驻的商户、注册的客户、管理人员、运营人员等使用人群,还需要考虑到较大的功能模块切分(如果足够大到类似京东、天猫那种体量的系统,则需要进行数据、功能、服务、位置等角度的分割)。模块结构如下:
src/ src/common/ src/home/ src/sso/ # 单点登录、令牌管理等 src/rest/ # 针对Wap、App等多客户端的 rest api src/goods/ # 商品管理及服务 src/storage/ # 库存管理及服务 src/cart/ # 购物车 src/order/ # 订单 src/delivery/ # 快递 src/pay/ # 在线支付、空中支付 src/member/ # src/coupon/ # 电子券 src/promotion/ # 促销 src/points/ # 积分 src/merchant/ # 入驻商户 src/shop/ # 商户门店 src/finance/ # 财务核算及款项清算 src/stat/ src/log/ src/monitor/ src/util/ src/task/ src/message/ # 消息队列
即时消息平台
实时推送平台不仅仅要处理 WebSocket 连接和消息囤积发送,还要处理多用户购买相应服务套餐、统计连接数、统计下行流量、进行连接鉴权等,Firebase、野狗、荆秀即时推送 等都是这类的服务商。模块结构如下:
src/ src/common/ src/home/ src/rest/ src/storage/ src/websocket/ # ws 或者 wss 服务 src/webhook/ # 钩子服务 src/middleware/ # 搭载中间件运行 src/pay/ src/member/ src/stat/ src/log/ src/monitor/ src/util/ src/message/ # 消息队列
代驾、租车运营平台
代驾、租车、共享单车等平台需要解决的是资源(客户、车、目的地)定位、路线计算、实时定点跟踪、GPS围栏监测等技术问题,然后才是商务行为的电子化处理。模块结构如下:
src/ src/common/ src/home/ src/rest/ src/map/ # 地图资源、路线计算、电子围栏运算 src/storage/ src/websocket/ # 实时消息传递 src/pay/ src/member/ src/driver/ src/assets/ # 资源费效评估 src/stat/ src/log/ src/math/ # 计算服务 src/monitor/ src/util/
在线教育、直播平台
在线教育或直播平台通常具备实时音视频上传、转码、存储、广播等硬性要求,因此系统除了管理相关课件、学生、教师、选课等,还要负责处理相关媒体文件。模块结构如下:
src/ src/common/ src/home/ src/rest/ src/sso/ # 单点登录、令牌管理等 src/media/ # 课件、音视频等媒体文件 src/bulk/ # 流媒体 src/process/ # 编解码处理 src/storage/ src/live/ # 直播 src/pay/ src/student/ src/teacher/ src/schedule/ src/stat/ src/log/ src/monitor/ src/util/ src/task/ src/message/ # 消息队列
注:以上结构为示例,并不具备通用性,研发时应当需要根据实际情况进行设计或调整。
项目模式
项目模式其实官网有介绍,但是太过简略,基本上是一笔带过。看看如下两种创建 thinkjs 项目的方式:# 用 mode 参数创建一个简单结构项目 thinkjs new thinkjs_normal --mode=normal # 无 mode 参数创建一个较为复杂结构的项目 thinkjs new thinkjs_module
两者创建的项目结构区别其实很简单:
normal mode 的结构直接把
config
controller
logic
model提到
src下面,因此适用于一个简单的网站系统。
module mode 则建立了基本的
home和
common两个应用模块,显然是为了较为复杂、多人协作的中大型项目进行的逻辑分割。
thinkjs_normal 项目结构
thinkjs_normal/package.json thinkjs_normal/.babelrc thinkjs_normal/.thinkjsrc thinkjs_normal/nginx.conf thinkjs_normal/pm2.json thinkjs_normal/.gitignore thinkjs_normal/README.md thinkjs_normal/www thinkjs_normal/www/development.js thinkjs_normal/www/production.js thinkjs_normal/www/testing.js thinkjs_normal/www/README.md thinkjs_normal/www/static thinkjs_normal/www/static/js thinkjs_normal/www/static/css thinkjs_normal/www/static/img thinkjs_normal/src thinkjs_normal/src/bootstrap thinkjs_normal/src/bootstrap/middleware.js thinkjs_normal/src/bootstrap/global.js thinkjs_normal/src/config thinkjs_normal/src/config/config.js thinkjs_normal/src/config/view.js thinkjs_normal/src/config/db.js thinkjs_normal/src/config/hook.js thinkjs_normal/src/config/session.js thinkjs_normal/src/config/error.js thinkjs_normal/src/config/env thinkjs_normal/src/config/env/development.js thinkjs_normal/src/config/env/testing.js thinkjs_normal/src/config/env/production.js thinkjs_normal/src/config/locale thinkjs_normal/src/config/locale/en.js thinkjs_normal/src/controller thinkjs_normal/src/controller/error.js thinkjs_normal/view thinkjs_normal/view/error_400.html thinkjs_normal/view/error_403.html thinkjs_normal/view/error_404.html thinkjs_normal/view/error_500.html thinkjs_normal/view/error_503.html thinkjs_normal/src/controller/base.js thinkjs_normal/src/controller/index.js thinkjs_normal/src/logic thinkjs_normal/src/logic/index.js thinkjs_normal/src/model thinkjs_normal/src/model/index.js thinkjs_normal/view/index_index.html
thinkjs_module 项目结构
thinkjs_module/package.json thinkjs_module/.babelrc thinkjs_module/.thinkjsrc thinkjs_module/nginx.conf thinkjs_module/pm2.json thinkjs_module/.gitignore thinkjs_module/README.md thinkjs_module/www thinkjs_module/www/development.js thinkjs_module/www/production.js thinkjs_module/www/testing.js thinkjs_module/www/README.md thinkjs_module/www/static thinkjs_module/www/static/js thinkjs_module/www/static/css thinkjs_module/www/static/img thinkjs_module/src thinkjs_module/src/common/bootstrap thinkjs_module/src/common/bootstrap/middleware.js thinkjs_module/src/common/bootstrap/global.js thinkjs_module/src/common/config thinkjs_module/src/common/config/config.js thinkjs_module/src/common/config/view.js thinkjs_module/src/common/config/db.js thinkjs_module/src/common/config/hook.js thinkjs_module/src/common/config/session.js thinkjs_module/src/common/config/error.js thinkjs_module/src/common/config/env thinkjs_module/src/common/config/env/development.js thinkjs_module/src/common/config/env/testing.js thinkjs_module/src/common/config/env/production.js thinkjs_module/src/common/config/locale thinkjs_module/src/common/config/locale/en.js thinkjs_module/src/common/controller thinkjs_module/src/common/controller/error.js thinkjs_module/view/common thinkjs_module/view/common/error_400.html thinkjs_module/view/common/error_403.html thinkjs_module/view/common/error_404.html thinkjs_module/view/common/error_500.html thinkjs_module/view/common/error_503.html thinkjs_module/src/home/config thinkjs_module/src/home/config/config.js thinkjs_module/src/home/controller thinkjs_module/src/home/controller/base.js thinkjs_module/src/home/controller/index.js thinkjs_module/src/home/logic thinkjs_module/src/home/logic/index.js thinkjs_module/src/home/model thinkjs_module/src/home/model/index.js thinkjs_module/view/home thinkjs_module/view/home/index_index.html
配置参数
官网是这么描述配置文件加载顺序的:框架默认的配置 -> 项目模式下框架配置 -> 项目公共配置 -> 项目模式下的公共配置 -> 模块下的配置
先问个问题:这五个配置都指的是哪里呢?
前两个可以忽略掉,那是 thinkjs 框架自身的配置设置,通常里面不会有我们项目会用到的配置参数。
第三个和第四个则是在不同的项目创建模式下的默认 config 配置文件夹,位置在:
# normal mode thinkjs_normal/src/config/* # module mode thinkjs_module/src/common/config/*
最后一个是指的在 module mode 下的项目,每个 module 自己的 config,位置在:
thinkjs_module/src/home/config/*
明白了多个地方多个配置文件的玩法之后,你可以创建多个 module,并给每个 module 配置自身独特的配置参数。
需要注意的是:thinkjs 加载配置文件是有顺序的![b]回到本节一开始提到的加载顺序,你应当明白:多个配置文件最终会在 thinkjs 运行时被全部加载,并合并在一起[/b](注意加粗文字)。
所以当存在多个配置文件时,需要注意配置参数的 key(即属性名)尽量不要重复,因为按照加载顺序,后加载的 key 的值会覆盖先加载的 key 的值,导致出现不希望的结果。
举例来说,有两个配置文件
src/common/config/assets.js和
src/home/config/assets.js,其中内容是:
// src/common/config/assets.js export default { "site_title": "my site" }; // src/home/config/assets.js export default { "site_title": "my test" }; // src/home/controller/index.js let assets = this.config('assets'); let siteTitle = assets['site_title']; console.log('siteTitle is: ', siteTitle); // my test
注:当然也有办法获取到 "my site" 这个值,后面的教程会提到方法。
公共方法
thinkjs 提供了一个src/common/bootstrap/global.js文件来放置全局变量/函数。
// 可以直接在 global.js 中增加自己定义的函数 global.formatDate = obj => { //... }
如果你的自定义函数很多,想分门别类的组织,也可以在
src/common/bootstrap/文件夹下新增文件来定义函数。当项目启动时,该目录下的文件会自动加载,无需手动 require。
src/common/bootstrap/global_datetime.js src/common/bootstrap/global_math.js src/common/bootstrap/global_string.js
注:thinkjs v3.x 可能会取消
bootstrap,想要升级的朋友们注意了。 ThinkJS v3.x 设计图
Babel 编译时删除注释
开发时的工作代码都在src下面,运行时才会编译到
app下面成为运行脚本(经过 Babel 编译),如果不想自己写的各种注释也出现在
app下面的代码中,可以修改项目目录下的一个隐藏文件
.babelrc增加相应
comments参数。
增加该参数后编译速度会比较慢,因为需要处理的代码内容多了~
{ "presets": [ ["es2015", {"loose": true}], "stage-1" ], "plugins": ["transform-runtime"], "sourceMaps": true, "comments": false # <-- 就是这个参数 }
注:给喜欢在生产服务器就地编译的筒子们。
完善 package.json 字段
package 打包描述文件虽然会被 thinkjs 自动生成,不过如果能够手工维护这个文件,添加必要的属性,会让我们的项目工程更加规范、有序。参考一下 thinkjs v2.x 源码的 package.json 文件:
{ "name": "thinkjs", "description": "ThinkJS - Use full ES6/7 features to develop web applications, Support TypeScript", "version": "2.2.18", "author": { "name": "welefen", "email": "welefen@gmail.com" }, "scripts": { "test": "npm run eslint && npm run test-cov", "test-cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- -t 50000 --recursive -R spec test/", "compile": "babel src/ --out-dir lib/", "watch-compile": "npm run compile -- --watch", "watch": "npm run watch-compile", "prepublish": "npm run compile", "eslint": "eslint src/" }, "bin": { "thinkjs": "./bin/index.js" }, "contributors": [ { "name": "welefen", "email": "welefen@gmail.com" }, { "name": "im-kulikov", "email": "im@kulikov.im" }, { "name": "maxzhang", "email": "zhangdaiping@gmail.com" }, { "name": "akira-cn", "email": "akira.cn@gmail.com" }, { "name": "qgy18", "email": "quguangyu@gmail.com" } ], "main": "lib/index.js", "dependencies": { "ejs": "2.4.1", "multiparty": "4.1.2", "mime": "1.3.4", "mysql": "2.11.1", "thinkit": "4.10.0", "babel-runtime": "6.6.1", "bluebird": "3.3.5", "co": "4.6.0", "colors": "1.1.2", "validator": "4.2.0", "commander": "2.9.0" }, "devDependencies": { "mocha": "1.20.1", "muk": "0.3.1", "istanbul": "0.4.0", "babel-cli": "^6.18.0", "babel-preset-es2015": "^6.18.0", "babel-preset-stage-1": "^6.16.0", "babel-plugin-transform-runtime": "^6.15.0", "babel-core": "^6.20.0", "babel-eslint": "^6.0.4", "eslint": "2.8.0", "typescript": "^2.1.6", "source-map": "0.5.3" }, "keywords": [ "thinkjs", "framework", "web", "rest", "restful", "router", "api", "es6", "es7", "async", "await", "yield", "websocket", "generator-function", "typescript" ], "repository": { "type": "git", "url": "https://github.com/thinkjs/thinkjs" }, "engines": { "node": ">=0.12.0" }, "license": "MIT", "readmeFilename": "README.md", "bugs": { "url": "https://github.com/thinkjs/thinkjs/issues" } }
修改 pm2 日志位置
pm2 (官网 http://pm2.keymetrics.io)是一个优秀的 Node.js 进程管理器。它的强大之处在于不仅可以作为 Node.js 项目的守护进程,还具备可配置化启动、分布式支持、内存监控、热重载(优雅重载)、支持数据统计、运行日志记录、实时运行监控、API 和脚本支持等强大的特性。(更多的特性,另文描述~)
thinkjs 推荐使用 pm2 来管理项目运行,并自动生成了 pm2 的配置文件
pm2.json。
默认生成的 pm2 配置文件不含日志记录部分,如果不单独配置,pm2 的日志将会保存在安装目录中,查找起来很不方便(当然你可以使用
pm2 logs [id|name]来直接查看某个进程的日志,不过有些时候还是需要直接查看日志文件的)。
我的做法是:在项目目录下建立
logs文件夹,用来放置 pm2 以及其他(诸如 log4js 等等)日志,打开
pm2.json,给
apps[0]增加如下几行配置参数:
{ "apps": [{ "error_file" : "/data/www/thinkjs_module/logs/pm2-err.log", "out_file" : "/data/www/thinkjs_module/logs/pm2-out.log", "log_date_format" : "YYYY-MM-DD HH:mm:ss Z", "merge_logs" : false }] }
error_file pm2 捕捉到的致命错误记录在这里
out_file pm2 接收到的 console 输出记录在这里
log_date_format 日期和时间格式
merge_logs 是否给日志文件增加进程id的后缀
注:更详细的参数配置,可前往 pm2 官网查阅。
done~
下一篇:Node.js 国产 MVC 框架 ThinkJS 开发 config 篇
原创:荆秀网 网页即时推送 https://xxuyou.com | 转载请注明出处
链接:https://blog.xxuyou.com/nodejs-thinkjs-study-start/
相关文章推荐
- Node.js 国产 MVC 框架 ThinkJS 开发 config 篇
- Node.js 国产 MVC 框架 ThinkJS 开发 controller 篇
- Node.js 国产 MVC 框架 ThinkJS 开发 controller 篇(续)
- Node.js 入门手册:那些最流行的 Web 开发框架
- (pomelo系列入门教程)深入浅出node.js游戏服务器开发——Pomelo框架的设计动机与架构介绍
- 全端开发必备!10个最好的 Node.js MVC 框架
- 以太坊DApp开发入门教程——Node.js和truffle框架打造区块链投票系统
- 全端开发必备!10个最好的 Node.js MVC 框架
- 以太坊 DApp 开发入门实战! 用Node.js和truffle框架搭建——区块链投票系统!
- Node.js 入门手册:那些最流行的 Web 开发框架
- 以太坊 DApp 开发入门实战! 用Node.js和truffle框架搭建——区块链投票系统!
- (pomelo系列入门教材)深入浅出node.js游戏服务器开发1——基础架构与框架介绍
- 深入浅出node.js游戏服务器开发1——基础架构与框架介绍
- Node.js Web 开发框架大全《中间件篇》
- 转 - 最流行的Node.js快速开发框架大荟萃
- 【Node.js】29 个Node.js框架用于快速Web应用程序开发
- 最流行的Node.js快速开发框架大荟萃
- Node.js Web 开发框架大全《中间件篇》
- Node.js Web 开发框架大全《静态文件服务器篇》