Переход к Express 4
Обзор
Express 4, на самом деле, ломает существующий код Express 3. Это означает, что существующее приложение Express 3 не будет работать, если обновить версию Express в установленных зависимостях данного приложения.
В этой статье содержится следующая информация:
- Изменения в Express 4.
- Пример миграции приложения Express 3 в Express 4.
- Обновление до версии генератора приложений Express 4.
Изменения в Express 4
В Express 4 реализованы следующие существенные изменения:
- Изменения ядра Express и системы промежуточных обработчиков. Зависимости от Connect и встроенных промежуточных обработчиков были удалены, поэтому вам потребуется установить промежуточные обработчики самостоятельно.
- Изменения в системе маршрутизации.
- Прочие изменения.
См. также:
Изменения ядра Express и системы промежуточных обработчиков
Express 4 больше не является зависимым от Connect, и из его ядра удалены все встроенные промежуточные обработчики,
за исключением функции express.static. Это означает, что теперь
Express представляет собой независимый веб-фреймворк маршрутизации и промежуточной обработки, и обновления промежуточных обработчиков никак не влияют на новые версии и выпуски Express.
Без встроенных промежуточных обработчиков вам необходимо явным образом установить все средства промежуточной обработки, необходимые для запуска вашего приложения. Выполните следующие действия:
- Установите модуль: 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 4.
В большинстве случаев можно просто заменить промежуточные обработчики старой, 3-й, версии на соответствующие обработчики Express 4. Дополнительную информацию можно найти в документации к модулю в GitHub.
app.use принимает параметры
В версии 4 можно использовать параметр переменной для определения пути загрузки функций промежуточной обработки, после чего считать значение параметра из обработчика маршрута. Например:
app.use('/book/:id', function (req, res, next) {
  console.log('ID:', req.params.id)
  next()
})
Система маршрутизации
Теперь промежуточные обработчики маршрутизации загружаются в приложения неявным образом, поэтому вам не нужно обращать внимание на порядок загрузки промежуточных обработчиков router.
Способ определения маршрутов остается неизменным, но в системе маршрутизации предусмотрено две новые функции, предназначенные для упорядочения маршрутов:
- Новый метод app.route()- для создания обработчиков маршрутов, образующих цепочки, для пути маршрута.
- Новый класс express.Router- для создания модульных монтируемых обработчиков маршрутов.
Метод app.route()
Новый метод app.route() позволяет создавать обработчики маршрутов, образующие цепочки, для пути маршрута. Поскольку путь указан в одном расположении, удобно создавать модульные маршруты, чтобы минимизировать избыточность и количество опечаток. Дополнительная информация
о маршрутах приводится в документации по Router().
Ниже приведен пример объединенных в цепочку обработчиков маршрутов, определенных с помощью функции 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
Еще одной функцией, позволяющей упорядочить маршруты, является новый класс express.Router, с помощью которого можно создавать модульные монтируемые обработчики маршрутов. Экземпляр Router представляет собой комплексную систему промежуточных обработчиков и маршрутизации; по этой причине его часто называют “мини-приложением”.
В приведенном ниже примере создается маршрутизатор в виде модуля, в него загружается промежуточный обработчик, определяется несколько маршрутов, и модуль монтируется в путь в главном приложении.
Например, создайте файл маршрутизатора с именем birds.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 данного маршрута.
Прочие изменения
В приведенной ниже таблице перечислены прочие, не слишком масштабные, но важные изменения, внесенные в версии Express 4:
| Объект | Описание | 
|---|---|
| Node.js | Express 4 требуется Node.js 0.10.x или более поздних версий; поддержка Node.js 0.8.x приостановлена. | 
| 
 | Модуль  | 
| 
 | Функция  | 
| 
 | Свойство приложения  | 
| 
 | Используйте  | 
| 
 | Относительные URL-адреса более не распознаются. | 
| 
 | Был массив; теперь объект. | 
| 
 | Была функция; теперь объект. | 
| 
 | Изменен на  | 
| 
 | Теперь представлен как  | 
| 
 | Удален. | 
| 
 | Удален. | 
| 
 | Функциональность ограничена установкой исходного значения cookie. Для использования дополнительных функциональных возможностей применяется
 | 
Пример миграции приложения
Ниже приводится пример миграции приложения Express 3 в Express 4.
Рассмотрим файлы app.js и package.json.
Приложение версии 3
app.js
Рассмотрим приложение Express v.3, включающее в себя следующий файл 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.bodyParser())
app.use(app.router)
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'), function () {
  console.log('Express server listening on port ' + app.get('port'))
})
package.json
Сопутствующий ему файл package.json версии 3, может выглядеть примерно так:
{
  "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 errorhandler express@latest pug@latest --save
Внесите в файл app.js следующие изменения:
- 
    Встроенные функции промежуточной обработки Express express.favicon,express.logger,express.methodOverride,express.session,express.bodyParserиexpress.errorHandlerболее не доступны в объектеexpress. Необходимо вручную установить соответствующие им альтернативные объекты и загрузить их в приложение.
- 
    Функцию app.routerзагружать не нужно. Она не является действительным объектом приложения Express 4, поэтому удалите кодapp.use(app.router);.
- 
    Убедитесь в том, что функции промежуточной обработки загружаются в соответствующем порядке, - загрузите errorHandlerпосле загрузки маршрутов приложения.
Приложение версии 4
package.json
При запуске указанной выше команды npm будет выполнено обновление 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-beta6",
    "method-override": "^2.1.2",
    "morgan": "^1.2.2",
    "multer": "^0.1.3",
    "serve-favicon": "^2.0.1"
  }
}
app.js
Затем удалите недействительный код, загрузите обязательные промежуточные обработчики и внесите остальные необходимые изменения. Файл 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), загружать его не обязательно, а приложение можно просто запустить следующим образом:
app.listen(app.get('port'), function () {
  console.log('Express server listening on port ' + app.get('port'))
})
Запустите приложение
Процесс миграции завершен, и данное приложение теперь является приложением версии Express 4. Для подтверждения запустите приложение с помощью следующей команды:
$ node .
Загрузите http://localhost:3000. Будет отображена домашняя страница в Express 4.
Обновление до версии генератора приложений Express 4
Инструмент командной строки для генерации приложений Express остается неизменным -
  express, но для обновления его до новой версии необходимо удалить установку
  генератора приложений Express 3, а затем установить новый express-generator.
Установка
Если в системе уже установлен генератор приложений Express 3, его необходимо удалить:
$ npm uninstall -g express
В зависимости от настроек прав доступа к файлам и каталогам, эту команду, возможно, следует вызвать с помощью sudo.
Теперь установите новый генератор:
$ npm install -g express-generator
В зависимости от настроек прав доступа к файлам и каталогам, эту команду, возможно, следует вызвать с помощью sudo.
Итак, команда express в вашей системе обновлена до версии генератора
Express 4.
Изменения генератора приложений
Опции команд и их использование, в основном, остались без изменений, за исключением следующих:
- Удалена опция --sessions.
- Удалена опция --jshtml.
- Добавлена опция --hoganдля поддержки Hogan.js.
Пример
Выполните следующую команду для создания приложения Express 4:
$ express app4
Обратив внимание на содержимое файла app4/app.js, вы заметите, что все функции
промежуточной обработки (кроме express.static), обязательные для приложения, загружаются
как независимые модули, а промежуточный обработчик router больше не загружается в приложение явным образом.
Также вы заметите, что файл app.js теперь является модулем Node.js, а не самостоятельным приложением, которое генерировалось старой версией генератора.
После установки зависимостей запустите приложение с помощью следующей команды:
$ npm start
Обратив внимание на сценарий запуска npm в файле package.json,
вы заметите, что, фактически, командой, запускающей приложение, является
node ./bin/www, которой в Express 3 соответствовала команда node app.js.
Поскольку файл app.js, созданный генератором Express 4, теперь является модулем
Node.js, его уже нельзя запускать отдельно как приложение (если не изменить код). Модуль необходимо загрузить в файл Node.js и запустить через файл Node.js. В данном случае, файлом Node.js является ./bin/www.
Ни каталог bin, ни файл www без расширения
не являются обязательными для создания приложения Express или запуска такого приложения. Это всего лишь
рекомендованные генератором значения, которые можно менять в соответствии с вашими потребностями.
Для того чтобы избавиться от каталога www и оставить все, “как было в Express 3”,
удалите строку module.exports = 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 в начало файла app.js с помощью следующего кода:
var debug = require('debug')('app4')
Далее, замените "start": "node ./bin/www" в файле package.json на "start": "node app.js".
Итак, функциональность ./bin/www была перемещена обратно в
app.js.  Такое изменение не является рекомендованным, но цель данного упражнения заключалась в том, чтобы помочь вам разобраться в принципах работы файла ./bin/www и понять, почему файл app.js теперь нельзя запускать как самостоятельный.