从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在不更新依赖的状况下将不能工做。html
这篇文章涵盖一下内容:node
Express 4 中的变化git
一个从 Express 3 迁移到 Express 4 的示例github
升级到 Express 4 的应用生成器express
主要的变化以下:npm
Express 的核心和中间件系统:对 Connect 和内建中间件的依赖被移除了。因此你必须本身添加中间件。json
路由系统数组
其它浏览器
参见:cookie
4.X 中的新特性
从 3.X 迁移到 4.X
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 中文档的说明
在 Express 4 中,如今你可使用带有一个可变参数的路径来加载中间件,而且从路由处理器中读取参数的值,例如:
app.use('/book/:id', function(req, res, next) { console.log('ID:', req.params.id); next(); })
应用隐式加载路由中间件,因此,如今你没必要担忧 router 路由中间件加载的次序问题。
定义路由的方式没有发生变化,如今增长了两个新的特性来帮助组织路由系统。
新的方法 route,针对一个路由路径建立链式的路由处理器。
新的类 express.Router,建立模块化的路由处理器
新的 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,能够帮助建立模块话的路由处理器。一个 Router 的实例就是一个完整的中间件和路由系统,因为这个缘由,它常常被称为 迷你应用。
下面演示了建立一个名为 bird.js 的路由文件,内容以下:
var express = require('express');var router = express.Router();// middleware specific to this routerrouter.use(function timeLog(req, res, next) { console.log('Time: ', Date.now()); next(); })// define the home page routerouter.get('/', function(req, res) { res.send('Birds home page'); })// define the about routerouter.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 的示例。
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 environmentsapp.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 onlyif ('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 启动。
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 environmentsapp.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 onlyif ('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,可是,升级到新版本的话,须要先卸载 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。