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》