http://expressjs.com/guide/migrating-4.html

Moving to Express 4

Overview

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:

Changes in Express 4

The main changes in Express 4 are:

See also:

Changes to Express core and middleware system

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:

  1. Install the module: npm install --save <module-name>
  2. In your app, require the module: require('module-name');
  3. Use the module according to its documentation: 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.

app.use accepts parameters

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();
})

The routing system

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:

  • A new method, app.route(), to create chainable route handlers for a route path.
  • A new class, express.Router, to create modular mountable route handlers.

app.route() method

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');
})

express.Router class

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.

Other changes

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.
http.createServer() The http module is no longer needed. The app is started using app.listen().
app.configure() app.configure() has been removed. Use process.env.NODE_ENV or app.get('env') to detect the environment and configure the app accordingly.
json spaces The json spaces application property is disabled by default in Express 4.
req.accepted() Use req.accepts()req.acceptsEncodings()req.acceptsCharsets(), and req.acceptsLanguages().
res.location() No longer resolves relative URLs.
req.params Was an array, is now an object.
res.locals Was a function, is now an object.
res.headerSent Changed to res.headersSent.
app.route Now available as app.mountpath.
res.on('header') Removed.
res.charset Removed.
res.setHeader('Set-Cookie', val) Functionality is now limited to setting the basic cookie value. Use res.cookie() for added functionality.

Example app migration

Here is an example of migrating an Express 3 application to Express 4. The files of interest are app.js and package.json.

Version 3 app

app.js

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', 'jade');
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'));
});

package.json

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",
"jade": "*"
}
}

Process

Begin the migration process by installing the required middleware for the Express 4 app and updating Express and Jade to their respective latest version with the following command:

$ npm install serve-favicon morgan method-override express-session
body-parser multer errorhandler express@latest jade@latest --save

Make the following changes to app.js:

  1. The http module is longer required, so remove var http = require('http');

  2. The built-in Express middleware express.faviconexpress.loggerexpress.methodOverrideexpress.sessionexpress.bodyParser and express.errorHandler are no longer available on the express object. You must install their alternatives manually and load them in the app.

  3. You no longer need to load app.router. It is not a valid Express 4 app object, so remove app.use(app.router);

  4. Make sure the middleware are loaded in the right order - load errorHandler after loading the app routes.

  5. Start the app with app.listen() instead of http.createServer.

Version 4 app

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",
"jade": "^1.5.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. 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', 'jade');
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'));
});

Run the app

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.

Upgrading to the Express 4 app generator

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.

Installing

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.

Changes to the app generator

Command options and use largely remain the same, with the following exceptions:

  • The --sessions option has been removed.
  • The --jshtml option has been removed.
  • The --hogan option has been added to support Hogan.js.

Example

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.

Moving to Express 4的更多相关文章

  1. Skip List & Bloom Filter

    Skip List | Set 1 (Introduction)   Can we search in a sorted linked list in better than O(n) time?Th ...

  2. [转] Creating a Simple RESTful Web App with Node.js, Express, and MongoDB

    You can find/fork the sample project on GitHub Hey! This and all my other tutorials will soon be mov ...

  3. 16 Go Concurrency Patterns: Timing out, moving on GO并发模式: 超时, 继续前进

    Go Concurrency Patterns: Timing out, moving on  GO并发模式: 超时, 继续前进 23 September 2010 Concurrent progra ...

  4. [Node.js] Level 5. Express

    Express Routes Let's create an express route that accepts GET requests on'/tweets' and responds by s ...

  5. 如何安全的将VMware vCenter Server使用的SQL Server Express数据库平滑升级到完整版

    背景: 由于建设初期使用的vSphere vCenter for Windows版,其中安装自动化过程中会使用SQL Server Express的免费版数据库进行基础环境构建.而此时随着业务量的增加 ...

  6. 【原】无脑操作:express + MySQL 实现CRUD

    基于node.js的web开发框架express简单方便,很多项目中都在使用.这里结合MySQL数据库,实现最简单的CRUD操作. 开发环境: IDE:WebStorm DB:MySQL ------ ...

  7. Express 教程 01 - 入门教程之经典的Hello World

    目录: 前言 一.Express?纳尼?! 二.开始前的准备工作 三.测试安装之经典的Hello World 四.使用express(1)来生成一个应用程序 五.说明 前言: 本篇文章是建立在Node ...

  8. VisualStudio 2015 开启IIS Express可以调试X64项目

    现在项目开发时总有时需要在X64下开发,这样我们就需要IIS Express中调试.不要总是放在IIS中,在Attach这样好慢.   如果不设置直接调试X64的程序,我们有可能会受到以下类似的错误 ...

  9. Node.js Express连接mysql完整的登陆注册系统(windows)

    windows学习环境: node 版本: v0.10.35 express版本:4.10.0 mysql版本:5.6.21-log 第一部分:安装node .Express(win8系统 需要&qu ...

随机推荐

  1. GIS制图课程目录

    由于更新次序跳跃式更新,因此很有必要整理一下全书目录,并将会按照实际学习的顺序进行更新. [前言] GIS制图课程前言 [理论篇] 理论篇-地图学与GIS制图的基础理论(一) 理论篇-地图学与GIS制 ...

  2. javascript this的一些误解

    太拘泥于"this"的字面意思就会产生一些误解.有两种常见的对于this 的解释,但是它们都是错误的. 1.指向自身 人们很容易把this 理解成指向函数自身,这个推断从英语的语法 ...

  3. 读书笔记 effective c++ Item 2 尽量使用const,枚举(enums),内联(inlines),不要使用宏定义(define)

    这个条目叫做,尽量使用编译器而不要使用预处理器更好.#define并没有当作语言本身的一部分. 例如下面的例子: #define ASPECT_RATIO 1.653 符号名称永远不会被编译器看到.它 ...

  4. IOS之TableViewCell重用机制解决上下刷新重复显示

    首先我是一个经验浅薄的iOS开发人员,这个问题想必许多初学者经常遇到这些问题,在面试中也会经常问到.现在我们一一解决. 首先我们要知道TableViewCell重用机制的原理是什么,我们抽象的理解为古 ...

  5. matlab 自定义函数及调用

    这一篇博客主要学习了: 第一,自定义函数优点有很多,比如可重复利用:容易纠错,以后直接装入大工程里(更重要的是,实参是复制给形参的,在自定义函数中运行时形参独立显示,这一点和C不一样). 第二,通过h ...

  6. [Android] "Failed to find Java version for 'C:\Windows\system32\java.exe"

    Impossible to install SDK r17 on win 7 x64 "Failed to find Java version for 'C:\Windows\system3 ...

  7. Myeclipse 搭建Java Web 项目:Servlet 《二》

    上一节,我们使用myeclipse部署了web项目,但那部署的为静态的web项目,下面我们来学习编写动态的web项目,编写动态项目必须要用到的为:servlet. Servlet是由sun公司命名的, ...

  8. Redis之Sentinel高可用安装部署

    背景: 之前通过Redis Sentinel 高可用实现说明和Redis 复制.Sentinel的搭建和原理说明大致已经介绍了sentinel的原理和实现,本文再次做个简单的回顾.具体的信息见前面的两 ...

  9. SaberRD之交流分析

    交流分析(AC Analysis)也叫做小信号(Small-Signal)分析,也即分析电路的小信号频率响应,更严谨的定义是:分析工作在直流偏置电压下的非线性电路对于一定频率范围内的输入小信号的系统响 ...

  10. [看图说话] 基于Spark UI性能优化与调试——初级篇

    Spark有几种部署的模式,单机版.集群版等等,平时单机版在数据量不大的时候可以跟传统的java程序一样进行断电调试.但是在集群上调试就比较麻烦了...远程断点不太方便,只能通过Log的形式,进行分析 ...