Moving to Express 4

Overview

Express 4是Express 3的重大更改.这意味着,如果您更新Express版本中的依存关系,则现有Express 3应用程序将无法使用.

本文介绍:

Changes in Express 4

Express 4有几项重大更改:

也可以看看:

Changes to Express core and middleware system

Express 4不再依赖Connect,并且从express.static函数中删除了所有内置的中间件. 这意味着Express现在是一个独立的路由和中间件Web框架,并且Express版本和版本不受中间件更新的影响.

如果没有内置的中间件,则必须显式添加运行应用程序所需的所有中间件. 只需遵循以下步骤:

  1. 安装模块: npm install --save <module-name>
  2. 在您的应用中,需要模块: require('module-name')
  3. 根据其文档使用模块: app.use( ... )

下表列出了Express 3中间件及其在Express 4中的对应版本.

快递3快递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 accepts parameters

在版本4中,您可以使用变量参数来定义加载中间件功能的路径,然后从路由处理程序中读取参数的值. 例如:

app.use('/book/:id', function (req, res, next) {
  console.log('ID:', req.params.id)
  next()
})

The routing system

现在,应用程序隐式地加载路由中间件,因此您不必担心中间件相对于router中间件的加载顺序.

定义路由的方式没有改变,但是路由系统具有两个新功能来帮助组织路由:

app.route() method

新的app.route()方法使您可以为路由路径创建可链接的路由处理程序. 由于路径是在单个位置指定的,因此创建模块化路由非常有帮助,减少冗余和错别字也很有帮助. 有关路由的更多信息,请参见Router()文档 .

这是通过使用app.route()函数定义的链式路由处理程序的示例.

app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })

express.Router class

有助于组织路由的另一个功能是新类express.Router ,您可以使用它来创建模块化的可安装路由处理程序. Router实例是完整的中间件和路由系统. 因此,它通常被称为"迷你应用程序".

以下示例将路由器创建为模块,在其中加载中间件,定义一些路由,并将其安装在主应用程序的路径上.

例如,在app目录中创建一个名为birds.js的路由器文件,其内容如下:

var express = require('express')
var router = express.Router()

// middleware specific to this router
router.use(function timeLog (req, res, next) {
  console.log('Time: ', Date.now())
  next()
})
// define the home page route
router.get('/', function (req, res) {
  res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
  res.send('About birds')
})

module.exports = router

然后,在应用程序中加载路由器模块:

var birds = require('./birds')

// ...

app.use('/birds', birds)

该应用程序现在将能够处理对/birds/birds/about路径的请求,并将调用特定于该路线的timeLog中间件.

Other changes

下表列出了Express 4中其他小的但重要的更改:

Object Description
Node.js Express 4需要Node.js 0.10.x或更高版本,并且已不再支持Node.js0.8.x.

http.createServer()

不再需要http模块,除非您需要直接使用它(socket.io/SPDY/HTTPS). 可以使用app.listen()函数启动该应用程序.

app.configure()

app.configure()函数已被删除. 使用process.env.NODE_ENVapp.get('env')函数检测环境并相应地配置应用程序.

json spaces

在Express 4中,默认情况下禁用json spaces应用程序属性.

req.accepted()

使用req.accepts()req.acceptsEncodings()req.acceptsCharsets()req.acceptsLanguages() .

res.location()

不再解析相对URL.

req.params

是一个数组; 现在是一个对象.

res.locals

是一个功能; 现在是一个对象.

res.headerSent

更改为res.headersSent .

app.route

现在可以作为app.mountpath .

res.on('header')

Removed.

res.charset

Removed.

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

现在,功能仅限于设置基本Cookie值. 使用res.cookie()获得更多功能.

Example app migration

这是将Express 3应用程序迁移到Express 4的示例.感兴趣的文件是app.jspackage.json .

Version 3 app

app.js

考虑具有以下app.js文件的Express v.3应用程序:

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'), function () {
  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": "*"
  }
}

Process

通过安装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.faviconexpress.loggerexpress.methodOverrideexpress.sessionexpress.bodyParserexpress.errorHandlerexpress对象上不再可用. 您必须手动安装其替代产品并将其加载到应用程序中.

  2. 您不再需要加载app.router函数. 它不是有效的Express 4应用程序对象,因此请删除app.use(app.router); 码.

  3. 确保以正确的顺序加载中间件功能-在加载应用程序路由后加载errorHandler .

Version 4 app

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'), function () {
  console.log('Express server listening on port ' + app.get('port'))
})

除非您需要直接使用http模块(socket.io/SPDY/HTTPS),否则不需要加载它,并且可以通过以下方式简单地启动应用程序:

app.listen(app.get('port'), function () {
  console.log('Express server listening on port ' + app.get('port'))
})

Run the app

迁移过程已完成,该应用程序现在是Express 4应用程序. 要确认,请使用以下命令启动应用程序:

$ node .

加载http:// localhost:3000并查看Express 4呈现的主页.

Upgrading to the Express 4 app generator

生成Express应用程序的命令行工具仍然是express ,但要升级到新版本,必须卸载Express 3应用程序生成器,然后安装新的express-generator .

Installing

如果您已经在系统上安装了Express 3应用程序生成器,则必须将其卸载:

$ npm uninstall -g express

根据文件和目录特权的配置方式,您可能需要使用sudo运行此命令.

现在安装新的生成器:

$ npm install -g express-generator

根据文件和目录特权的配置方式,您可能需要使用sudo运行此命令.

现在,系统上的express命令已更新为Express 4生成器.

Changes to the app generator

命令选项和用法在很大程度上保持不变,但以下情况除外:

Example

执行以下命令以创建Express 4应用程序:

$ express app4

如果查看app4/app.js文件的内容,则会注意到该应用程序所需的所有中间件功能( express.static除外)均作为独立模块加载,并且router中间件不再显式加载.在应用程序中.

您还将注意到app.js文件现在是Node.js模块,这与旧生成器生成的独立应用程序不同.

安装依赖项后,使用以下命令启动应用程序:

$ npm start

如果你看一下在故宫启动脚本package.json文件,你会发现,启动应用程序的实际命令是node ./bin/www ,这曾经是node app.js在快递3.

由于Express 4生成器生成的app.js文件现在是Node.js模块,因此无法再作为应用程序独立启动(除非您修改代码). 该模块必须加载到Node.js文件中,并通过Node.js文件启动. 在这种情况下,Node.js文件为./bin/www .

创建Express应用程序或启动该应用程序时, bin目录和无扩展名的www文件都不是必需的. 它们只是生成器提出的建议,因此可以随时对其进行修改以满足您的需求.

要摆脱www目录并使东西保持" Express 3方式",请删除显示为module.exports = app;的行module.exports = app;app.js文件的末尾,然后将以下代码粘贴到其位置:

app.set('port', process.env.PORT || 3000)

var server = app.listen(app.get('port'), function () {
  debug('Express server listening on port ' + server.address().port)
})

Ensure that you load the debug module at the top of the app.js file by using the following code:

var debug = require('debug')('app4')

接下来,将package.json文件中的"start": "node ./bin/www"更改为"start": "node app.js" .

现在,您已经转移的功能./bin/wwwapp.js . 不建议进行此更改,但是此练习可帮助您了解./bin/www文件的工作方式以及为何app.js文件不再自行启动.

by  ICOPY.SITE