NodeJS服务端重构计划
不知不觉做node开发已经半年时间了。这期间写尝试着去攻克了一些问题。实现了一下想法,也遇到过一些坑。
是时候来梳理一下代码,规划一下接下来的工作。
现阶段我们的nodeserver端代码结构是这种:
乍一看好像没有什么问题。事实上这当中充斥着一些反复代码,以及一些没有測试的模块,代码组织也不够合理。这些问题都是须要处理的。
先来说说几个经常使用的术语
router
路由模块负责请求的分发。把请求转给详细的controller。controller是每一个请求进来之后处理的逻辑,而route则定义了请求应该进入那个controller。controller
controller是一个完毕某项任务的调度中心,不设计详细的数据库操作,也不做页面渲染。仅仅负责获取现有的数据。加工处理。调用相应的接口把数据呈现给client。middleware
我们知道server响应一个client请求通常是串行的操作。由路由模块把请求分发到详细的controller,在分发到controller之前我们能够对这些数据做一些欲处理操作。比如推断请求头部的content-type字段提前把数据解析好,比方过滤一些包体过大的请求等。完毕这些任务的模块一般称为中间件。也叫过滤器吧!
1. 利用MVC结构来又一次布置代码
在转nodejs开发之前写过一些PHP的代码,深受其代码结构的影响。传统的MVC架构清晰并且easy理解。看过了一些开源项目的代码结构,感觉server端代码结构还是有很多能够借鉴的地方。因为前端界面是基于canvas来绘制的,所以不存在传统意义上的渲染界面操作,server仅仅完毕一些主要的CURD操作就可以。
1.1 引入Router模块
依据详细的业务逻辑抽象在controller之前引入一个Router来分发请求。express4.x提供了一个Router函数,摈弃了之前把请求直接挂载到全局app对象上的做法(app.use(”api/a’, controler))。
推荐的做法是把不同的业务模块挂在不同router对象上(app.use(‘/api/a’, webRouter))。再把router挂在app对象上。
//之前的做法
var app = express();
app.post('/api1/a', ControllerA);
//推荐做法
var app = express();
//user manager
var router = express.Router();
router.post('/api1/a', ControllerA);
app.use('/api1', router);
1.2 把几个反复的校验操作抽象为filter(middleware)
在一些须要验证用户是否登录的模块,须要推断用户的信息是否挂在session对象上。我们能够把这个操作抽象为一个过滤器。当我们发现几个模块都有相似的预处理操作时都能够抽象为过滤器的形式。
1.3 替换oauth模块
server端集成了各种社交帐号的授权登录模块,经过几个月的測试以及趋于稳定了,只是在不同浏览器上竟然还存在不一致的表现。
考虑到代码兴许的维护成本,还是放弃这个轮子了,nodejs有个passport模块能够来解决问题!
1.4 替换现有的Model模块
我们的数据库採用mongodb,现有的model模块基于原生的驱动来封装,须要写一些新功能的时候体力活比較多,考虑放弃这个轮子。当时在写PHP程序的时候写了一个ORM模块把数据库的操作抽象成对语言对象的操作。nodejs有不少的ORM模块,考虑使用mongose或者sequelize来完毕这个任务。
1.5 优化异步处理
从接触Nodejs开发起,一个不得不正视的问题是怎么把异步处理写的优雅。简洁。有四个方式能够选择,
fibjs. 我们知道nodejs基于异步io,在调用一个异步函数等待返回的时候都须要注入一个回调函数。
假设我们能够把这个等待处理结果的过程默认给实现了,这样就能解决回调的问题。fibjs正好能够解决问题。
只是fibjs严重的模块侵入方式。也就是说原先的npm模块都得拿来改动。
第三方异步处理模块. nodejs经过这些年的发展逐渐出现了一些开源模块来解决异步的问题。如async/eventproxy/step/等等。这些模块基于事件处理的方式来解决回调金字塔的问题。
Promise. Promise是一个非常优秀的理念。通过把一些小的功能函数封装成promise函数,一个复杂的请求事实上就相应着一个promise函数链。
简洁优雅的代码组织方式。良好的异常捕获机制都是Promise的长处。只是promise存在的一个问题是,假设一个模块用promise写好了,差点儿其他与之相关的模块都得换成promise的形式。
KOA. koa积极拥抱ECMA6标准,其利用co模块实现,同步代码抒发异步情怀!
koa 须要重写整个server模块,打算后面来干这个事情,故舍弃之。promise涉及的代码非常多,不会比直接使用koa轻松多少所以也暂且放弃。打算选择一个折中的方式,一些轻量模块就直接用回调好了,相信良好的抽象能力也能解决一部分问题。较复杂的异步操作就通过第三方异步模块来完毕。学习成本不大,拿来就用,何乐不为呢!
2.引入自己主动化測试模块
1.1 基本測试
測试的重要性不言而喻。之前在开发的过程中也给一些比較重的模块写呢一些測试。可是都不成系统,不够完好。
单元測试计划使用assert加shouldjs配合mocha来完毕外加一个mock模块来完毕,另外mocha能够方便的生成代码覆盖度測试报告。server端集成測试能够使用superagent来模块请求、校验请求结果。
1.2 pre-commit hook
每次提交都触发測试,动态检測代码健壮性。
这样也就能防范于未然了。
1.3 锁定版本号
Nodejs生态圈非常繁荣。我们项目使用的非常多都是开源模块,为了保证项目稳定性,规避一些第三方模块的BUG。在測试稳定后把版本号锁定。
时间计划
3 天
NodeJS服务端重构计划的更多相关文章
- 微信小程序初见+nodejs服务端 (一个简单的博客)
推荐网址: 腾讯云快速开发(nodejs前后端):https://developers.weixin.qq.com/miniprogram/dev/qcloud/qcloud.html#%E5%AF% ...
- nodejs服务端开发学习笔记
正在学习中,不断改错... 学习了一段时间nodejs,对其中的很多东西还不是很理解,在网上看过很多的例子,希望通过自己的一些总结让自己了解的更全面些,同时也作为学习笔记留存备忘. 准备工作 node ...
- [原创]使用vscode+es6写nodejs服务端调试配置
前端的小伙伴们在babel等的加持下,已经可以愉快的使用es6来写代码了. 然后对于服务端的nodejs就有点坑爹了,虽然原生支持了es6,但是只是部分支持,一些不支持的特性(比如module)使用了 ...
- react native android 上传文件,Nodejs服务端获取上传的文件
React Native端 使用react-native-image-picker 做出选择图片的操作,选择完成后,直接将图片Post至服务器,保存在服务器的某个地方(保存图片的路径需要公开显示),并 ...
- nodejs 服务端添加相应头Access-Control-Allow-Origin
重点在这句:res.setHeader("Access-Control-Allow-Origin", "*"); var http = require(&quo ...
- nodejs服务端实现post请求
博客之前写过一篇php实现post请求的文章. 今天想到好久没有输出了,重新认识到输出的重要性.百般思索该写些什么?想来想去,想到了两点: 逐步熟练nodejs各种场景知识,针对mysql数据交互和f ...
- nodejs服务端使用jquery操作Dom
添加模块: npm install jquery@3.2.1 npm install jsdom 引入模块: var jsdom = require("jsdom"); ...
- nodeJS 服务端文件上传
var http = require('http'); var path = require('path'); var fs = require('fs'); function uploadFile( ...
- 初识NodeJS服务端开发(Express+MySQL)
http://www.alloyteam.com/2015/03/sexpressmysql/
随机推荐
- Eclipse中JDK的配置
window -> preference -> java -> install jres -> add -> standard vm -> 设置好相应的jre ho ...
- c++笔试题:不使用第三个变量来交换俩个变量的数值
题目:将a 与 b的值互换. 通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换.代码如下: int a,b; a; b: int t; t ...
- Kinect 开发 —— 进阶指引 (下)
运动识别 利用运动识别(motion detection)来进行近景识别是最有意思的一种方式.实现运动识别的基本原理是设置一个起始的基准RGB图像,然后将从摄像头获取的每一帧影像和这个基准图像进行比较 ...
- AtCoder Grand Contest 018 A - Getting Difference
A - Getting Difference Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement ...
- 使用spring-boot 国际化配置所碰到的乱码问题
写好html静态页面 , 也加上了编码格式 , 获取国际化展示在浏览器中还是存在乱码 , 开始以为是浏览器编码格式问题 , 做过处理后任没有得到解决 , 具体的处理方案如下: <meta ht ...
- 搜索 debian8.7.1 ,google vs baidu
国外的 Linux 比国内流行, debian官方网站只能找到当前版本DVD文件.想找旧版的Debian在百度一圈后徒劳无功,于是把目标转向 google ,只需要输入 debian?8.7.1-i3 ...
- 洛谷 P3386 【模板】二分图匹配 Dinic版
题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...
- less中混合
@charset "UTF-8"; //1 普通混合 //2 不带输出的混合:加() .font_hx(){ font-size: 28px; color: red; } h1{ ...
- SQL分页的几种方式
1.使用Row_number() over(order by columnName)函数来作为标示分页(下面的例子都是以last_seen来排序的,要求取顺序为20-30行的数据) SELECT Us ...
- 【2017 Multi-University Training Contest - Team 6】Kirinriki
[链接]http://acm.hdu.edu.cn/showproblem.php?pid=6103 [题意] 给出一串字符串,从中选出两个不重叠的字符串,使得两个字符串的距离和 <= m 的最 ...