Express 4 is a breaking change from Express 3. Express 4是对Express 3的突破性更改。That means an existing Express 3 app will not work if you update the Express version in its dependencies.这意味着如果您在其依赖项中更新Express版本,现有的Express 3应用程序将无法工作。
This article covers:本文涵盖:
There are several significant changes in Express 4:Express 4中有几个重大变化:
See also:
Express 4 no longer depends on Connect, and removes all built-in middleware from its core, except for the express4不再依赖于Connect,并从其核心中删除了所有内置中间件(express.static
function. express.static
函数除外)。This means that Express is now an independent routing and middleware web framework, and Express versioning and releases are not affected by middleware updates.这意味着Express现在是一个独立的路由和中间件web框架,并且Express版本控制和发布不受中间件更新的影响。
Without built-in middleware, you must explicitly add all the middleware that is required to run your app. 如果没有内置中间件,则必须显式添加运行应用程序所需的所有中间件。Simply follow these steps:只需执行以下步骤:
npm install --save <module-name>
require('module-name')
app.use( ... )
The following table lists Express 3 middleware and their counterparts in Express 4.下表列出了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 |
Here is the complete list of Express 4 middleware.下面是Express 4中间件的完整列表。
In most cases, you can simply replace the old version 3 middleware with its Express 4 counterpart. 在大多数情况下,您可以简单地将旧的版本3中间件替换为对应的Express 4中间件。For details, see the module documentation in GitHub.有关详细信息,请参阅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:在版本4中,您可以使用变量参数定义加载中间件函数的路径,然后从路由处理程序读取参数值。例如:
app.use('/book/:id', function (req, res, next) {
console.log('ID:', req.params.id)
next()
})
Apps now implicitly load routing middleware, so you no longer have to worry about the order in which middleware is loaded with respect to the 应用程序现在隐式加载路由中间件,因此您不再需要担心中间件相对于router
middleware.router
中间件的加载顺序。
The way you define routes is unchanged, but the routing system has two new features to help organize your routes:定义路线的方式不变,但路线系统有两个新功能可帮助组织路线:
app.route()
, to create chainable route handlers for a route path.app.route()
,用于为路由路径创建可链接的路由处理程序。express.Router
, to create modular mountable route handlers.app.route()
The new 新的app.route()
method enables you to create chainable route handlers for a route path. app.route()
方法使您能够为路由路径创建可链接的路由处理程序。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.Router()
文档。
Here is an example of chained route handlers that are defined by using the 下面是使用app.route()
function.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
classThe other feature that helps to organize routes is a new class, 另一个有助于组织路由的功能是一个新类express.Router
, that you can use to create modular mountable route handlers. express.Router
,您可以使用它创建模块化可装载的路由处理程序。A Router
instance is a complete middleware and routing system; for this reason it is often referred to as a “mini-app”.Router
实例是一个完整的中间件和路由系统;因此,它通常被称为“迷你应用程序”。
The following example creates a router as a module, loads middleware in it, defines some routes, and mounts it on a path on the main app.下面的示例将路由器创建为模块,在其中加载中间件,定义一些路由,并将其装载到主应用程序的路径上。
For example, create a router file named 例如,在应用程序目录中创建一个名为birds.js
in the app directory, with the following content: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
Then, load the router module in the app:然后,在应用程序中加载路由器模块:
var birds = require('./birds')
// ...
app.use('/birds', birds)
The app will now be able to handle requests to the 该应用程序现在将能够处理对/birds
and /birds/about
paths, and will call the timeLog
middleware that is specific to the route./birds
和/birds/about
路径的请求,并将调用特定于路由的timeLog
中间件。
The following table lists other small but important changes in Express 4:下表列出了Express 4中的其他小而重要的更改:
Node.js | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Here is an example of migrating an Express 3 application to Express 4. 下面是一个将Express 3应用程序迁移到Express 4的示例。The files of interest are 感兴趣的文件是app.js
and package.json
.app.js
和package.json
。
app.js
Consider an Express v.3 application with the following 考虑一个带有下列app.js
file: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
The accompanying version 3 附带的版本3 package.json
file might look something like this:package.json
文件可能如下所示:
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.12.0",
"pug": "*"
}
}
Begin the migration process by installing the required middleware for the Express 4 app and updating Express and Pug to their respective latest version with the following command:通过安装Express 4应用程序所需的中间件并使用以下命令将Express和Pug更新到各自的最新版本,开始迁移过程:
$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest pug@latest --save
Make the following changes to 对app.js
:app.js
进行以下更改:
express.favicon
, express.logger
, express.methodOverride
, express.session
, express.bodyParser
and express.errorHandler
are no longer available on the express
object. You must install their alternatives manually and load them in the app.app.router
function. It is not a valid Express 4 app object, so remove the app.use(app.router);
code.errorHandler
after loading the app routes.package.json
Running the above npm
command will update package.json
as follows:
{
"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: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()
// 所有环境
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)
// 错误处理中间件应在加载路由后加载
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'))
})
Unless you need to work directly with the 除非您需要直接使用http
module (socket.io/SPDY/HTTPS), loading it is not required, and the app can be simply started this way:http
模块(socket.io/SPDY/HTTPS),否则不需要加载它,应用程序可以通过以下方式简单启动:
app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'))
})
The migration process is complete, and the app is now an Express 4 app. 迁移过程已完成,该应用程序现在是Express 4应用程序。To confirm, start the app by using the following command:要确认,请使用以下命令启动应用程序:
$ node .
Load http://localhost:3000 and see the home page being rendered by Express 4.
The command-line tool to generate an Express app is still express
, but to upgrade to the new version, you must uninstall the Express 3 app generator and then install the new express-generator
.
If you already have the Express 3 app generator installed on your system, you must uninstall it:如果系统上已安装Express 3 app generator,则必须卸载它:
$ npm uninstall -g express
Depending on how your file and directory privileges are configured, you might need to run this command with 根据文件和目录权限的配置方式,您可能需要使用sudo
.sudo
运行此命令。
Now install the new generator:现在安装新的发电机:
$ npm install -g express-generator
Depending on how your file and directory privileges are configured, you might need to run this command with 根据文件和目录权限的配置方式,您可能需要使用sudo
.sudo
运行此命令。
Now the 现在,系统上的express
command on your system is updated to the Express 4 generator.express
命令更新为express 4生成器。
Command options and use largely remain the same, with the following exceptions:命令选项和使用基本保持不变,但以下情况除外:
--sessions
option.--jshtml
option.--hogan
option to support Hogan.js.--hogan
选项以支持Hogan.js。Execute the following command to create an Express 4 app:执行以下命令以创建Express 4应用程序:
$ express app4
If you look at the contents of the 如果查看app4/app.js
file, you will notice that all the middleware functions (except express.static
) that are required for the app are loaded as independent modules, and the router
middleware is no longer explicitly loaded in the app.app4/app.js
文件的内容,您会注意到应用程序所需的所有中间件功能(express.static
除外)都作为独立模块加载,路由器中间件不再显式加载到应用程序中。
You will also notice that the 您还将注意到,app.js
file is now a Node.js module, in contrast to the standalone app that was generated by the old generator.app.js
文件现在是一个Node.js模块,与旧生成器生成的独立应用程序不同。
After installing the dependencies, start the app by using the following command:安装依赖项后,使用以下命令启动应用程序:
$ npm start
If you look at the npm start script in the package.json
file, you will notice that the actual command that starts the app is node ./bin/www
, which used to be node app.js
in Express 3.
Because the app.js
file that was generated by the Express 4 generator is now a Node.js module, it can no longer be started independently as an app (unless you modify the code). 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.
To get rid of the www
directory and keep things the “Express 3 way”, delete the line that says module.exports = app;
at the end of the app.js
file, then paste the following code in its place:
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')
Next, change "start": "node ./bin/www"
in the package.json
file to "start": "node app.js"
.
You have now moved the functionality of ./bin/www
back to 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.