不知不觉做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服务端重构计划的更多相关文章

  1. 微信小程序初见+nodejs服务端 (一个简单的博客)

    推荐网址: 腾讯云快速开发(nodejs前后端):https://developers.weixin.qq.com/miniprogram/dev/qcloud/qcloud.html#%E5%AF% ...

  2. nodejs服务端开发学习笔记

    正在学习中,不断改错... 学习了一段时间nodejs,对其中的很多东西还不是很理解,在网上看过很多的例子,希望通过自己的一些总结让自己了解的更全面些,同时也作为学习笔记留存备忘. 准备工作 node ...

  3. [原创]使用vscode+es6写nodejs服务端调试配置

    前端的小伙伴们在babel等的加持下,已经可以愉快的使用es6来写代码了. 然后对于服务端的nodejs就有点坑爹了,虽然原生支持了es6,但是只是部分支持,一些不支持的特性(比如module)使用了 ...

  4. react native android 上传文件,Nodejs服务端获取上传的文件

    React Native端 使用react-native-image-picker 做出选择图片的操作,选择完成后,直接将图片Post至服务器,保存在服务器的某个地方(保存图片的路径需要公开显示),并 ...

  5. nodejs 服务端添加相应头Access-Control-Allow-Origin

    重点在这句:res.setHeader("Access-Control-Allow-Origin", "*"); var http = require(&quo ...

  6. nodejs服务端实现post请求

    博客之前写过一篇php实现post请求的文章. 今天想到好久没有输出了,重新认识到输出的重要性.百般思索该写些什么?想来想去,想到了两点: 逐步熟练nodejs各种场景知识,针对mysql数据交互和f ...

  7. nodejs服务端使用jquery操作Dom

    添加模块:   npm install jquery@3.2.1   npm install jsdom 引入模块:   var jsdom = require("jsdom"); ...

  8. nodeJS 服务端文件上传

    var http = require('http'); var path = require('path'); var fs = require('fs'); function uploadFile( ...

  9. 初识NodeJS服务端开发(Express+MySQL)

    http://www.alloyteam.com/2015/03/sexpressmysql/

随机推荐

  1. RvmTranslator6.0 - Dassault Systemes 3DXML

    RvmTranslator6.0 - Dassault Systemes 3DXML eryar@163.com 1. Introduction RvmTranslator can translate ...

  2. jquery17 DOM操作 : 添加 删除 获取 包装 DOM筛选

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  3. ElasticSearch 工作原理

    ElasticSearch 工作原理图 文字说明,以后更新

  4. Gym 100952 D. Time to go back

    http://codeforces.com/gym/100952/problem/D D. Time to go back time limit per test 1 second memory li ...

  5. 搭建Spark源码研读和代码调试的开发环境

    转载自https://github.com/linbojin/spark-notes/blob/master/ide-setup.md 搭建Spark源码研读和代码调试的开发环境 工欲善其事,必先利其 ...

  6. unalias---取消命令别名

    unalias命令用来取消命令别名,是为shell内建命令. 选项 -a:取消所有命令别名. 实例 使用unalias命令将已经设置的命令别名"cc"取消,输入如下命令: unal ...

  7. JNDI学习总结(1)——JNDI入门

    JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,不少专家认为,没有透彻理解JNDI的意义和作用,就没有 ...

  8. wpf app全局变量传参方法(代码片段 )

    清空某行绑定的行数据: int RowIndex = datagrid.SelectedIndex; _Table.Rows[RowIndex]["AVERAGE_PRICE"] ...

  9. SQL数值转字符串保留指定小数位

    IF EXISTS ( SELECT * FROM sysobjects WHERE xtype = 'fn' AND name = 'fn_NumberFormat' ) BEGIN DROP FU ...

  10. Android 安卓直播开源: RTMP 推流SDK

    前些日子在github上提交了基于GPUImage的iOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了Android直播推流 ...