最近公司要启动一个移动项目,在后台系统的选型上,可选的有PHP、Java、NodeJS,从技术上来说,Java较为成熟,但开发速度较慢,性能稳定;PHP开发迅速,但稳定性不高,性能也一般,开发效率较高;NodeJS的性能较高,可以处理更多的连接和iO问题,所以最终选择了NodeJS。
NodeJS本质来说是一个服务器端的Javascript,但是其使用起来,并不是那么容易,我大致的学习过程如下,我买了两本书,一本是朴灵的《深入浅出NodeJS》,一本是赵坤等的《Node.JS实战》,相对来说,前者对我的影响更大,让我对NodeJs有了一个直观的了解,朴灵的介绍偏向底层,对框架性的极少较少,后来我就买了第二本书,但是只是大致翻了一下,坦白来说,我之前对NodeJS的了解等于零,对JQuery也只有粗浅的研究,所以遇到了很多困难。最后我清理了一下思路,选择Sails MVC框架。
我要解决的问题也很简单,需要为移动APP提供后台支持,需要提供HTTP服务,支持MySQL数据库,以及其他的缓存数据库,并要和PHP框架Laravel开发的WEB程序互通,第一个问题就是需要能够采用同样的加密算法对密码加密和比对。这些问题下面会以此解决。
NodeJS的安装比较简单,在nodejs.org上下载对应操作系统的包即可,目前的版本是0.10.31,Windows和Mac平台可以直接安装,Linux平台需要自己编译,编译过程很简单,依次运行./configure,make,sudo make install即可,现在的NodeJS默认会安装NPM,就是NodeJS的包管理工具,大部分的模块都可以通过这个工具安装。
常见的Nodejs资源是nodejs.org和github.com,前者包含官方文档,后者可以搜索到一些你需要的包,虽然大部分的包网上都能找到教程,但是教程很容易过时,最好看看github.com上的对应的说明,或者下载安装模块后,看模块目录下的README.Md,可以知道一些基本的用法,避免在起始配置上花费过多的时间。
在寻找模块时,可以看看其评价,寻找评价较好的模块,因为nodejs的模块实在太多了。
开发nodejs时,我知道的工具有nodeclipse、Netbeans、WebStorm,相对来说,WebStorm较好,不过需要钱,nodeclipse也不错,只不过感觉不稳定,Netbeans增加一个插件就可以了,但是没有调试功能,只是一个运行命令而已,好在它的编辑功能很强大。其他的sublime和notepad++都可以用,最终我用的还是Netbeans,因为可以和PHP、Java程序公用一个环境,Eclipse有点太大了,最近不怎么喜欢了。
nodejs的程序其他的程序如PHP、Java有很大的不同,如果它有的地方出错了,整个系统就崩溃了,但PHP和Java都不会,他们只会在出错的地方出错,其他的地方正常运行。因为nodejs本质来说,其主体线程只有一个,崩溃了就没有了。所以要特别小心,但是也有其优点,访问全局变量要容易的多,比如Sessioin、缓存等。不过同样需要注意其内存分配问题,全局变量可能会永远存在,容易造成内存泄漏问题。
安装nodejs模块的命令式npm install module_name,这会在当前目录下创建一个node_modules,里面是包含的模块,如果要安装全局模块,需要用npm install module_name -g,这会在主目录下创建node_modules,里面存储包含的模块。模块名可以在命令中指定,也可以在当前目录下的package.json中指定。下面以express为例说明一下。
学习nodejs常见的组件是express,这是一个简单的提供http服务的mvc框架,类似于PHP的laravel,或者Java的Spring,当然其功能要弱一些,安装命令为npm install -g express,然后用express命令安装,有以下几种情况:
express #在当前目录下创建express框架,默认使用jade引擎
express -e #在当前目录下创建express框架,默认使用ejs引擎
express project#在project目录下创建express框架,默认使用jade引擎
express -e project#在project目录下创建express框架,默认使用ejs引擎
express --version #显示当前版本
也可以用express -h,查看所有的帮助信息
默认的页面渲染引擎有两种: jade和ejs,ejs类似于php的方式将js脚本嵌入到html代码中,虽然看起来比较乱,但是习惯了也没什么,jade有点难以理解,不太适应,好像效率也不高,就选择了ejs引擎。
默认的package.json如下
{
"name": "test",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"ejs": "~0.8.5"
}
}
在运行完express -e命令之后,系统会提示你到目录中运行npm install命令,这个命令会根据package.json的dpendencies的属性下载模块安装。如需要增加session支持,可以运行npm install express-session,也可以在package.json的dependencies增加一行,如下
"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"ejs": "~0.8.5",
"express-session":"*"
}
然后运行npm install命令就可以了。
运行express的命令如下:
node ./bin/www
就是在根目录下的bin目录下的www文件,这是一个js文件,运行之后,就可以在浏览器中查看运行结果,默认的首页为http://localhost:3000,
express框架的目录也很清楚,大致如下
D:.
│ app.js #主要的入口文件,或者说起始文件
│ package.json #模块配置文件
│
├─bin
│ www #启动文件:命令为 node www
│
├─public #一些静态文件,如图片、JS、CSS文件
│ ├─images
│ ├─javascripts
│ └─stylesheets
│ style.css
│
├─routes #路由文件,目前express支持将将一个虚拟目录下的请求放到要给路由文件中,这是在app.js中定义的
│ index.js #app.use('/',routes) ->根目录下的路由
│ users.js #app.use('/user',users) ->user目录下的路由
│
└─views #mvc的view层,目前都为ejs文件
error.ejs
index.ejs
不过目前来说,express不支持控制器,其逻辑常常要写在routes文件中,不过可以将逻辑放在其他文件中,然后require进来。
默认的路由文件index.js如下:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
module.exports = router;
1)req
req.params.name ->/user/:name
req.query.name ->/user?name=shiyq
req.body.name ->名称为name的表单输入值
req.param(name) ->以上的三种输入都支持,次序为params,body,query
req.cookie.name ->cookie的name属性
2)res
res.cookie(name,value) ->设置cookie
res.redirect('/foo/bar') ->跳转到/foo/bar
res.location('foo/bar') ->类似redirect
res.send('<p>name</p>') ->向浏览器输出
res.json() ->想浏览器返回json数据
res.render(view, [locals], callback) ->转向view,并携带变量
res.end() ->结束输出
让express支持session,需要安装express-session模块,查看相应模块下的README.Md文件,可以看到如下内容
var express = require('express')
var session = require('express-session')
var app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true
}))
可知这个express-session需要紧跟express的定义,其使用方式是app.use(),如果位置太靠后,可能会出现问题,需要注意,其默认使用方式为req.session.name,默认的express-session将session保存在内存中,如果想保存到redis,memcache以及mongodb,需要集成另外的组件,可以在github.com上寻找,同时要记得阅读README.Md文件
到此为止,就可以进行基本的express开发了,但是很容易发现修改了代码之后,系统并不生效,nodejs没有所谓的热启动机制,需要重新启动程序,不过每次启动就太麻烦了,所以要使用自动启动的工具,supervisor,安装方式为npm install supervisor -g,执行命令为supervisor app.js,可以用supervisor -h查看帮助,一般来说需要设置-w或者-i开关,-w代表监控的目录,只有这些目录下的文件修改了才会重新启动node,默认为当前目录“.”,目录以“,”间隔,-i是忽略某些目录。-w开关非常有用,比如某些程序会在当前目录下创建临时文件,就会不停的重启,需要设置只有某些目录修改才需要启动,如sails框架,其目录结构如下
这里明显有个临时文件.tmp,如果直接运行supervisor app.js,就会出现不停重启的现象,所以我在根目录下写了一个sailsjs.bat文件,内容为
supervisor -w api,assets,config,node_modules,tasks app.js
这就可以解决不停重启的问题了。