安裝 Nodejs
去Nodejs官網根據自己的操作系統下載對應的安裝包並安裝。我們就有了NodeJS和npm環境。npm是Node的包管理工具,會在安裝NodeJS時一並安裝。可以用以下命令查看版本號驗證我們的安裝成功與否:
sunjingdeMacBook-Pro:microblog sunjing$ node -v v0.12.2 sunjingdeMacBook-Pro:microblog sunjing$ npm -v 2.7.4
安裝 express-generator
我們使用express作為開發框架,與1版不同,新版的express已經不可以使用:
express -t ejs microblog
來快速建立網站結構,而是要額外安裝express-generator來生成網站框架。
npm install -g express-generator
'-g' 參數表示全局安裝,這樣我們就可以直接在命令行上使用了。
創建項目
創建框架
在要存放項目的目錄打開終端或命令行,使用以下命令建立網站框架:
express -e microblog
'-e' 參數表示使用ejs作為模板引擎,如不加會默認使用jade。
執行命令后會看到如下結果:
sunjingdeMacBook-Pro:~ sunjing$ express -e microblog create : microblog create : microblog/package.json create : microblog/app.js create : microblog/public create : microblog/public/javascripts create : microblog/public/images create : microblog/public/stylesheets create : microblog/public/stylesheets/style.css create : microblog/routes create : microblog/routes/index.js create : microblog/routes/users.js create : microblog/views create : microblog/views/index.ejs create : microblog/views/error.ejs create : microblog/bin create : microblog/bin/www install dependencies: $ cd microblog && npm install run the app: $ DEBUG=microblog:* ./bin/www
編輯依賴項
打開項目目錄,找到package.json文件,將其中的依賴項修改如下,在默認的依賴項里添加上我們后面將會用到的一些模塊。
"dependencies": { "body-parser": "~1.12.0", "cookie-parser": "~1.3.4", "debug": "~2.1.1", "ejs": "~2.3.1", "express": "~4.12.2", "express-session":"*", "morgan": "~1.5.1", "serve-favicon": "~2.2.0", "mongodb":"*", "connect-mongo":"*", "connect-flash":"*", "log4js":"*" }
關於依賴項版本號的書寫規則可以查看Difference between tilde(~) and caret(^) in package.json,需要注意的是雖然前面我們已經全局安裝了express-generator,這里我們仍然需要本地安裝express模塊。
安裝依賴項
好啦,現在可以安裝我們上面列出的依賴項了,在項目目錄里運行如下命令,即會多出來一個node_modules目錄,存放了各依賴模塊。
sunjingdeMacBook-Pro:microblog sunjing$ npm install
運行項目
在新的express框架下,1版上用的
node app.js
啟動命令已經不再適用,要改用
sunjingdeMacBook-Pro:microblog sunjing$ npm start > microblog@0.0.0 start /Users/sunjing/microblog > node ./bin/www
為什么呢?因為在package.json中有這樣配置
"scripts": { "start": "node ./bin/www" }
所以用 npm start 命令等同於:
sunjingdeMacBook-Pro:microblog sunjing$ node ./bin/www
我們后面使用forever管理進程的時候還會提到這里。
這時候我們已經可以在瀏覽器里用3000端口http://localhost:3000/查看我們的網站頁面了。
打開 app.js

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'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); // 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;
其中
var routes = require('./routes/index'); var users = require('./routes/users');
表示引用routes文件夾下的index.js和users.js
app.use('/', routes); app.use('/users', users);
// 掛載至 / 的中間件,任何指向 / 的請求都會執行它
// 掛載至 /users 的中間件,任何指向 /users 的請求都會執行它
這里還有應用級中間件、路由級中間件(區別待查。。。歡迎交流)
應用級中間件
應用級中間件綁定到 app 對象 使用 app.use()
和 app.METHOD()
, 其中, METHOD
是需要處理的 HTTP 請求的方法,例如 GET, PUT, POST 等等,全部小寫。例如:

var app = express(); // 沒有掛載路徑的中間件,應用的每個請求都會執行該中間件 app.use(function (req, res, next) { console.log('Time:', Date.now()); next(); }); // 掛載至 /user/:id 的中間件,任何指向 /user/:id 的請求都會執行它 app.use('/user/:id', function (req, res, next) { console.log('Request Type:', req.method); next(); }); // 路由和句柄函數(中間件系統),處理指向 /user/:id 的 GET 請求 app.get('/user/:id', function (req, res, next) { res.send('USER'); });
路由級中間件
路由級中間件和應用級中間件一樣,只是它綁定的對象為 express.Router()
。

var app = express(); var router = express.Router(); // 沒有掛載路徑的中間件,通過該路由的每個請求都會執行該中間件 router.use(function (req, res, next) { console.log('Time:', Date.now()); next(); }); // 一個中間件棧,顯示任何指向 /user/:id 的 HTTP 請求的信息 router.use('/user/:id', function(req, res, next) { console.log('Request URL:', req.originalUrl); next(); }, function (req, res, next) { console.log('Request Type:', req.method); next(); }); // 一個中間件棧,處理指向 /user/:id 的 GET 請求 router.get('/user/:id', function (req, res, next) { // 如果 user id 為 0, 跳到下一個路由 if (req.params.id == 0) next('route'); // 負責將控制權交給棧中下一個中間件 else next(); // }, function (req, res, next) { // 渲染常規頁面 res.render('regular'); }); // 處理 /user/:id, 渲染一個特殊頁面 router.get('/user/:id', function (req, res, next) { console.log(req.params.id); res.render('special'); }); // 將路由掛載至應用 app.use('/', router);