原文地址: http://expressjs.com/migrating-4.html

概览

从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在不更新依赖的情况下将不能工作。

这篇文章涵盖一下内容:

  • Express 4 中的变化
  • 一个从 Express 3 迁移到 Express 4 的示例
  • 升级到 Express 4 的应用生成器

Express 4 中的变化

主要的变化如下:

  • Express 的核心和中间件系统:对 Connect 和内建中间件的依赖被移除了。所以你必须自己添加中间件。
  • 路由系统
  • 其它

参见:

  • 4.X 中的新特性
  • 从 3.X 迁移到 4.X

Express 的核心和中间件系统

Express 4 不再依赖 Connect,并且从核心中移除了所有内建的中间件,除了 express.static 之外。这意味着 Express 现在是一个不依赖路由和中间件的 Web 框架。这样 Express 的版本化和发布就不再受到中间件的影响。

随着内建的中间件被移除,你必须显式添加所有依赖的中间件来运行你的应用,简单来说需要以下步骤:

  1. 安装模块:npm install –save 模块名称
  2. 在你的应用中,使用这个模块: require( 模块名称 )
  3. 基于模块的文档来使用模块

下表列出了 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
express.timeout connect-timeout

完整的列表见这里:https://github.com/senchalabs/connect#middleware

多数情况下,你可以使用 Express 4 中对应 Express 3 的模块来替换老的模块,详细的说明见 GitHub 中文档的说明

App.use 接受的参数

在 Express 4 中,现在你可以使用带有一个可变参数的路径来加载中间件,并且从路由处理器中读取参数的值,例如:

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

路由系统

应用隐式加载路由中间件,所以,现在你不必担心 router 路由中间件加载的次序问题。

定义路由的方式没有发生变化,现在增加了两个新的特性来帮助组织路由系统。

  • 新的方法 route,针对一个路由路径创建链式的路由处理器。
  • 新的类 express.Router,创建模块化的路由处理器

app.route 方法

新的 app.route 方法对特定的路由路径创建链式的路由处理器。由于可以在一个地方定义路径,这样有助于创建模块话的路由规则,减少重复。

路由的详细信息,可以参见 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 类

另外一个帮助组织路由的特性是新的类 express.Router,可以帮助创建模块话的路由处理器。一个 Router 的实例就是一个完整的中间件和路由系统,由于这个原因,它经常被称为 迷你应用。

下面演示了创建一个名为 bird.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 中间件。

其它变化

下表列出了其它小的但是重要的修改

对象

说明

Node

Express 4 需要 Node 0.10.x 及其以上版本,已经不支持 0.8.x

http.createServer

不再需要 http 模块,应用使用 app.listen() 启动

app.configure()

app.configure() 已经被移除,使用 process.env.NODE_ENV 或者 app.get(“env”) 来检测环境、配置应用

json.spaces()

在 Express 4 中默认禁用了 json spaces

Req.location()

不再能获取相对 url

Req.params

原来是一个数组,现在是对象

Res.locals

原来是函数,现在是对象

Res.headerSent

修改为 res.headersSent

App.route

现在作为 app.mountpath 存在

Res.on(“header”)

删除

Res.charset

删除

Res.setHeader(“Set-Cookie”, val)

这个功能现在限制为设置基本的 cookie 值,使用 res.cookie() 的添加功能

示例

这里是一个从 Express 3 升级到 Express 4 的示例。

Version 3 app

app.js

原来的 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', '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 如下所示

{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.12.0",
"jade": "*"
}
}

迁移过程

在迁移之前,先安装 Express 4 需要的中间件,还要更新 express,Jade 到最新的版本。

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

对 app.js 进行一下的修改。

1.  http 模块已经使用了,所以,删除 var http = require( "http" );

2. 内建的中间件 express.favicon, express.logger, express.methodOverride, express.session, express.bodyParser 和 express.errorHandler 已经不存在了,你必须手动安装,然后在应用中替换它们。

3. 不再需要加载 app.router ,实际上,它也已经不是 Express 4 中的对象,所以,删除 app.use( app.router );

4. 使用 app.listen() 来取代 http.createServer 启动。

Version 4 app

package.json

执行上面的命令,会如下更新 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",
"jade": "^1.5.0",
"method-override": "^2.1.2",
"morgan": "^1.2.2",
"multer": "^0.1.3",
"serve-favicon": "^2.0.1"
}
}

app.js

然后,删除无效的代码,加载需要的中间件,完成其它必须的修改,最终的 app.js 看起来如下所示:

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'))); // development only
if ('development' == app.get('env')) {
app.use(errorHandler());
} app.get('/', routes.index);
app.get('/users', user.list); app.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

运行应用

现在,迁移已经完成了,使用如下命令启动。

$ node app

使用浏览器访问 http://localhost:3000,查看使用 Express 4 生成的页面。

升级到 Express 4 的应用生成器

生成一个 Express 4 的命令行工具还是 express,但是,升级到新版本的话,需要先卸载 Express 3 的生成器,然后安装新的生成器。

安装

如果你已经安装过 Express 3 的生成器,必须先卸载

npm uninstall –g express 

依赖与你的目录权限和配置,可能需要先执行 sudo 提升权限。

现在,安装新的生成器

Npm install –g express-generator

现在,你系统中的 express 命令已经升级为 Express 4 的生成器了。

生成器的变化

除了下面的变化,基本上与以前相同。

--sessions 选项被删除了

--jshtml 选项被删除了

--hogan 被添加,以便支持 Hogan.js

示例

执行下面的命令,创建 app4 应用

express app4

如果你查看 app4 文件夹中的 app.js 文件,你会发现所有的中间件被替换为独立的中间件加载,router 中间件不再显式加载。

你还会注意到 app.js 现在是一个 Node 模块。

安装依赖的文件之后,使用下面的命令启动应用。

$ npm start

如果你查看 package.json 中的启动脚本,你会注意到实际的启动脚本是 node ./bin/www,在 Express 3 中是 node app.js

由于 Express 4 新生成的 app.js 已经是一个 Node 模块,它可以不再需要通过一个独立的应用来启动,它可以在 Node 文件中加载,通过 Node 文件启动,这里就是 ./bin/www

不管是 bin 文件夹,还是 www 文件,他们都是手工由 Express 生成器生成的,所以,需要的话,都可以进行修改。

为了与 Express 3 保持一致,删除 module.experts = 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);
});

确认加载 debug 模块。

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

然后将 package.json 文件中的 start: "node ./bin/www" 修改为 "start": "node app.js"。

现在,已经从 ./bin/www 回到了 app.js。

迁移到 Express 4.x的更多相关文章

  1. Express 4 更新改变文档

    概览 从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在不更新依赖的情况下将不能工作. 这篇文章涵盖一下内容: Express 4 中的变化 一 ...

  2. [转] Express 4 中的变化

    http://www.cnblogs.com/haogj/p/3985438.html 概览 从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在 ...

  3. Express 学习笔记纯干货(Routing、Middleware、托管静态文件、view engine 等等)

    原始文章链接:http://www.lovebxm.com/2017/07/14/express-primer/ 1. Express 简介 Express 是基于 Node.js 平台,快速.开放. ...

  4. 学习Nodejs:《Node.js开发指南》微博项目express2迁移至express4过程中填的坑

    <Node.js开发指南>项目地址https://github.com/BYVoid/microblog好不容易找到的基础版教程,但书中是基于express2的,而现在用的是express ...

  5. Express (Routing、Middleware、托管静态文件、view engine 等等)

    1. Express 简介 Express 是基于 Node.js 平台,快速.开放.极简的 web 开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用. Express 不对 ...

  6. 使用LocalDB部署Asp.Net MVC网站时遇到的问题

    首先一句话介绍LocalDB.LocalDB是SQLServer的文件数据库,类似于SQLite.它拥有SQLServer的绝大部分功能,简单易用.但部署LocalDB到生产系统是不推荐的.本文部署是 ...

  7. VMWare vCenter 4.x 数据库由SQL Express 迁移至SQL Server 2008 R2

    默认安装下的 VMware vCenter 4.x 会在本地安装 SQL Express 2005 版本,如果你有需要迁移至 Full SQL Server版本比如 SQL Server 2008 R ...

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

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

  9. Code First 迁移,及迁移错误

    迁移错误: 今天在使用EF6 Code First时,出现如下错误,折腾了老半天.分享一下,帮后面的兄弟少走弯路. PM> Enable-Migrations Checking if the c ...

随机推荐

  1. Jedis编程设计:连接池

        Jedis作为redis的最佳客户端,它提供了连接池的特性,"连接池"在通常情况下可以有效的提高应用的通信能力,并且这是一种良好的设计模式.Jedis的连接池设计基于apa ...

  2. MySQL存储引擎MyISAM与InnoDB的优劣

    使用MySQL当然会接触到MySQL的存储引擎,在新建数据库和新建数据表的时候都会看到. MySQL默认的存储引擎是MyISAM,其他常用的就是InnoDB了. 至于到底用哪种存储引擎比较好?这个问题 ...

  3. Linux后台开发常用工具

    内存分析工具valgrind valgrind辅助工具qcachegrind 可视化查看valgrind结果 淘宝DBA团队发布的监控脚本,使用perl开发,可以完成对linux系统和MySql相关指 ...

  4. Linux中文件描述符fd和文件指针flip的理解

    转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html 简单归纳:fd只是一个整数,在open时产生.起到一个索引的作用,进程通 ...

  5. CXF发布restful WebService的入门例子(客户端)

    上篇说了怎么用cxf发布restful webservice,由于浏览器只能对该service发送http的GET请求,所以如果想对服务器上的数据,还需要实现客户端. 客户端的实现方式有无数种...可 ...

  6. BEvent_客制化Event Agent通道(案例)(待整理)

    2014-09-09 Created By BaoXinjian

  7. Java爬虫搜索原理实现

    permike 原文 Java爬虫搜索原理实现 没事做,又研究了一下爬虫搜索,两三天时间总算是把原理闹的差不多了,基本实现了爬虫搜索的原理,本次实现还是俩程序,分别是按广度优先和深度优先完成的,广度优 ...

  8. 实现读入一个彩色视频文件并以灰度格式输出这个视频文件,学习opencv例2-10

    #include "cv.h"#include "highgui.h"int main(int argc,char* argv[]){ //书本中的main没有 ...

  9. svn 中 版本回退

    譬如有个文件,有十个版本,假定版本号是1,2,3,4,5,6,7,8,9,10. Revert to this revision: 如果在版本6这里点击“Revert to this revision ...

  10. vim 学习日志(3):跳到行尾、行首、文件尾、文件首、加密

    vi操作: 1.跳到文本的最后一行:按“G”,即“shift+g” 2.跳到最后一行的最后一个字符 : 先重复1的操作即按“G”,之后按“$”键,即“shift+4”. 3.跳到第一行的第一个字符:先 ...