這個翻譯StrongLoop / IBM提供.

相對於英文版說明文件,本文件可能已不合時宜。如需最新的更新,請參閱英文版說明文件

移至 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 4 有數項明顯的變更:

另請參閱:

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:

  1. 安裝模組:npm install --save <module-name>
  2. 在您的應用程式中,需要模組:require('module-name')
  3. 遵循模組的說明文件來使用該模組:app.use( ... )

下表列出 Express 3 中介軟體和其在 Express 4 中的對應項目。

Express 3Express 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() 方法

新的 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.jspackage.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 進行下列變更:

  1. express 物件中不再提供內建 Express 中介軟體函數 express.faviconexpress.logger, express.methodOverrideexpress.sessionexpress.bodyParserexpress.errorHandler。您必須手動安裝其替代項目,並將它們載入到應用程式。 You must install their alternatives manually and load them in the app.

  2. You no longer need to load the app.router function. 不再需要載入 app.router 函數。它不是有效的 Express 4 應用程式物件,因此請移除 app.use(app.router); 程式碼。

  3. 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

除了以下,指令的選項與用法大致不變:

範例

執行下列指令,以建立 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。

http.createServer()

不再需要 http 模組,除非您需要直接使用它 (socket.io/SPDY/HTTPS)。應用程式可藉由使用 app.listen() 函數來啟動。 The app can be started by using the app.listen() function.

app.configure()

The app.configure() function has been removed.
app.configure() 函數已移除。請使用 process.env.NODE_ENVapp.get('env') 函數來偵測環境,並據以配置應用程式。

json spaces

Express 4 中依預設會停用 json spaces 應用程式內容。

req.accepted()

使用 req.accepts()req.acceptsEncodings()req.acceptsCharsets()req.acceptsLanguages()。</td> </tr>

res.location()

不再解析相對 URL。

req.params

Was an array; now an object.

res.locals

Was a function; now an object.

res.headerSent

已變更為 res.headersSent

app.route

現在以 app.mountpath 形式提供。

res.on('header')

已移除。

res.charset

已移除。

res.setHeader('Set-Cookie', val)

Functionality is now limited to setting the basic cookie value. 現在功能僅限於設定基本 Cookie 值。請使用 res.cookie() 來取得新增的功能。

Edit this page