Express 迁移到 4.x 版本
概述
Express 4 相对于 Express 3 引入了重大变化。如果你决定更新 Express 版本,现有的 Express 3 应用需要进行迁移和修改才能继续运行。
本文涵盖:
- Express 4 的主要变化。
- 一个将 Express 3 应用迁移到 Express 4 的示例。
- 如何升级到 Express 4 的应用生成器。
Express 4 的变化
Express 4 引入了几个重大变化,包括:
- Express 核心和中间件系统的更改:不再依赖 Connect,删除了所有内置中间件,除了
express.static
。 - 路由系统的更改。
- 其他一些小但重要的变化。
对 Express 核心和中间件系统的更改
Express 4 不再依赖 Connect,并且删除了核心中的所有内置中间件,除了 express.static
。现在,Express 是一个独立的路由和中间件 Web 框架,不再受中间件更新的影响。
若要添加中间件,需要显式安装并加载它们。以下是操作步骤:
- 安装模块:
npm install --save <module-name>
- 在应用中引用模块:
require('module-name')
- 根据模块文档使用它:
app.use(...)
以下是 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 3 中间件替换为 Express 4 对应的中间件。详细信息请参考 GitHub 上的模块文档。
app.use 接受参数
在 Express 4 中,可以使用可变参数定义加载中间件函数的路径,并从路由处理程序中读取参数的值。例如:
app.use('/book/:id', (req, res, next) => {
console.log('ID:', req.params.id);
next();
});
路由系统
Express 4 现在隐式加载路由中间件,因此你不需要担心中间件相对于 router 中间件的加载顺序。路由定义方式没有改变,但有两个新特性:
app.route()
方法:为路由路径创建可链式路由处理程序。express.Router
类:创建模块化可挂载的路由处理程序。
以下是使用 app.route()
方法定义的链式路由处理程序的示例:
app.route('/book')
.get((req, res) => {
res.send('Get a random book');
})
.post((req, res) => {
res.send('Add a book');
})
.put((req, res) => {
res.send('Update the book');
});
使用 express.Router
类可以创建模块化的路由处理程序,通常被称为“mini-app”。
其他变化
以下是 Express 4 中其他一些重要的变化:
目的 | 描述 |
---|---|
Node.js | Express 4 需要 Node.js 0.10.x 或更高版本,不再支持 Node.js 0.8.x。 |
http.createServer() | 不再需要 http 模块,除非需要直接使用它(如 socket.io/SPDY/HTTPS)。可以直接使用 app.listen() 启动应用。 |
app.configure() | 已删除。使用 process.env.NODE_ENV 或app.get('env') 检测环境并配置应用。 |
json spaces | 在 Express 4 中默认禁用 json spaces 应用属性。 |
req.accepted() | 使用 req.accepts() 、req.acceptsEncodings() 、req.acceptsCharsets() 和 req.acceptsLanguages() 。 |
res.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
和 package.json
文件。
版本 3 应用
以下是 Express v3 的 app.js
和 package.json
文件示例:
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', '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.json()); // 修改:使用 express.json 替代 express.bodyParser
app.use(express.urlencoded({ extended: true })); // 修改:使用 express.urlencoded 替代 express.bodyParser
app.use(app.router); // 修改:在 Express 4 中,这不再需要
app.use(express.static(path.join(__dirname, 'public')));
// development only
if (app.get('env') === 'development') {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), () => {
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",
"pug": "*"
}
}
迁移过程
要开始迁移过程,请安装 Express 4 应用所需的中间件,并更新 Express 和 Pug 到各自最新版本:
$ npm install serve-favicon morgan method-override express-session body-parser multer express@latest pug@latest --save
对 app.js
进行以下更改:
- 删除
express.bodyParser
,替换为body-parser
和multer
。 - 删除
app.use(app.router);
,因为这不是 Express 4 应用的有效对象。 - 确保中间件按正确顺序加载,错误处理中间件应加载在路由之后。
版本 4 应用
更新后的 package.json
和 app.js
文件如下:
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",
"pug": "^2.0.0",
"method-override": "^2.1.2",
"morgan": "^1.2.2",
"multer": "^0.1.3",
"serve-favicon": "^2.0.1"
}
}
app.js
:
var http = require('http');
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(path.join(__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 (app.get('env') === 'development') {
app.use(errorHandler());
}
var server = http.createServer(app);
server.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'));
});
如果你不需要直接操作 http
模块(例如,使用 socket.io
、SPDY
或 HTTPS
),则无需显式引用它。Express 应用可以通过以下简洁的方式启动:
app.listen(app.get('port'), () => {
console.log('Express server listening on port ' + app.get('port'));
});
运行迁移后的应用程序
一旦迁移过程完成,你的应用程序将升级至 Express 4。为了验证升级是否成功,请执行以下命令来启动应用:
$ node app.js
启动后,打开浏览器,访问 http://localhost:3000
,你将能够看到由 Express 4 提供服务的主页。
升级至 Express 4 应用生成器
要升级到 Express 4 的应用生成器,请按照以下步骤操作:
- 卸载旧版生成器 — 如果已安装 Express 3 生成器,请运行以下命令来卸载它:
$ npm uninstall -g express
- 安装新版生成器 — 安装 Express 4 的
express-generator
:$ npm install -g express-generator
创建新的 Express 4 应用
使用新的 express
命令创建一个名为 app4
的应用:
$ express app4
启动新创建的应用
安装所有依赖后,通过运行以下命令来启动你的 Express 4 应用:
$ npm start
这将执行 package.json
中定义的 start
脚本,该脚本现在指向 ./bin/www
文件。这是 Express 4 生成器的一个变化,它使用一个单独的启动脚本来管理应用的监听端口。
注意:./bin/www
文件是 Express 4 生成器引入的一个新特性,它允许应用以模块化的方式运行。如果你更喜欢 Express 3 的直接启动方式,可以通过以下步骤进行调整:
1、删除 app.js
文件底部的 module.exports = app;
行。
2、在原位置添加以下代码,直接启动服务器:
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), () => {
console.log('Express server listening on port', server.address().port);
});
3、在 package.json
文件中,将 "start": "node ./bin/www"
修改为 "start": "node app.js"
。
这样,你就可以像 Express 3 那样直接通过 node app.js
命令来启动应用了。虽然这不是 Express 4 生成器推荐的做法,但它可以帮助你理解 Express 4 的模块化结构以及如何通过 Node.js 文件启动应用。