express搭建nodeJS中间层(一)
2016-01-10
写在前面
好了,准备了一周的理论知识和开发方案,nodeJS中间层搭建项目从今天就开始了。作为项目的负责人和初次尝试者,我会把开发的过程中用到的技术、碰到的壁一个个用文章记录下来。http://jafeney.com/2016/01/10/2016-01-10-express-1/
express框架介绍
express框架是nodeJS出来不久就诞生的webServer构建框架,目前的版本是 4.x。项目时间紧迫,这次就不从零开始搞了,站在巨人的肩膀上解决问题,可以帮我们节省些底层工作。
@ express API官方网站 http://www.expressjs.com.cn
安装环境
如果你还没有安装node,先把它安装好。然后用npm 全局安装express和express-generator。
1 2
|
$ npm install exprss -g --save</div><div class="line" style="color:rgb(255,255,255); min-height:19px">$ npm install express-generator -g --save
|
文件部署
通过express-generator生成器工具 express 可以快速创建一个应用的骨架:(我的项目名是 node_hk)
默认生成的目录是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
. ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── error.jade ├── index.jade └── layout.jade
|
更改依赖包配置
因为我的前端项目用的是artTemplate模板引擎,为了很前后端复用,因此node这边也采用这款模板引擎。所以需要把express默认的jade改成了art-template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
{ "name": "node_hk", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", "express": "~4.13.1", "art-template": "~3.0.3", "morgan": "~1.6.1", "serve-favicon": "~2.3.0" } }
|
安装node_modules
配置好了 package.json,下面我们就用npm 依次安装它们吧!
启动项目
启动这个应用(MacOS 或 Linux 平台):
1
|
$ DEBUG=myapp npm start
|
Windows 平台使用如下命令:
1
|
$ set DEBUG=myapp & npm start
|
然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了(等等
报错了对不对 _ ,别着急,往下看)。
把默认的jade模板引擎改成artTemplate
改造app.js
app.js是express的主要文件,这个文件里包含了指定模板引擎、指定视图文件默认路径的代码。需要将指定模板引擎的代码改为指定用art-template引擎。视图文件默认路径保持不变,因此无需改动。
新的app.js如下(懒得看就直接copy吧):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); /*引用artTemplate模板*/ var template=require('art-template'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); /*把jade模板引擎改成artTemplate*/ //app.set('view engine', 'jade'); template.config('base',''); template.config('extname','.html'); app.engine('.html',template.__express); app.set('view engine','html'); // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
|
编写artTemplate模板文件
在工作区下,进入express文件夹中的views子文件夹,创建index.html,并将如下代码输入index.html,并保存。
注意,views文件夹下会有index.jade等三个后缀是.jade的文件存在,可以忽视它们。因为express默认支持的模板引擎是jade,所以初始化的框架中的模板是以.jade结尾的文件。也可以删除它们。
这里举个简单的 index.html 例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>hello express & art-template</title> </head> <body> <h2>Hello express & art-template</h2> <div id='main'> <ul> {{each list}} <li>编号:{{$value.id}} &nbsp;&nbsp;姓名:{{$value.name}}</a></li> {{/each}} </ul> </div> </body> </html>
|
渲染模板
express默认访问index路由。我们需要在index路由方法中,渲染模板。
进入routes文件夹,打开index.js,增加渲染模板的代码,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { //数据 var data = { title: '国内要闻', time: (new Date).toString(), list: [ { id: '1', name: '张三' }, { id: '2', name: '李四' } ] }; //渲染模板 res.render('index', data); }); module.exports = router;
|
代码中的res.render(‘index’, data)调用,会调用artTemple模块中的template.express方法,并传入模板文件名、数据。
template.express方法是在app.js中注册给express框架的。
在Windows命令行下,进入工作区,执行 node app.js ,服务器就启动了。
此时在本地机器上使用浏览器访问http://localhost:3000将会看到Html输出了,服务器端的命令行工具上同时也会显示“New request
arrived.”字样。
按Ctl+C退出服务器
@参考 express 官方API http://www.expressjs.com.cn
@参考 执着的慢行者 《使用artTemplate模板开发网站(node.js + express环境)》
写在前面
上一篇写到用express搭建本地环境而且成功实现了路由和模板渲染,这一篇具体讲讲如何把一个原本用artTemplate渲染的前端页面用nodeJS渲染并返回给浏览器。
改造过程
上一篇已经在express里配置好了artTemplate模板引擎,所以这里的改造变得无比简单。
删除不需要的依赖项
之前在 <head></head>
里引入的artTemplate类库存在的目的是在客户端用JavaScript调用template函数,对指定id的模板进行渲染,服务端这个步骤是不需要的,直接删除即可。
接下来再把这个结构删掉,因为服务端是直接把html文件作为模板引入的,不需要在单独声明 script
的类型和模板的id。
1
|
<script type="text/html" id="xxxx"></script>
|
最后一个依赖是用原本用JavaScript 调取接口获取data,然后用 template() 方法指定模板进行渲染这个过程,我们等下要把它放到服务端来完成,所以客户端里也不需要了。在我的设计模式里,只需要把 fGetData()
这个模块注释掉就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
/** * [单例初始化入口] * @return {[type]} [description] */ init:function(){ var self=this; /*执行模板渲染模块*/ self.fGetData(); //现在不需要了,把它注释掉吧! self.eventBind($,self);</div><div class="line" style="color:rgb(255,255,255); min-height:19px"> /*执行图片加载缓冲*/</div><div class="line" style="color:rgb(255,255,255); min-height:19px"> $('.lazyload').lazyload({effect : "fadeIn"}); }
|
静态资源迁移
我的项目是用gulp自动化管理的,只需要把 builder
、 lib
、html
这三个目录分别
copy到express工程 public目录下的 JavaScripts
、stylesheets
,根目录下的 view
文件夹里(文件位置具体怎么放看你的
个人爱好)。
当然这样迁移好还不够,模板文件里的路径也要改成迁移后的新路径。
注意:因为 之前我们再 app.js 里设置了静态资源的引用路径,所以路由 /index
下
静态资源 是可以直接访问的。比如 就像下面这样就能 引用到这2个 css文件了:
1 2 3 4 5 6
|
<head> <meta charset="utf-8" /> <title>首页</title> <link rel="stylesheet" type="text/css" href="stylesheets/base.min.css"/> <link rel="stylesheet" type="text/css" href="stylesheets/style.min.css"/> </head>
|
服务端渲染
我们的数据本来是通过调取Java接口获取到的,所以这里 服务端 要用到 nodeJS的 request
模块,先安装它:
有了request,我们就能在nodeJS里随意调用 Java写好的数据接口了。
接下里打开路由目录下的index.js 文件,在首页的路由里把模板渲染的工作 完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
var express = require('express'); var request= require('request'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { /*正式数据*/ request('http://test.webapp.baai.com/hk/index.json',function(error,response,body){ /*判断请求是否成功*/ if (!error && response.statusCode == 200) { /*把字符串转换为json*/ var data=JSON.parse(body); /*渲染模板*/ res.render('index', data); } }); });
|
注意: 返回的数据默认格式是string,如果需要json格式,要用JSON.parse()进行处理,不然就会报错
部署到远程服务器
这个过程 需要 懂一点 Linux,先用 文件服务工具 登录到 远程服务器,把 项目资源copy到线上服务器。
接下来就是 安装nodeJS环境了,这个步骤网上教程太多了,不同的系统不一样(不会的自己 百度 吧)。我用的服务器是阿里云的 centOS,本身自带nodeJS环境,所以不用从头安装,不过node的版本比较低,所以我简单升级了一下环境。
1、检查 Node的当前版本,使用命令
1 2
|
$ node -v</div><div class="line" style="color:rgb(255,255,255); min-height:19px">$ npm -v
|
2、清除npm cache
1
|
$ sudo npm cache clean -f
|
3、全局安装 Node Binary管理模块“n”
4、升级到最新版本(该步骤可能需要花费一些时间)
5、查看Node的版本,检查升级是否成功
1 2
|
$ node -v </div><div class="line" style="color:rgb(255,255,255); min-height:19px">$ npm -v
|
Nginx站点与NodeJS站点共存的配置
首先是网站入口问题,Nginx使用了80端口,NodeJS使用8080端口。我们利用Nginx的“proxy_pass”将对80端口NodeJS站点的访问导向8080端口,在LuManager中,这个配置十分简单:
1、进入LuManager后台,用“快速建站”建立NodeJS网站,如testnodejs.com网站,这里也可建立多个NodeJS网站,网站域名按如下方式填写即可:
1
|
testnodejs.com *.testnodejs.com testnodejs2.com *.testnodejs2.com
|
使他们指向共同的NodeJS网站群根目录,如nodejs目录。
2、然后为NodeJS网站配置Nginx,修改该NodeJS网站配置,进入选填项,在Nginx扩展设置(location段)**添加如下代码:
1
|
proxy_pass http://127.0.0.1:8080;
|
如此一来,外部对testnodejs.com、testnodejs2.com等NodeJS网站的访问全部转向了8080端口,NodeJS监听8080端口即可。而该NodeJS网站群的根目录即上面设置的nodejs目录,我们可在该目录中再搭设testnodejs.com、testnodejs2.com等虚拟站点。
安装Forever后台管理器
我们不可能直接通过node命令来管理远程站点,这样无法保证网站的可持续运行。我们用Forever来解决这个问题,它可以将NodeJS应用以后台守护进程的方式运行,我们还可以将NodeJS应用设成随系统启动而自动运行。
首先,全局安装Forever:
1
|
$ npm install forever -g
|
安装 完后我们 就要让 express项目在后台自行运行了:
进入到 你的项目的根目录。原本 express项目的启动命令是 npm
start
,这里我用forever启动肯定不能这么搞了,我们打开 项目的package.json文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
{ "name": "node_hk", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", "express": "~4.13.1", "art-template": "~3.0.3", "morgan": "~1.6.1", "serve-favicon": "~2.3.0" } }
|
注意到 “start”脚本对应的shell指令是 node
./bin/www
,换句话说 npm
start
实际上执行的就是这个 shell命令,那么我们很容易想到 项目启动的命令 实际上就是 它了,只是 express 4.x 把这个工作 托管给了 npm。
于是,forever启动项目的命令就是:
1
|
$ forever start ./bin/www
|
好了,执行这个命令后,你的项目就托管给 forever在后台自动运行了,你关闭了 窗口也不会影响 node服务。然后再说说 关闭命令:
先查看当前交给 forever 托管的node进程:
这个命令会列出当前 被 forever托管的 nodeJS进程,如果想关闭那个,把它的id找到,执行:
如果你懒得找进程,那干脆全部关闭吧,执行:
Forever使用介绍
子命令actions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
start: 启动守护进程 stop: 停止守护进程 stopall: 停止所有的forever进程 restart: 重启守护进程 restartall: 重启所有的foever进程 list: 列表显示forever进程 config: 列出所有的用户配置项 set <key> <val>: 设置用户配置项 clear <key>: 清楚用户配置项 logs: 列出所有forever进程的日志 logs <script|index>: 显示最新的日志 columns add <col>: 自定义指标到forever list columns rm <col>: 删除forever list的指标 columns set<cols>: 设置所有的指标到forever list cleanlogs: 删除所有的forever历史日志
|
配置参数options:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
-m MAX: 运行指定脚本的次数 -l LOGFILE: 输出日志到LOGFILE -o OUTFILE: 输出控制台信息到OUTFILE -e ERRFILE: 输出控制台错误在ERRFILE -p PATH: 根目录 -c COMMAND: 执行命令,默认是node -a, append: 合并日志 -f, fifo: 流式日志输出 -n, number: 日志打印行数 pidFile: pid文件 sourceDir: 源代码目录 minUptime: 最小spinn更新时间(ms) spinSleepTime: 两次spin间隔时间 colors: 控制台输出着色 plain: no-colors的别名,控制台输出无色 -d, debug: debug模式 -v, verbose: 打印详细输出 -s, silent: 不打印日志和错误信息 -w, watch: 监控文件改变 watchDirectory: 监控*目录 watchIgnore: 通过模式匹配忽略监控 -h, help: 命令行帮助信息
|
@参考 《Nodejs进程管理模块forever详解Node.js》
@参考 zensh《阿里云主机Nginx下配置NodeJS、Express和Forever》