Express 4 是 Express 3 的重大變更。這表示現有的 Express 3 應用程式在更新其相依項目的 Express 版本後,將無法正常運作。
本文涵蓋
Express 4 有幾個重大變更
另請參閱
Express 4 不再依賴 Connect,並從其核心移除所有內建中介軟體,僅保留 express.static
函式。這表示 Express 現在是一個獨立的路由和中介軟體網路架構,而 Express 的版本和發行不受中介軟體更新影響。
在沒有內建中介軟體的情況下,您必須明確新增執行應用程式所需的所有中介軟體。只需遵循下列步驟
npm install --save <module-name>
require('module-name')
app.use( ... )
下表列出 Express 3 中介軟體及其在 Express 4 中的對應中介軟體。
Express 3 | Express 4 |
---|---|
express.bodyParser |
body-parser + multer |
express.compress |
compression |
express.cookieSession |
cookie-session |
express.cookieParser |
cookie-parser |
express.logger |
morgan |
express.session |
express-session |
express.favicon |
serve-favicon |
express.responseTime |
response-time |
express.errorHandler |
errorhandler |
express.methodOverride |
method-override |
express.timeout |
connect-timeout |
express.vhost |
vhost |
express.csrf |
csurf |
express.directory |
serve-index |
express.static |
serve-static |
以下是 Express 4 中介軟體的完整清單。
在多數情況下,你可以簡單地用 Express 4 對應的版本取代舊的版本 3 中介軟體。詳細資訊請參閱 GitHub 中的模組文件。
app.use
接受參數在版本 4 中,你可以使用變數參數來定義載入中介軟體函式的路徑,然後從路由處理程式中讀取參數的值。例如
app.use('/book/:id', (req, res, next) => {
console.log('ID:', req.params.id)
next()
})
應用程式現在會隱式載入路由中介軟體,因此你不再需要擔心中介軟體載入的順序是否與 router
中介軟體有關。
你定義路由的方式沒有改變,但路由系統有兩個新功能,可以協助你整理路由
app.route()
,用於為路由路徑建立可串接的路由處理程式。express.Router
,用於建立可模組化、可掛載的路由處理程式。app.route()
方法新的 app.route()
方法讓你能夠為路由路徑建立可串接的路由處理程式。由於路徑是在單一位置指定的,因此建立模組化路由非常有幫助,而且可以減少重複和錯字。如需有關路由的更多資訊,請參閱 Router()
文件。
以下是使用 app.route()
函式定義的串接路由處理程式的範例。
app.route('/book')
.get((req, res) => {
res.send('Get a random book')
})
.post((req, res) => {
res.send('Add a book')
})
.put((req, res) => {
res.send('Update the book')
})
express.Router
類別另一個有助於整理路由的功能是一個新的類別,express.Router
,你可以使用它來建立可模組化、可掛載的路由處理程式。Router
執行個體是一個完整的軟體和路由系統;因此,它通常稱為「迷你應用程式」。
以下範例建立一個路由器作為模組,載入其中的中介軟體,定義一些路由,並將它掛載在主應用程式的路徑上。
例如,在應用程式目錄中建立一個名為 birds.js
的路由器檔案,內容如下
var express = require('express')
var router = express.Router()
// middleware specific to this router
router.use((req, res, next) => {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', (req, res) => {
res.send('Birds home page')
})
// define the about route
router.get('/about', (req, res) => {
res.send('About birds')
})
module.exports = router
然後,在應用程式中載入路由器模組
var birds = require('./birds')
// ...
app.use('/birds', birds)
應用程式現在可以處理對 /birds
和 /birds/about
路徑的請求,並且會呼叫特定於路由的 timeLog
中介軟體。
下表列出 Express 4 中其他一些小但重要的變更
物件 | 說明 |
---|---|
Node.js | Express 4 需要 Node.js 0.10.x 或更新版本,且已停止支援 Node.js 0.8.x。 |
|
不再需要 |
|
已移除 |
|
在 Express 4 中, |
|
使用 |
|
不再解析相對 URL。 |
|
以前是陣列;現在是物件。 |
|
以前是函式;現在是物件。 |
|
已變更為 |
|
現在可用為 |
|
已移除。 |
|
已移除。 |
|
功能現在僅限於設定基本 cookie 值。對於新增功能,請使用 |
以下是將 Express 3 應用程式遷移至 Express 4 的範例。相關檔案為 app.js
和 package.json
。
app.js
考慮一個 Express v.3 應用程式,其具有以下 app.js
檔案
var express = require('express')
var routes = require('./routes')
var user = require('./routes/user')
var http = require('http')
var path = require('path')
var app = express()
// all environments
app.set('port', process.env.PORT || 3000)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(express.favicon())
app.use(express.logger('dev'))
app.use(express.methodOverride())
app.use(express.session({ secret: 'your secret here' }))
app.use(express.bodyParser())
app.use(app.router)
app.use(express.static(path.join(__dirname, 'public')))
// development only
if (app.get('env') === 'development') {
app.use(express.errorHandler())
}
app.get('/', routes.index)
app.get('/users', user.list)
http.createServer(app).listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
package.json
隨附的版本 3 package.json
檔案可能類似以下內容
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.12.0",
"pug": "*"
}
}
透過安裝 Express 4 應用程式所需的中間件,並將 Express 和 Pug 更新至其各自的最新版本,以以下指令開始遷移處理
$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
對 app.js
進行以下變更
內建 Express 中間件函式 express.favicon
、express.logger
、express.methodOverride
、express.session
、express.bodyParser
和 express.errorHandler
不再於 express
物件中提供。您必須手動安裝其替代方案,並將其載入應用程式中。
您不再需要載入 app.router
函式。它不是有效的 Express 4 應用程式物件,因此請移除 app.use(app.router);
程式碼。
請確定中間件函式已載入正確順序 - 在載入應用程式路由後載入 errorHandler
。
package.json
執行上述 npm
指令將會更新 package.json
如下
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"body-parser": "^1.5.2",
"errorhandler": "^1.1.1",
"express": "^4.8.0",
"express-session": "^1.7.2",
"pug": "^2.0.0",
"method-override": "^2.1.2",
"morgan": "^1.2.2",
"multer": "^0.1.3",
"serve-favicon": "^2.0.1"
}
}
app.js
然後,移除無效程式碼、載入所需的中間件,並視需要進行其他變更。app.js
檔案將會類似以下內容
var http = require('http')
var express = require('express')
var routes = require('./routes')
var user = require('./routes/user')
var path = require('path')
var favicon = require('serve-favicon')
var logger = require('morgan')
var methodOverride = require('method-override')
var session = require('express-session')
var bodyParser = require('body-parser')
var multer = require('multer')
var errorHandler = require('errorhandler')
var app = express()
// all environments
app.set('port', process.env.PORT || 3000)
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(favicon(path.join(__dirname, '/public/favicon.ico')))
app.use(logger('dev'))
app.use(methodOverride())
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'uwotm8'
}))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(multer())
app.use(express.static(path.join(__dirname, 'public')))
app.get('/', routes.index)
app.get('/users', user.list)
// error handling middleware should be loaded after the loading the routes
if (app.get('env') === 'development') {
app.use(errorHandler())
}
var server = http.createServer(app)
server.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
除非您需要直接使用 http
模組 (socket.io/SPDY/HTTPS),否則不需要載入它,而應用程式可以單純以這種方式啟動
app.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'))
})
遷移處理已完成,而應用程式現在是 Express 4 應用程式。為確認,請使用以下指令啟動應用程式
$ node .
載入 https://127.0.0.1:3000 並查看由 Express 4 呈現的首頁。
產生 Express 應用程式的命令列工具仍然是 express
,但若要升級至新版本,您必須先解除安裝 Express 3 應用程式產生器,然後安裝新的 express-generator
。
如果您系統上已安裝 Express 3 應用程式產生器,您必須將其解除安裝
$ npm uninstall -g express
根據您的檔案和目錄權限設定,您可能需要使用 sudo
執行此命令。
現在安裝新的產生器
$ npm install -g express-generator
根據您的檔案和目錄權限設定,您可能需要使用 sudo
執行此命令。
現在您系統上的 express
命令已更新為 Express 4 產生器。
命令選項和使用方式大致保持不變,但有下列例外
--sessions
選項。--jshtml
選項。--hogan
選項以支援 Hogan.js。執行下列命令以建立 Express 4 應用程式
$ express app4
如果您查看 app4/app.js
檔案的內容,您會注意到所有應用程式所需的中間件函式(除了 express.static
)都載入為獨立模組,而且 router
中間件不再明確載入應用程式中。
您也會注意到 app.js
檔案現在是 Node.js 模組,與舊產生器產生的獨立應用程式不同。
安裝相依項後,使用下列命令啟動應用程式
$ npm start
如果您查看 package.json
檔案中的 npm start 腳本,您會注意到實際啟動應用程式的命令是 node ./bin/www
,在 Express 3 中為 node app.js
。
由於 Express 4 產生器產生的 app.js
檔案現在是 Node.js 模組,因此它不再能獨立作為應用程式啟動(除非您修改程式碼)。必須在 Node.js 檔案中載入模組,並透過 Node.js 檔案啟動。在本例中,Node.js 檔案是 ./bin/www
。
bin
目錄或沒有副檔名的 www
檔案對於建立 Express 應用程式或啟動應用程式都不是必要的。它們只是產生器提出的建議,因此您可以根據自己的需要修改它們。
若要移除 www
目錄並維持「Express 3 方式」,請刪除 app.js
檔案結尾的 module.exports = app;
行,然後貼上以下程式碼取代
app.set('port', process.env.PORT || 3000)
var server = app.listen(app.get('port'), () => {
debug('Express server listening on port ' + server.address().port)
})
請務必使用以下程式碼在 app.js
檔案的開頭載入 debug
模組
var debug = require('debug')('app4')
接著,將 package.json
檔案中的 "start": "node ./bin/www"
變更為 "start": "node app.js"
。
您現在已將 ./bin/www
的功能移回 app.js
。不建議進行此變更,但此練習有助於您了解 ./bin/www
檔案如何運作,以及 app.js
檔案為何不再自行啟動。