Node.js開發框架Express4.x搭建(ubuntu)
這時我們就著手安裝express框架,指令如下: ~ npm install -g express-generator@4 #全局安裝-g
如果需要使用4.0,這里有個需要注意的問題在4.x版本express 已經把命令行工具分離出來
我們現在全局安裝只需要安裝這個命令行工具就可以,指令如下:
npm install -g express-generator
安裝好express-generator包后,我們在命令行就可以使用express命令了。
~ express -V # 檢查express的版本 4.11.2 ~ express -h # 檢查看express的幫助命令
接下來,我們使用express的命令,來創建項目了。
-
express blog &&cd blog
( blog是安裝的文件夾名)
進入項目目錄,下載依賴庫,構建項目。
-
npm install
(安裝express及依賴)
啟動項目。
-
npm start
-
第一次啟動發生了錯誤,可能是express-generator和express不匹配造成的,找到問題在app.js文件中,注釋第9行和第26行。
.. //var users = require('./routes/users'); .. //app.use('/users', users); ..-
再次啟動項目
D:\workspace\javascript\nodejs-demo>npm start > express4-demo@0.0.0 start D:\workspace\javascript\nodejs-demo > node ./bin/www
項目啟動成功,打開瀏覽器 http://localhost:3000,就可以看到顯示的頁面了。
項目啟動成功,打開瀏覽器 http://localhost:3000,就可以看到顯示的頁面了。
2. 目錄結構
接下來,我們詳細看一下Express4項目的結構、配置和使用。
-
bin, 存放啟動項目的腳本文件
-
node_modules, 存放所有的項目依賴庫。
-
public,靜態文件(css,js,img)
-
routes,路由文件(MVC中的C,controller)
-
views,頁面文件(Ejs模板)
-
package.json,項目依賴配置及開發者信息
-
app.js,應用核心配置文件
3. package.json項目配置
package.json用于項目依賴配置及開發者信息,scripts屬性是用于定義操作命令的,可以非常方便的增加啟動命令,比如默認的start,用npm start代表執行node ./bin/www命令。
查看package.json文件。
{
"name": "express4-demo",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.10.2",
"cookie-parser": "~1.3.3",
"debug": "~2.1.1",
"ejs": "~2.2.3",
"express": "~4.11.1",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0"
}
} 4. app.js核心文件
從Express3.x升級到Express4.x,主要的變化就在app.js文件中。查看app.js文件,我已經增加注釋說明。
// 加載依賴庫,原來這個類庫都封裝在connect中,現在需地注單獨加載
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();
// 定義EJS模板引擎和模板文件位置,也可以使用jade或其他模型引擎
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// 定義icon圖標
app.use(favicon(__dirname + '/public/favicon.ico'));
// 定義日志和輸出級別
app.use(logger('dev'));
// 定義數據解析器
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 定義cookie解析器
app.use(cookieParser());
// 定義靜態文件目錄
app.use(express.static(path.join(__dirname, 'public')));
// 匹配路徑和路由
app.use('/', routes);
//app.use('/users', users);
// 404錯誤處理
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 開發環境,500錯誤處理和錯誤堆棧跟蹤
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
});
});
}
// 生產環境,500錯誤處理
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
// 輸出模型app
module.exports = app; 我們看到在app.js中,原來調用connect庫的部分都被其他的庫所代替,serve-favicon、morgan、cookie-parser、body-parser,默認項目中,只用到了最基本的幾個庫,還沒有其他需要替換的庫,在本文最后有詳細列出。
另外,原來用于項目啟動代碼也被移到./bin/www的文件,www文件也是一個node的腳本,用于分離配置和啟動程序。
查看./bin/www文件。
#!/usr/bin/env node
/**
* 依賴加載
*/
var app = require('../app');
var debug = require('debug')('nodejs-demo:server');
var http = require('http');
/**
* 定義啟動端口
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* 創建HTTP服務器實例
*/
var server = http.createServer(app);
/**
* 啟動網絡服務監聽端口
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* 端口標準化函數
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
/**
* HTTP異常事件處理函數
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* 事件綁定函數
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
} 5. Bootstrap界面框架
創建Bootstrap界面框架,直接在index.ejs文件上面做修改。可以手動下載Bootstrap庫放到項目中對應的位置引用,也可以通過bower來管理前端的Javascript庫,參考文章 bower解決js的依賴管理。另外還可以直接使用免費的CDN源加載Bootstrap的css和js文件。下面我就直接使用Bootcss社區提供的CDN源加載Bootstrap。
編輯views/index.ejs文件
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" >
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<div class="well jumbotron">
<h1><%= title %></h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>
效果如下,已經加入了bootstrap的樣式了。
接下來,我們把index.ejs頁面切分成3個部分:header.ejs, index.ejs, footer.ejs,用于網站頁面的模塊化。
-
header.ejs, 為頁面的頭部區域
-
index.ejs, 為內容顯示區域
-
footer.ejs,為頁面底部區域
編輯header.ejs。
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel="stylesheet" >
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
編輯footer.ejs。
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>
編輯footer.ejs。
<div class="well jumbotron">
<h1><%= title %></h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
把頁表和頁底的代碼分離后,讓index.ejs頁面的核心代碼更少,更容易維護。
6. 路由功能
路由功能,是Express4以后全面改版的功能。在應用程序加載隱含路由中間件,不用擔心在中間件被裝載相對于路由器中間件的順序。定義路由的方式是不變的,路由系統中增加2個新的功能。
-
app.route()函數,創建可鏈接的途徑處理程序的路由路徑。
-
express.Router類,創建模塊化安裝路徑的處理程序。
app.route方法會返回一個Route實例,它可以繼續使用所有的HTTP方法,包括get,post,all,put,delete,head等。
app.route('/users')
.get(function(req, res, next) {})
.post(function(req, res, next) {}) express.Router 類,則可以幫助我們更好的組織代碼結構。在app.js文件中,定義了app.use(‘/’, routes); routes是指向了routes目錄下的index.js文件,./routes/index.js文件中,express.Router被定義使用, 路徑/*處理都會由routes/index.js文件里的Router來處理。如果我們要管理不同的路徑,那么可以直接配置為多個不同的Router。
app.use('/user', require('./routes/user').user);
app.use('/admin', require('./routes/admin').admin);
app.use('/', require('./routes')); 7. 程序代碼
對于剛接觸Express4.x的朋友,可以直接從Github上面下載本文項目中的源代碼,按照片文章中的介紹學習Express4,下載地址:https://github.com/bsspirit/nodejs-demo/tree/express4
也可以直接用github命令行來下載:
~ git clone git@github.com:bsspirit/nodejs-demo.git # 下載github項目 ~ cd nodejs-demo # 進入下載目錄 ~ git checkout express4 # 切換到express4的分支 ~ npm install # 下載依賴庫 ~ npm start # 啟動服務器
注:Github上本項目有3分支,express3和master分支都是express3的例子,express4分支是本文的例子。
當然,本文對express4的介紹其實還遠遠不夠,除了文中說到的express改動的部分,其他的部分都express3類似,所以更詳細的使用說明,還請大家同時參考文章,Nodejs開發框架Express3.0開發手記–從零開始 來一起學習。
8. Express3.x和Express4.x的改動列表
最后,列舉一下3.x的內置模塊和4.x模塊的對照表,我們可以發現大部分都是connect部分的替換。關于connect庫的詳細介紹,可以參考文章,Nodejs基礎中間件Connect
