This document might be outdated relative to the documentation in English. For the latest updates, please refer to the documentation in English.
Express 4 is a breaking change from Express 3. That means an existing Express 3 app will not work if you update the Express version in its dependencies.
This article covers:
The main changes in Express 4 are:
See also:
Express 4 no longer depends on Connect, and removes all the built-in
middleware from its core, except express.static
. This means
Express is now an independent routing and middleware web framework, and
Express versioning and releases are not affected by middleware updates.
With the built-in middleware gone, you must explicitly add all the middleware 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.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.
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.
In version 4 you can now load middleware on a path with a variable parameter and read the parameter value from the route handler. For example:
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.
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.express.Router
, to create modular mountable route handlers.The new app.route()
method enables you to create chainable route handlers
for a route path. Since the path is specified in a single location, it
helps to create modular routes and reduce redundancy and typos. For more
information on routes, see Router() documentation.
Here is an example of chained route handlers defined using 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');
})
The other feature to help 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”.
The following example creates a router as a module, loads a middleware in it, defines some routes, and mounts it on a path on the main app.
Create a router file named birds.js
in the app directory,
with the following content:
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 /birds
and
/birds/about
, along with calling the timeLog
middleware specific to the route.
The following table lists other small but important changes in Express 4.
Object | Description |
---|---|
Node | Express 4 requires Node 0.10.x or later and has dropped support for Node 0.8.x. |
|
The http module is no longer needed. The app is started using
|
|
|
|
The |
|
Use |
|
No longer resolves relative URLs. |
|
Was an array, is now an object. |
|
Was a function, is now an object. |
|
Changed to |
|
Now available as |
|
Removed. |
|
Removed. |
|
Functionality is now limited to setting the basic cookie value. Use
|
Here is an example of migrating an Express 3 application to Express 4.
The files of interest are app.js
and package.json
.
Consider an Express v.3 application with the following app.js
file:
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 ('development' == app.get('env')) {
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'));
});
The accompanying version 3 package.json
file might look
something like this:
{
"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:
$ 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
:
The http
module is longer required, so remove
var http = require('http');
The built-in Express middleware 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.
You no longer need to load app.router
.
It is not a valid Express 4 app object, so remove
app.use(app.router);
Make sure the middleware are loaded in the right order - load errorHandler
after loading the app routes.
Start the app with app.listen()
instead of
http.createServer
.
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-beta6",
"method-override": "^2.1.2",
"morgan": "^1.2.2",
"multer": "^0.1.3",
"serve-favicon": "^2.0.1"
}
}
Then, remove invalid code, load the required middleware, and make other
changes as necessary. Then app.js
will look like this:
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(__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 ('development' == app.get('env')) {
app.use(errorHandler());
}
app.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
With that, the migration process is complete, and the app is now an Express 4 app. To confirm, start the app with 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 as follows:
$ npm uninstall -g express
Depending on how your file and directory privileges are configured,
you may need to run this command with sudo
.
Now install the new generator:
$ npm install -g express-generator
Depending on how your file and directory privileges are configured,
you may need to run this command with sudo
.
Now the express
command on your system is updated to the
Express 4 generator.
Command options and use largely remain the same, with the following exceptions:
--sessions
option has been removed.--jshtml
option has been removed.--hogan
option has been added to support Hogan.js.Execute the following command to create an Express 4 app:
$ express app4
If you look at the contents of the app.js
file in the
app4
directory, you will notice that all the middleware
(except express.static
) required for the app are loaded as
independent modules and the router
middleware
is no longer explicitly loaded in the app.
You will also notice that the app.js
file is now a Node module,
compared to the standalone app generated by the old generator.
After installing the dependencies, start the app using the following command:
$ npm start
If you peek at the npm start script in 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.
Since the app.js
file generated by the Express 4 generator
is now a Node module, it can no longer be started independently as an app
(unless you modify the code). It has to be to be loaded in a Node file
and started via the Node file. The Node 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 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
app.js
, and 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);
});
Make sure to load the debug
module at the top of app.js
with the following code.
var debug = require('debug')('app4');
Next, change "start": "node ./bin/www"
in the package.json
file to "start": "node app.js"
.
With that, you just moved the functionality of ./bin/www
back to
app.js
. Not that it is recommended, but the exercise helps
to understand how ./bin/www
works and why app.js
won’t start on its own anymore.