移至 Express 4
概觀
Express 4 是對 Express 3 的突破性變更。也就是說,如果您在其相依關係中更新 Express 版本,現有的 Express 3 應用程式將無法運作。 That means an existing Express 3 app will not work if you update the Express version in its dependencies.
本文涵蓋:
- Express 4 中的變更。
- 將 Express 3 應用程式移轉至 Express 4 的範例。
- 升級至 Express 4 應用程式產生器。
Express 4 中的變更
Express 4 有數項明顯的變更:
- Changes to Express core and middleware system. The dependencies on Connect and built-in middleware were removed, so you must add middleware yourself.
- 路由系統的變更。
- 其他各項變更。
另請參閱:
Express 核心和中介軟體系統的變更
Express 4 不再相依於 Connect,除了 express.static
函數,其他所有的內建中介軟體皆已從其核心移除。也就是說,Express 現在是一個獨立的路由與中介軟體 Web 架構,Express 的版本化與版次不受中介軟體更新的影響。 This means that
Express is now an independent routing and middleware web framework, and
Express versioning and releases are not affected by middleware updates.
由於沒有內建中介軟體,您必須明確新增執行您應用程式所需的所有中介軟體。只需遵循下列步驟: Simply follow these steps:
- 安裝模組:
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 中介軟體的完整清單。
In most cases, you can simply replace the old version 3 middleware with its Express 4 counterpart. For details, see the module documentation in GitHub.
app.use
接受參數
In version 4 you can use a variable parameter to define the path where middleware functions are loaded, then read the value of the parameter from the route handler. For example:
app.use('/book/:id', (req, res, next) => {
console.log('ID:', req.params.id)
next()
})
路由系統
Apps 現在隱含地載入了路由中介軟體,因此您不用再擔心該中介軟體相對於 router
中介軟體的載入順序。
路由的定義方式不變,但是路由系統多了兩個新特性,可協助您組織路由:
- 新方法
app.route()
,用來為路由路徑建立可鏈接的路由處理程式。 - 新類別
express.Router
,用來建立可裝載的模組路由處理程式。
app.route()
方法
新的 app.route()
方法可讓您為路由路徑建立可鏈接的路由處理程式。由於是在單一位置指定路徑,建立模組路由很有用,因為它可減少冗餘和打錯字的情況。如需路由的相關資訊,請參閱 Router()
說明文件。 Because the path is specified in a single location, creating modular routes is helpful, as is reducing redundancy and typos. For more
information about routes, see Router()
documentation.
下列範例顯示利用 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
類別
The other feature that helps to organize routes is a new class,
express.Router
, that you can use to create modular mountable
route handlers. A Router
instance is a complete middleware and
routing system; for this reason it is often referred to as a “mini-app”.
下列範例是將路由器建立成模組、 在其中載入中介軟體、定義一些路由,並將它裝載在主要應用程式中的路徑。
例如,在應用程式目錄中建立一個名為 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 其他小幅卻很重要的變更:
</tbody></table>
應用程式移轉範例
下列範例顯示如何將 Express 3 應用程式移轉至 Express 4。值得一提的檔案是 app.js
和 package.json
。
The files of interest are app.js
and package.json
.
第 3 版應用程式
app.js
假設 Express 第 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 中介軟體函數express.favicon
、express.logger
,express.methodOverride
、express.session
、express.bodyParser
和express.errorHandler
。您必須手動安裝其替代項目,並將它們載入到應用程式。 You must install their alternatives manually and load them in the app. -
You no longer need to load the
app.router
function. 不再需要載入app.router
函數。它不是有效的 Express 4 應用程式物件,因此請移除app.use(app.router);
程式碼。 -
Make sure that the middleware functions are loaded in the correct order - load
errorHandler
after loading the app routes.
第 4 版應用程式
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
Then, remove invalid code, load the required middleware, and make other
changes as necessary. The app.js
file will look like this:
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'))
})
Run the app
The migration process is complete, and the app is now an Express 4 app. To confirm, start the app by using the following command:
$ node .
載入 http://localhost:3000,並查看 Express 4 所呈現的首頁。
升級至 Express 4 應用程式產生器
用來產生 Express 應用程式的指令行工具仍然是 express
,但為了升級至新版本,您必須解除安裝 Express 3 應用程式產生器,再安裝新的 express-generator
。
安裝
如果您的系統已安裝 Express 3 應用程式產生器,必須解除安裝它:
$ npm uninstall -g express
視您如何配置檔案與目錄專用權而定,您可能需要使用 sudo
來執行這個指令。
現在安裝新的產生器:
$ npm install -g express-generator
視您如何配置檔案與目錄專用權而定,您可能需要使用 sudo
來執行這個指令。
現在,您系統上的 express
指令已更新為 Express 4 產生器。
Changes to the app generator
除了以下,指令的選項與用法大致不變:
- 已移除
--sessions
選項。 - 已移除
--jshtml
選項。 - 新增了
--hogan
選項,以支援 Hogan.js。
範例
執行下列指令,以建立 Express 4 應用程式:
$ express app4
如果您查看 app4/app.js
檔的內容,您會發現應用程式所需要的所有中介軟體函數(但不包括 express.static
)都載入成獨立模組,且 router
中介軟體不再明確載入到應用程式中。
您也會發現,相對於舊產生器產生的獨立式應用程式,app.js
檔現在是一個 Node.js 模組。
安裝相依關係之後,請使用下列指令來啟動應用程式:
$ npm start
如果您查看 package.json
檔中的 npm 啟動 Script,您會發現,啟動應用程式的實際指令是 node ./bin/www
,這在 Express 3 中是 node app.js
。
由於 Express 4 產生器產生的 app.js
檔現在是一個 Node.js 模組,因此無法再以應用程式形式單獨啟動它(除非您修改程式碼)。模組必須載入到 Node.js 檔,並透過 Node.js 檔啟動。在本例中,Node.js 檔是 ./bin/www
。 The module must be loaded in a Node.js file
and started via the Node.js file. The Node.js file is ./bin/www
in this case.
Neither the bin
directory nor the extensionless www
file is mandatory for creating an Express app or starting the app. They are
just suggestions made by the generator, so feel free to modify them to suit your
needs.
若要除去 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)
})
請使用下列程式碼,確定 debug
模組是載入於 app.js
檔頂端:
var debug = require('debug')('app4')
然後將 package.json
檔中的 "start": "node ./bin/www"
變更為 "start": "node app.js"
。
現在您已將 ./bin/www
的功能移回至 app.js
。不建議進行這項變更,但這項練習有助您瞭解 ./bin/www
檔的運作方式,以及 app.js
檔不再自行啟動的原因。 This change is not recommended, but the exercise helps you
to understand how the ./bin/www
file works, and why the app.js
file
no longer starts on its own.
Object | Description |
---|---|
Node.js | Express 4 需要 Node.js 0.10.x 或更新版本,且不再支援 Node.js 0.8.x。 |
|
不再需要 |
|
The |
|
Express 4 中依預設會停用 |
|
使用 |
|
不再解析相對 URL。 |
|
Was an array; now an object. |
|
Was a function; now an object. |
|
已變更為 |
|
現在以 |
|
已移除。 |
|
已移除。 |
|
Functionality is now limited to setting the basic cookie value.
現在功能僅限於設定基本 Cookie 值。請使用
|