[转]使用Node.js完成的第一个项目的实践总结

2019年11月18日 阅读数:227
这篇文章主要向大家介绍[转]使用Node.js完成的第一个项目的实践总结,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

本文转自:http://blog.csdn.net/yanghua_kobe/article/details/17199417javascript

https://github.com/yanghua/FixedAssetManager_Serverphp

项目简介

这是一个资产管理项目,主要的目的就是实现对资产的无纸化管理。经过为每一个资产生成二维码,来联合移动终端完成对资产的审核等。这个项目既提供了Web端的管理界面也提供移动端(Andorid)的资产审核、派发等相关功能。 咱们用Node.js构建该项目的Web端以及移动端的Serveice API。css

项目主框架:Express 简介

 

 

Express 是一个很是流行的node.js的web框架。基于connect(node中间件框架)。提供了不少便于处理http请求等web开发相关的扩展。 Express简单的结构图:html

 

Express的特性:前端

  • 基于Connect构建
  • 健壮的路由
  • 提供丰富的HTTP处理方法
  • 支持众多视图模板引擎(14+)
  • 内容协商
  • 专一于提供高性能
  • 环境基于配置
  • 快速构建可执行的应用程序
  • 高测试覆盖率

前端框架简介

Bootstrap

Bootstrap是Twitter推出的一个用于前端开发的开源工具包。它由Twitter的设计师MarkOtto和JacobThornton合做开发,是一个CSS/HTML框架。Bootstrap是简洁、直观、强悍的前端开发框架,让web开发更迅速、简单。 同时,不少基于Bootstrap的开源插件也让Bootstrap社区更加活跃。 最新的Bootstrap3提供了很是强的定制化特性。包括Less,jQuery插件等。 Bootstrap 为您提供了全部这些基本的模块- Grid、Typography、Tables、Forms、Buttons和Responsiveness。 此外,还有大量其余有用的前端组件,好比Dropdowns、Navigation、Modals、Typehead、Pagination、Carousal、Breadcrumb、Tab、Thumbnails、Headers等等。 有了这些,你能够搭建一个Web 项目,并让它运行地更快速更轻松。 此外,因为整个框架是基于模块的,你能够经过定制你本身的CSS来使得它知足你的特殊需求。 它是基于几种最佳实践,咱们认为这是一个很好的开始学习现代Web 开发的时机,一旦你掌握了HTML 和JavaScript/jQuery 的基本知识,你就能够在Web 开发中运用这些知识。vue

Ember.js

 

Ember.js是一个JavaScript的MVC框架,它由Apple前雇员建立的SproutCore2.0更名进化而来。 构建一个Ember应用程序,一般会使用到六个主要部件:应用程序(Application)、模型(Model)、视图(View)、模板(Template)、路由(Routing)和控制器(Controller)。 这里咱们server端主要依赖express框架,它提供的这些功能跟express有些是相同的。咱们主要应用了Ember的模板组件,Express对于它提供了很好的集成。咱们只须要进行很简单的配置便可:java

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.set('view engine', 'html');   
  2. app.set('views', path.join(__dirname, 'views'));  
  3. app.set("view options", {layout : false});  
  4. app.register('.html', require('ejs'));  
app.set('view engine', 'html'); 
app.set('views', path.join(__dirname, 'views'));
app.set("view options", {layout : false});
app.register('.html', require('ejs'));

测试框架简介

should.js

should 是用于node.js的一个表述性、可读性很强的测试无关的“断言”库。它是BDD风格的,用一个单例的不可枚举的属性访问器扩展了Object的prototype,容许你表述对象应该展现的行为。 should的一个特性是能够支持链式断言,好比:node

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. user.should.be.an.instanceOf(Object).and.have.property('name', 'tj');  
  2. user.pets.should.be.instanceof(Array).and.have.lengthOf(4);  
user.should.be.an.instanceOf(Object).and.have.property('name', 'tj');
user.pets.should.be.instanceof(Array).and.have.lengthOf(4);

mocha

 
Mocha是一个简单、灵活、有趣的javascript测试框架。它能够同时适用于node.js跟浏览器端。能够很轻松得完成同步、异步测试,对产生异常的测试用例提供灵活以及准确的报告。能够经过接口实现BDD、TDD、QUnit风格。
 

mocha + should.js

 
mocha是能够实现BDD模式的测试框架,而should.js是BDD模式的断言库。把它们结合起来,能够组建出一个很是灵活,而且不失表述性的测试框架。咱们全部给终端的接口,都基于它们完成了测试。
 

项目组件 - node modules

mysql

功能简介:mysql- node.js平台mysql驱动,支持事务、链接池、集群、sql注入检测、多作参数传递写法等特性。 主页地址:https://github.com/felixge/node-mysqlmysql

eventproxy

功能简介:eventproxy- node.js 异步回调代理。主要用来解决node中深层次回调嵌套的问题,支持不少异步模式:多类型异步、重复异步、持续型异步。 主页地址:https://github.com/JacksonTian/eventproxyjquery

validator

功能简介:javascript的验证工具集,支持两种模式:check(校验)/sanitize(处理),同时提供了可扩展的错误处理。 主页地址:http://github.com/chriso/node-validator

ejs

 

功能简介:embered.jsjavascript 模板引擎(能够跟express集成,做为服务端模板引擎) 主页地址:https://github.com/visionmedia/ejs

loader

功能简介:loader- 资源加载工具,能够区分开发模式、发布模式;在发布模式下可进行资源压缩、合并。以实现减小静态资源带宽而且便于实现客户端缓存 主页地址:https://github.com/TBEDP/loader

canvas

 

功能简介:canvas - node.js 经常使用的图形图像处理库,是不少其它库的基础依赖库 主页地址:https://github.com/learnboost/node-canvas

captchagen

功能简介:captchagen-node.js经常使用验证码图片处理库,依赖上面的canvas库 主页地址:http://github.com/wearefractal/captchagen

crypto-js

功能简介:crypto-js- javascript 经常使用加密库、hash库封装,支持sha-x / md5 / hash等各类加密、hash算法 主页地址:http://github.com/wearefractal/captchagen

nodemailer

功能简介:nodemailer- 邮件发送工具,支持SMTP等邮件发送协议 主页地址:http://github.com/andris9/nodemailer

qrcode

功能简介:qrcode- node.js服务端的qrcode生成器。支持多种输出类型(dataUrl/file/bitArray) 主页地址:http://github.com/soldair/node-qrcode

pdfkit

功能简介:qrcode- node.js服务端的qrcode生成器。支持多种输出类型(dataUrl/file/bitArray) 主页地址:http://github.com/soldair/node-qrcode

excel

功能简介:excel- node.js excel解析器,支持xlsx(Excel2007+) 主页地址:https://github.com/trevordixon/excel

excel-export

 

功能简介:excel-export- node.js excel生成器,支持导出excel 主页地址:https://github.com/functionscope/Node-Excel-Export

net-ping

功能简介:net-ping- node.js 对ping的封装,用于测试目标主机是否可达 主页地址:https://bitbucket.org/stephenwvickers/node-net-ping

debug

功能简介:debug- node.js debug工具,对console.log的封装,支持多种颜色输出。 主页地址:https://github.com/visionmedia/debug

项目组织结构

 
 

NPM - Node.js 模块依赖管理工具

npm是管理node.js模块依赖的工具,依赖于开源技术的优点就是你有很是多的优秀库能够帮助你快速构建一个系统,但就像一把双刃剑,因为开源致使版本的升级不可控。这时,一个集中性的模块依赖管理工具的优点就十分明显。它负责帮你管理开源项目的版本,你只须要添加对某个开源模块的依赖便可。

unix/linux下安装npm:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. curl http://npmjs.org/install.sh | sudo sh  
curl http://npmjs.org/install.sh | sudo sh

如何在项目中使用npm管理你的依赖:

(1)在项目的根目录下建立一个package.json文件

在dependencies下添加所须要依赖的模块,示例以下:
打开terminal,进入项目的根目录下:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. $ cd projectPath  
$ cd projectPath
安装这些module到本地repository:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. $ npm install   
$ npm install 

这时你会发现,项目的根目录下多了一个node_modules文件夹,那里面就是从npm远程库里下载的模块而后“安装”到你的项目中的。 如今,你就能够在你的项目中应用你依赖的这些modules了。你能够经过require关键字来使用他们。好比,

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. require("eventproxy");  
require("eventproxy");

Node.js 模块加载机制

node.js的模块加载基于CommonJS规范。 在Node.js中,将模块分为两大类: (1)原生模块 原生模块在Node.js源代码编译的时候编译进了二进制执行文件,加载速度最快。  (2)文件模块 node.js依赖modulepath(模块路径)来加载module,而modulepath的生成规则主要是从当前文件目录开始查找node_modules文件夹,而后依次进入父目录查找父目录下的node_modules目录直至到根目录下得node_modules目录。因此在require的时候,若是带上module的路径,则按照该路径查找,若是没有就按照上面的node_modules文件夹向上追溯查找,若是都没有找到,则抛出异常。

自动化部署

项目环境的构建、部署都是自动化的。 咱们假设项目最终会发布在任意版本的Ubuntuserver上。在安装git的前提下,经过以下命令去clone项目到本地:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. git clone git://github.com/yanghua/FixedAssetManager_Server.git  
git clone git://github.com/yanghua/FixedAssetManager_Server.git
项目doc下有四个shell文件:
  • node_install_ubuntu.sh - 在ubuntuserver上安装node.js的脚本
  • node-canvas-install_ubuntu.sh - 在Ubuntuserver上安装node-canvas的脚本
  • mysql_install_ubuntu.sh - 在Ubuntu server上安装mysql的脚本
  • dispatch.sh - 部署项目的脚本

将它们copy到当前用户的home目录下,依次执行便可。整个过程几乎实现了无需人为干涉的“自动化”。

pm2 - 线上监控管理工具

 
pm2是很是优秀工具,它提供对基于node.js的项目运行托管服务。它基于命令行界面,提供不少特性:
  1. 内置的负载均衡器(使用nodecluster module)
  2. 以守护进程运行
  3. 0s(不间断)重启
  4. 为ubuntu/ CentOS 提供启动脚本
  5. 关闭不稳定的进程(避免无限死循环)
  6. 基于控制台监控
  7. HTTP API
  8. 远程控制以及实时监控接口
pm2使用nodecluster构建一个内置的负载均衡器。部署多个app的实例来达到分流的目的以减轻单app处理的压力。
 

异常监控与邮件推送

 

node.js 处处都是异步调用。经常使用的try/catch同步捕获异常并处理的方式,在这里不起做用了。这是由于不少callback已经离开了当时try的上下文,致使没法获取异常产生的堆栈信息。基于这个问题,咱们对异常处理的模式按类型进行区分处理:

(1)http请求异常 这种异常Express就能够进行处理。若是是非法请求,在路由的时候,对未匹配的请求进行统一处理:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.get("*", others.fourofour);   
app.get("*", others.fourofour); 

(2)业务异常

这种异常一般不会影响到程序的运行,咱们以不一样的异常代码返回给前端或者终端,来给调用端友好的提示。

(3)应用程序级别的异常或必须处理的错误

这种状况下,应用程序可能没有办法处理异常,也有可能由应用程序抛出。对于这种应用程序级别的异常。咱们用两种方式来catch:

[1]利用Express提供的应用程序的异常处理机制:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.error(function(err, req, res, next) {                                             
  2.         mailServie.sendMail({                                                     
  3.           subject : "FixedAssetManager_Server[App Error]",                    
  4.           text    : err.message + "\n" + err.stack + "\n" + err.toString()            
  5.         });                                                                       
  6.         if (err instanceof PageNotFoundError) {                               
  7.             res.render("errors/404");                                             
  8.         } else if (err instanceof ServerError) {                                      
  9.             res.render("errors/500");                                             
  10.         }                                                                         
  11.     });  
app.error(function(err, req, res, next) {     										
        mailServie.sendMail({													
          subject : "FixedAssetManager_Server[App Error]",					
          text    : err.message + "\n" + err.stack + "\n" + err.toString()			
        });																		
        if (err instanceof PageNotFoundError) {								
            res.render("errors/404");											
        } else if (err instanceof ServerError) {									
            res.render("errors/500");											
        }																		
    });
[2]应用程序已经没法响应处理了,则利用node.js提供的,对于进程级别的异常处理方式:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. process.on("uncaughtException", function (err) {                                      
  2.         mailServie.sendMail({                                                     
  3.             subject : "FixedAssetManager_Server[App Error]",                      
  4.             text    : err.message + "\n" + err.stack + "\n" + err.toString()          
  5.         });                                                                       
  6.     });   
process.on("uncaughtException", function (err) {									
        mailServie.sendMail({													
            subject : "FixedAssetManager_Server[App Error]",					
            text    : err.message + "\n" + err.stack + "\n" + err.toString()		
        });																		
    });	
这两种应用程序级别的异常,优先级都比较高,所以咱们采用了邮件通知的策略,来辅助开发人员进行快速定位并修复。
 

静态资源优化:压缩合并与缓存

web应用中对于资源的定义大体分为:静态资源、动态资源两种。动态资源一般是可变的,须要进行相应处理的,而静态资源在线上一般都是不会变的。常见的静态资源有:javascript文件、css文件、图片文件等。对于这些静态文件,咱们经过设置过时时间来进行缓存。而对于文本文件,因为浏览器的解析行为,对他们进行合并或者压缩都不会产生影响。 这里须要提到咱们在组件中介绍的Loader。在项目刚被clone下来的时候,须要先执行makebuild来对项目进行初始化。在初始化的过程当中,Loader会对项目的views文件夹中的文件进行扫描。它一般会扫描html界面:查找相似于以下的片断:

  1. <!-- style -->                                                                      
  2.     <%- Loader("/public/stylesheets/login.min.css")                            
  3.       .css("/public/libs/bootstrap/css/bootstrap.min.css")                        
  4.       .css("/public/stylesheets/login.css")                                       
  5.       .done(assets)                                                               
  6.       %>                                                                       
  7.     <!-- script -->                                                                 
  8.     <%- Loader("/public/libs/js/login.min.js")                                     
  9.       .js("/public/libs/jquery/jquery-1.10.2.min.js")                             
  10.       .js('/public/libs/bootstrap/js/bootstrap.min.js')                           
  11.       .js("/public/libs/CryptoJS_v3.1.2/rollups/sha256.js")                       
  12.       .js("/public/libs/js/login.js")                                                 
  13.       .done(assets)                                                               
  14.     %>  
<!-- style -->																	
    <%- Loader("/public/stylesheets/login.min.css")							
      .css("/public/libs/bootstrap/css/bootstrap.min.css")						
      .css("/public/stylesheets/login.css")										
      .done(assets)																
      %>																		
    <!-- script -->																
    <%- Loader("/public/libs/js/login.min.js")									
      .js("/public/libs/jquery/jquery-1.10.2.min.js")							
      .js('/public/libs/bootstrap/js/bootstrap.min.js')							
      .js("/public/libs/CryptoJS_v3.1.2/rollups/sha256.js")						
      .js("/public/libs/js/login.js")												
      .done(assets)																
    %>
去查找.css()以及.js()方法中的这些路径参数,并对这些文件进行合并或压缩混淆(这取决于配置),来产生一份assets.json(资产列表)文件。这里面定义了一些键值对,键为上面代码段中Loader()方法后面跟的参数,值为具体合并后文件的路径。这样,Loader会根据配置来判断加载类型。若是当前为开发模式或者为debug模式,则调用.js()/.css(),基于其中的路径参数来生成<script/> <link />。若是为发布模式,则根据.done()里的assets键值对,结合Loader()的参数,来输出合并后的文件。以减小前端http请求数量以及总大小。对publich文件夹下的文件,设置静态文件缓存:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. //config for production env                                                       
  2. app.configure("production", function () {                                             
  3.     app.use('/public', express.static(staticDir, { maxAge: maxAge }));                
  4.     app.use(express.errorHandler());                                              
  5.     app.set('view cache', true);                                                      
  6. });  
//config for production env														
app.configure("production", function () {											
    app.use('/public', express.static(staticDir, { maxAge: maxAge }));				
    app.use(express.errorHandler());											
    app.set('view cache', true);													
});
由于设置了缓存,在从新改动这些静态文件再发布的时候,若是缓存时间太长,则客户端的静态文件可能不会被替换。对于这个问题,Loader经过在文件的后缀追加一个版本号来做为参数。这样,当从新生成assets.json的时候每一个文件会产生新的版本号,浏览器会请求“新文件”替换掉客户端老的缓存文件。
 

Restful风格的URL

Restful以“Resource”为核心概念,认为URL是用来表示一种资源。而不该该表示一个动做或者其余的东西。而动做,好比“CRUD”正好对应http的四个method:get/post/put/delete。本项目中,咱们大部分的URL以Restful风格为主,但没有严格贯彻执行。

前端内容模板化、组件化

前端咱们采用的是ejs的模板来构建,它很好得实现了html的片断化、组件化。有一个基础的模板,别的都只是一块html片断。它们在服务端完成组合、解析,生成完整的html流输出到客户端。 这样的开发模式,使得前端代码的划分比较清晰,组件化也使得代码的复用变得更容易。

makefile

在项目初始化的过程当中,咱们使用makefile文件来使得一些动做自动化运行。好比咱们以前提到过的构建assets.json来合并文件的动做,就是经过执行makebuild文件来完成的。

加强的Debug模块

目前,Node.js尚未很强大的调试工具。经常使用的辅助诊断方式就是打log。但繁多的日志输出,混杂在http log里实在是不方便判断。咱们在项目中使用了debug module来进行debug,他支持对log加不一样颜色的key word而且还支持timestamp。你在一大堆日志中,一眼就足以区分是从哪一个module或者组件输出的。咱们在项目中对不一样的layer应用不一样的关键字:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. var debug4Ctrller   = require("debug")("controller");  
  2. var debug4Proxy     = require("debug")("proxy");  
  3. var debug4Lib       = require("debug")("lib");  
  4. var debug4Test      = require("debug")("test");  
  5. var debug4Other     = require("debug")("other");  
var debug4Ctrller   = require("debug")("controller");
var debug4Proxy     = require("debug")("proxy");
var debug4Lib       = require("debug")("lib");
var debug4Test      = require("debug")("test");
var debug4Other     = require("debug")("other");

将其置为全局:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. global.debugCtrller = debug4Ctrller;  
  2. global.debugProxy   = debug4Proxy;  
  3. global.debugLib     = debug4Lib;  
  4. global.debugTest    = debug4Test;  
  5. global.debugOther   = debug4Other;  
global.debugCtrller = debug4Ctrller;
global.debugProxy   = debug4Proxy;
global.debugLib     = debug4Lib;
global.debugTest    = debug4Test;
global.debugOther   = debug4Other;
这样你在controller层的log就能够以以下方式log:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. debugCtrller("XXX %s", "YYY");  
debugCtrller("XXX %s", "YYY");

这样在Terminal中,输出的log会按照不一样的颜色进行区分,辨别性明显加强:

 
 

一切均可自动化——Grunt

 
Grunt是Javascript任务运行器。
 

为何须要任务运行器?

 
对于须要反复重复的任务,例如压缩、编译、单元测试、代码检查等,自动化工具能够减轻你的劳动,简化你的工做。
 

为何使用Grunt?

 
Grunt 有庞大的生态圈,而且天天都在增加。你能够自由地选择数以百计的插件,帮助你自动化地处理任务。
 
用Grunt构建现有项目
1:全局安装grunt命令行接口:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. npm install -g grunt-cli  
npm install -g grunt-cli
2:在项目的根目录下新建一个Gruntfile.js文件,该文件为grunt的配置、初始化文件
3:在packaget.json文件的devDependencies项中,添加grunt核心依赖以及须要的插件依赖:
注若是不想手动添加这些依赖,能够直接打开Terminal,在项目根路径下运行:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. npm install grunt --save-dev      
npm install grunt --save-dev	

依赖会被自动写入package.json的devDependencies项中。

关于Gruntfile的编写规则,详细请查看, Gruntjs中文文档
目前项目中用到的几个gruntplugin:
  • jshint: 用于对JS语法进行强制检查
  • csslint: 用于对css语法进行强制检查
  • uglify: 用于压缩项目文件
Gruntfile配置的写法很是灵活而且随意,支持对文件进行正则匹配等特性。
 

统一的代码风格

 
对于多人协做的项目,代码风格显得尤其重要。对于代码风格的统一,咱们采用软硬结合的方式。软指的是自动化格式工具;硬指的是强制检查工具。
 

自动格式化工具

目前项目中,两人都采用SublimeText做为代码编辑器。借助,SublimeText多如牛毛的插件,能够简化不少重复性工做,带来显著的效率提高。这里介绍几个格式化工具:
  • alignment:等号对齐排版插件
  • JSFormat:JS代码格式化排版工具
  • HTML-CSS-JS Prettify 代码格式化工具
对于2,3两个插件,选择他们的缘由是:他们开放了代码风格的定义规则,而不是强制应用它们本身的规则。你能够任意定义你想让它格式化的代码风格,好比:

你只须要在项目的根目录下,建立一个.jsbeautifyrc文件,里面对缩进,空格等进行定义便可覆盖默认配置。这很是方便那些已经习惯了本身有一套代码风格的人使用这些插件。

更难能难得的是,对于一个项目你能够有多个.jsbeautifyrc文件进行配置。他们的优先级取决于这些配置文件靠近待格式化文件的程度(某种意义上就是这些配置文件在目录层次的深度)。这很是切换咱们的需求:由于node项目先后端都是js。对于后端咱们采用的是4空格缩进,对于前端JS咱们采用的2空格缩进。那么咱们只须要在前端JS文件夹下,新建一个新的.jsbeautifyrc配置文件,copy上面的配置,而后将indent_size修改成2便可。
 

强制检查工具

自动格式化工具只是一种“效率工具”,不足以造成“强制规定”。这里咱们辅以代码检查工具,来强制要求代码风格、语法规范。

检查工具在GruntSection已经列出,在commit代码以前,必须运行检查,并确保没有任何Warnning跟Error。
 

Express 2.x to 3.x 接口适配与调整

一、ejs 服务端模板的调整: 原先的模板配置方式是采用在html文件,设置:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. <% layout('layout') -%>  
<% layout('layout') -%>
来标识一个component会套用某个模板,而在3.x中ejs模板引擎,改成采用middleware的方式使用:(须要安装一个module:express-partials)
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.use(require('express-partials')());  
app.use(require('express-partials')());
与此同时,3.x专门提供了一个设置引擎的接口:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.engine('html', require('ejs').renderFile);  
app.engine('html', require('ejs').renderFile);
替代了原先2.x的:
[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.register('.html', require('ejs'));  
app.register('.html', require('ejs'));
二、处理错误的方式改变:

2.x处理错误有专门的一个API:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.error(function(err, req, res, next) {                                             
  2.     //error logic handle                                                      
  3. };  
app.error(function(err, req, res, next) {											
    //error logic handle													
};

 

3.x退而采用middleware的方式来处理:

[javascript] view plain copy print ? 在CODE上查看代码片 派生到个人代码片
  1. app.use(function(err, req, res, next) {                                           
  2.     //error logic handle                                                      
  3. }  
app.use(function(err, req, res, next) {											
    //error logic handle													
}

更多express2.x to 3.x的改变,能够看看官方给出的变动列表

 

从EventProxy 到 async 切换

eventproxy是淘宝前端团队开发的一个node.js事件处理代理。用于辅助开放人员组织代码的执行顺序,对于不少须要干预执行顺序与过程的代码,避免了node.js深层嵌套的callback模式。

async跟eventproxy出于一样的目的。但在API的设计模式上有所差别。async的API的风格偏向于“整合”,Eventproxy偏向于“拆分”。
 

Mongodb for node.js:mongoose的使用

 

model的定义

mongodb里数据的集合称之为collection。而每一个collection都有一个schema与之对应,能够简单的理解为是对其数据的定义(类型与结构)。

对应到mongoose里,一个schema是一个model,形如: