[转] Express 4 中的变化
http://www.cnblogs.com/haogj/p/3985438.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 的版本化和发布就不再受到中间件的影响。
随着内建的中间件被移除,你必须显式添加所有依赖的中间件来运行你的应用,简单来说需要以下步骤:
- 安装模块:npm install –save 模块名称
- 在你的应用中,使用这个模块: require( 模块名称 )
- 基于模块的文档来使用模块
下表列出了 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 中的变化的更多相关文章
- node/静态路由/express框架中的express.static()和app.use()
此篇文章转载于 express框架中的express.static()和app.use() Express框架在使用app.use中传入express.static设置静态路由时,这个文件夹下的所有文 ...
- Mongo基础使用,以及在Express项目中使用Mongoose
MongoDB的基本使用 MongoDB特点: 使用BSON存储数据 支持相对丰富的查询操作(相对其他nosql数据库) 支持索引 副本集(支持多个实例/多个服务器运行同个数据库) 分片(数据库水平扩 ...
- js 实时监听input中值变化
注意:用到了jquery需要引入jquery.min.js. 需求: 1.每个地方需要分别打分,总分为100; 2.第一个打分总分为40; 3.第二个打分总分为60. 注意:需要判断null.&quo ...
- Node.js连接Mysql,并把连接集成进Express中间件中
引言 在node.js连接mysql的过程,我们通常有两种连接方法,普通连接和连接池. 这两种方法较为常见,当我们使用express框架时还会选择使用中间express-myconnection,可以 ...
- Express 4 中如何使用connect-mongo
正在跟随上面的教程一步一步做,在会话支持那一节中安装 connect-mongo 后,添加: var MongoStore = require('connect-mongo')(express); v ...
- 在express站点中使用ejs模板引擎
在express站点中使用ejs模板引擎 文/玄魂 目录 在express站点中使用ejs模板引擎 前言 1.1 安装 1.2修改app.js 1.3创建测试页面 前言 使用 vs创建 ...
- 第50讲:Scala中Variance变化点
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 在Visual Studio Express 2013中开发自定义控件
在专业版本中,新建项目时有"Windows Control Library"这样一个类型可以用于新建自定义控件项目. 但是Express版本中,没有这样一个类型可供选择.这里有另外 ...
- iOS中让Settings Bundle中的变化立即在App中反应出来的两种方法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了能够在Settings Bundle中的变化在进入App后 ...
随机推荐
- sql数据库优化技巧汇总
(转)SQL 优化原则 一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着 ...
- LINQ小记
//LINQ 根据长度查询出来 string[] strs = new string[] { "1", "22", "333& ...
- js 时间函数 及相关运算大全
js 时间函数 及相关运算大全 var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); ...
- iOS:不同属性声明方式的解析
代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因 ...
- iOS 宏定义_16进制色值转化为RGB返回UIColor类型对象
// 十六进制颜色 #define COLOR_WITH_HEX(hexValue) [UIColor colorWithRed:((float)((hexValue & 0xFF0000) ...
- iOS,OC,图片相似度比较,图片指纹
上周,正在忙,突然有个同学找我帮忙,说有个需求:图片相似度比较. 网上搜了一下,感觉不是很难,就写了下,这里分享给需要的小伙伴. 首先,本次采用的是OpenCV,图片哈希值: 先说一下基本思路: 1. ...
- 实现对properties文件的有序读写
最近遇到一项需求,要求把properties文件中的内容读取出来供用户修改,修改完后需要再重新保存到properties文件中.很简单的需求吧,可问题是Properties是继承自HashTable的 ...
- bzoj1912
由于k只有2,所以我们分类讨论显然当k=1时,我们只要连一条最长的路径即可就是树的直径L少走了L-1条边如果k=2时,我们再次连边成环后如果成环路径与上一次的最长路径没有相同的边,那少走的边数是路径长 ...
- Hibernate(八)一对多单向关联映射
上次的博文Hibernate从入门到精通(七)多对一单向关联映射我们主要讲解了一下多对一单向关联映射, 这次我们继续讲解一下一对多单向映射. 一对多单向关联映射 在讲解一对多单向关联之前,按 照我们的 ...
- 解决外部机器通过VM内ubuntu IP 无法访问vm内web服务的问题
1. 2.i root@ubuntu:/home/udapeng# ifconfig root@ubuntu:/www/sentry# nano uwsgi.ini root@ubuntu:/www/ ...