Spec-Zone.ru › Express

Переход на Express 5

Обзор

Express 5 не сильно отличается от Express 4: хотя основной API остался прежним, в новой версии есть изменения, нарушающие совместимость с предыдущей. Поэтому приложение, созданное с Express 4, может перестать работать после обновления до Express 5.

Для установки этой версии требуется Node.js версии 18 или выше. Затем выполните следующую команду в каталоге приложения:

npm install "express@5"

После этого запустите автоматические тесты, чтобы выяснить, что работает неправильно, и устраните проблемы с учетом перечисленных ниже обновлений. Когда все ошибки тестов будут исправлены, запустите приложение и проверьте, какие ошибки возникнут. Вы сразу узнаете, если приложение использует неподдерживаемые методы или свойства.

Код-моды Express 5

Чтобы упростить переход на новую версию сервера Express, мы создали набор код-модов, которые помогут автоматически обновить код до последней версии Express.

Чтобы запустить все доступные код-моды, выполните следующую команду:

npx @expressjs/codemod upgrade

Чтобы запустить отдельный код-мод, выполните следующую команду:

npx @expressjs/codemod name-of-the-codemod

Список доступных код-модов можно найти здесь.

Изменения в Express 5

Удаленные методы и свойства

  • app.del()
  • app.param(fn)
  • Названия методов во множественном числе
  • Двоеточие в начале аргумента name метода app.param(name, fn)
  • req.param(name)
  • res.json(obj, status)
  • res.jsonp(obj, status)
  • res.redirect('back') и res.location('back')
  • res.redirect(url, status)
  • res.send(body, status)
  • res.send(status)
  • res.sendfile()
  • router.param(fn)
  • express.static.mime
  • журналы отладки express:router

Изменены

  • Синтаксис сопоставления маршрутов по пути
  • Обработка отклоненных промисов в промежуточном ПО и обработчиках
  • express.urlencoded
  • dotfiles в express.static
  • app.listen
  • app.router
  • req.body
  • req.host
  • req.query
  • res.clearCookie
  • res.status
  • res.vary

Улучшения

  • res.render()
  • Поддержка кодирования Brotli

Удаленные методы и свойства

Если приложение использует какой-либо из этих методов или свойств, оно завершится с ошибкой. Поэтому после обновления до версии 5 необходимо изменить приложение.

app.del()

Express 5 больше не поддерживает функцию app.del(). При ее использовании будет выдана ошибка. Для регистрации маршрутов HTTP DELETE используйте вместо нее функцию app.delete().

Изначально вместо delete использовалась del, поскольку delete — зарезервированное ключевое слово JavaScript. Однако начиная с ECMAScript 6 delete и другие зарезервированные ключевые слова разрешено использовать в качестве имен свойств.

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.del('/user/:id', (req, res) => {
  res.send(`DELETE /user/${req.params.id}`)
})

// v5
app.delete('/user/:id', (req, res) => {
  res.send(`DELETE /user/${req.params.id}`)
})

app.param(fn)

Сигнатура app.param(fn) использовалась для изменения поведения функции app.param(name, fn). Она объявлена устаревшей начиная с версии 4.11.0, а Express 5 больше не поддерживает ее.

Названия методов во множественном числе

Названия следующих методов были изменены на форму множественного числа. В Express 4 использование старых методов приводило к предупреждению об устаревании. Express 5 больше не поддерживает их:

req.acceptsCharset() заменяется на req.acceptsCharsets().

req.acceptsEncoding() заменяется на req.acceptsEncodings().

req.acceptsLanguage() заменяется на req.acceptsLanguages().

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod pluralized-methods
// v4
app.all('/', (req, res) => {
  req.acceptsCharset('utf-8')
  req.acceptsEncoding('br')
  req.acceptsLanguage('en')

  // ...
})

// v5
app.all('/', (req, res) => {
  req.acceptsCharsets('utf-8')
  req.acceptsEncodings('br')
  req.acceptsLanguages('en')

  // ...
})

Двоеточие (:) в начале имени для app.param(name, fn)

Двоеточие в начале имени функции app.param(name, fn) осталось со времен Express 3. Для обратной совместимости Express 4 поддерживал его, сопровождая использование предупреждением об устаревании. Express 5 будет молча игнорировать двоеточие и использовать параметр name без префикса.

Это не должно повлиять на ваш код, если вы следуете документации Express 4 по app.param, поскольку в ней двоеточие в начале не упоминается.

req.param(name)

Этот потенциально неоднозначный и небезопасный метод получения данных формы удален. Теперь необходимо искать имя отправленного параметра отдельно в объекте req.params, req.body или req.query.

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod req-param
// v4
app.post('/user', (req, res) => {
  const id = req.param('id')
  const body = req.param('body')
  const query = req.param('query')

  // ...
})

// v5
app.post('/user', (req, res) => {
  const id = req.params.id
  const body = req.body
  const query = req.query

  // ...
})

res.json(obj, status)

Express 5 больше не поддерживает сигнатуру res.json(obj, status). Вместо этого задайте статус, а затем вызовите метод res.json() в цепочке, например: res.status(status).json(obj).

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.post('/user', (req, res) => {
  res.json({ name: 'Ruben' }, 201)
})

// v5
app.post('/user', (req, res) => {
  res.status(201).json({ name: 'Ruben' })
})

res.jsonp(obj, status)

Express 5 больше не поддерживает сигнатуру res.jsonp(obj, status). Вместо этого задайте статус, а затем вызовите метод res.jsonp() в цепочке, например: res.status(status).jsonp(obj).

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.post('/user', (req, res) => {
  res.jsonp({ name: 'Ruben' }, 201)
})

// v5
app.post('/user', (req, res) => {
  res.status(201).jsonp({ name: 'Ruben' })
})

res.redirect(url, status)

Express 5 больше не поддерживает сигнатуру res.redirect(url, status). Вместо нее используйте следующую сигнатуру: res.redirect(status, url).

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.get('/user', (req, res) => {
  res.redirect('/users', 301)
})

// v5
app.get('/user', (req, res) => {
  res.redirect(301, '/users')
})

res.redirect('back') и res.location('back')

Express 5 больше не поддерживает специальную строку back в методах res.redirect() и res.location(). Вместо нее используйте значение req.get('Referrer') || '/', чтобы вернуться на предыдущую страницу. В Express 4 методы res.redirect('back') и res.location('back') были объявлены устаревшими.

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod magic-redirect
// v4
app.get('/user', (req, res) => {
  res.redirect('back')
})

// v5
app.get('/user', (req, res) => {
  res.redirect(req.get('Referrer') || '/')
})

res.send(body, status)

Express 5 больше не поддерживает сигнатуру res.send(obj, status). Вместо этого задайте статус, а затем вызовите метод res.send() в цепочке, например: res.status(status).send(obj).

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.get('/user', (req, res) => {
  res.send({ name: 'Ruben' }, 200)
})

// v5
app.get('/user', (req, res) => {
  res.status(200).send({ name: 'Ruben' })
})

res.send(status)

Express 5 больше не поддерживает сигнатуру res.send(status), в которой status — число. Вместо нее используйте функцию res.sendStatus(statusCode): она задает код состояния в заголовке HTTP-ответа и отправляет текстовое описание кода, например «Not Found», «Internal Server Error» и т. д. Если нужно отправить число с помощью функции res.send(), заключите его в кавычки, чтобы преобразовать в строку. Так Express не примет его за попытку использовать неподдерживаемую старую сигнатуру.

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.get('/user', (req, res) => {
  res.send(200)
})

// v5
app.get('/user', (req, res) => {
  res.sendStatus(200)
})

res.sendfile()

В Express 5 функция res.sendfile() заменена вариантом res.sendFile() с именем в стиле camelCase.

Примечание: В Express 5 для определения MIME-типа метод res.sendFile() использует пакет mime-types, который возвращает значения Content-Type, отличающиеся от Express 4 для ряда распространенных типов файлов:

  • Файлы JavaScript (.js): теперь «text/javascript» вместо «application/javascript»
  • Файлы JSON (.json): теперь «application/json» вместо «text/json»
  • Файлы CSS (.css): теперь «text/css» вместо «text/plain»
  • Файлы XML (.xml): теперь «application/xml» вместо «text/xml»
  • Файлы шрифтов (.woff): теперь «font/woff» вместо «application/font-woff»
  • Файлы SVG (.svg): теперь «image/svg+xml» вместо «application/svg+xml»

Примечание

Заменить устаревшие сигнатуры можно следующей командой:

npx @expressjs/codemod v4-deprecated-signatures
// v4
app.get('/user', (req, res) => {
  res.sendfile('/path/to/file')
})

// v5
app.get('/user', (req, res) => {
  res.sendFile('/path/to/file')
})

router.param(fn)

Сигнатура router.param(fn) использовалась для изменения поведения функции router.param(name, fn). Она объявлена устаревшей начиная с версии 4.11.0, а Express 5 больше не поддерживает ее.

express.static.mime

В Express 5 mime больше не является экспортируемым свойством поля static. Для работы со значениями MIME-типа используйте пакет mime-types.

Важно: Это изменение затрагивает не только прямое использование express.static.mime, но и другие методы Express, использующие определение MIME-типа, например res.sendFile(). В Express 5 по сравнению с Express 4 изменились следующие MIME-типы:

  • Файлы JavaScript (.js): теперь отдаются как «text/javascript» вместо «application/javascript»
  • Файлы JSON (.json): теперь отдаются как «application/json» вместо «text/json»
  • Файлы CSS (.css): теперь отдаются как «text/css» вместо «text/plain»
  • Файлы HTML (.html): теперь отдаются как «text/html; charset=utf-8» вместо просто «text/html»
  • Файлы XML (.xml): теперь отдаются как «application/xml» вместо «text/xml»
  • Файлы шрифтов (.woff): теперь отдаются как «font/woff» вместо «application/font-woff»
// v4
express.static.mime.lookup('json')

// v5
const mime = require('mime-types')
mime.lookup('json')

Журналы отладки express:router

В Express 5 логика обработки маршрутизатора реализована в виде зависимости. Поэтому журналы отладки маршрутизатора больше недоступны в пространстве имен express:. В версии 4 журналы были доступны в пространствах имен express:router, express:router:layer и express:router:route. Все они входили в пространство имен express:*. В версии 5.1 и выше журналы доступны в пространствах имен router, router:layer и router:route. Журналы из router:layer и router:route входят в пространство имен router:*. Чтобы получить такой же подробный журнал отладки, как при использовании express:* в версии 4, используйте сочетание express:*, router и router:*.

# v4
DEBUG=express:* node index.js

# v5
DEBUG=express:*,router,router:* node index.js

Изменения

Синтаксис сопоставления маршрутов по пути

Синтаксис сопоставления маршрутов по пути используется, когда строка передается в качестве первого параметра API app.all(), app.use(), app.METHOD(), router.all(), router.METHOD() и router.use(). В сопоставление строки пути с входящим запросом внесены следующие изменения:

  • У подстановочного знака * должно быть имя, как и у параметров :; используйте /*splat вместо /*
// v4
app.get('/*', async (req, res) => {
  res.send('ok')
})

// v5
app.get('/*splat', async (req, res) => {
  res.send('ok')
})

Примечание

*splat сопоставляется с любым путем, кроме корневого. Если нужно также сопоставить корневой путь /, можно использовать /{*splat}, заключив подстановочный знак в фигурные скобки.

// v5
app.get('/{*splat}', async (req, res) => {
  res.send('ok')
})
  • Необязательный символ ? больше не поддерживается; вместо него используйте фигурные скобки.
// v4
app.get('/:file.:ext?', async (req, res) => {
  res.send('ok')
})

// v5
app.get('/:file{.:ext}', async (req, res) => {
  res.send('ok')
})
  • Символы регулярных выражений не поддерживаются. Например:
    app.get('/[discussion|page]/:slug', async (req, res) => {
    res.status(200).send('ok')
    })
    

    следует заменить на:

    app.get(['/discussion/:slug', '/page/:slug'], async (req, res) => {
    res.status(200).send('ok')
    })
    
  • Некоторые символы зарезервированы во избежание неоднозначности при обновлении (()[]?+!); чтобы экранировать их, используйте \.
  • Имена параметров теперь могут быть допустимыми идентификаторами JavaScript или заключаться в кавычки, например :"this".

Обработка отклоненных промисов в промежуточном ПО и обработчиках

Отклоненные промисы, возвращаемые промежуточным ПО и обработчиками запросов, теперь обрабатываются путем передачи отклоненного значения в промежуточное ПО обработки ошибок в качестве Error. Это значит, что использовать функции async в качестве промежуточного ПО и обработчиков стало проще, чем когда-либо. Если в функции async возникает ошибка или внутри асинхронной функции отклоняется промис await, эти ошибки будут переданы обработчику ошибок так же, как при вызове next(err).

Подробнее об обработке ошибок в Express читайте в документации по обработке ошибок.

express.urlencoded

Метод express.urlencoded по умолчанию устанавливает для параметра extended значение false.

dotfiles в express.static

В Express 5 для параметра dotfiles промежуточного ПО express.static теперь по умолчанию установлено значение "ignore". В Express 4 файлы dotfiles отдавались по умолчанию. В результате файлы в каталогах, названия которых начинаются с точки (.), например .well-known, больше не будут доступны, а запросы к ним будут возвращать ошибку 404 Not Found. Это может нарушить работу функций, зависящих от доступа к каталогам, названия которых начинаются с точки, например Android App Links и Apple Universal Links.

Пример кода, который перестанет работать:

// v4
app.use(express.static('public'))

После перехода на Express 5 запрос к /.well-known/assetlinks.json приведет к ошибке 404 Not Found.

Чтобы исправить это, явно укажите конкретные каталоги, названия которых начинаются с точки, используя параметр dotfiles: "allow":

// v5
app.use('/.well-known', express.static('public/.well-known', { dotfiles: 'allow' }))
app.use(express.static('public'))

Такой подход позволяет безопасно отдавать только нужные каталоги, названия которых начинаются с точки, сохраняя безопасное поведение по умолчанию для остальных dotfiles, которые останутся недоступными.

app.listen

В Express 5 метод app.listen вызывает предоставленную пользователем функцию обратного вызова (если она задана), когда на сервере возникает событие ошибки. В Express 4 такие ошибки выбрасывались. В Express 5 ответственность за обработку ошибок переносится на функцию обратного вызова. Если возникает ошибка, она передается в функцию обратного вызова в качестве аргумента. Например:

const server = app.listen(8080, '0.0.0.0', (error) => {
  if (error) {
    throw error // e.g. EADDRINUSE
  }
  console.log(`Listening on ${JSON.stringify(server.address())}`)
})

app.router

Объект app.router, удаленный в Express 4, вернулся в Express 5. В новой версии этот объект представляет собой просто ссылку на базовый маршрутизатор Express. В Express 3 приложение должно было явно загружать его.

req.body

Свойство req.body возвращает undefined, если тело запроса не было обработано. В Express 4 по умолчанию оно возвращает {}.

req.host

В Express 4 функция req.host ошибочно удаляла номер порта, если он был указан. В Express 5 номер порта сохраняется.

req.query

Свойство req.query больше нельзя изменять; теперь это геттер. Парсер query-параметров по умолчанию изменен с «extended» на «simple».

res.clearCookie

Метод res.clearCookie игнорирует параметры maxAge и expires, заданные пользователем.

res.status

Метод res.status принимает только целые числа в диапазоне от 100 до 999, следуя поведению, определенному Node.js, и возвращает ошибку, если код состояния не является целым числом.

res.vary

Метод res.vary выбрасывает ошибку, если аргумент field не указан. В Express 4 при отсутствии аргумента в консоли выводилось предупреждение.

Улучшения

res.render()

Теперь этот метод обеспечивает асинхронное поведение для всех движков представлений, предотвращая ошибки, вызванные движками представлений с синхронной реализацией, нарушающей рекомендованный интерфейс.

Поддержка кодирования Brotli

Express 5 поддерживает кодирование Brotli для запросов от клиентов, которые его поддерживают.

Изменить эту страницу

© 2017 StrongLoop, IBM, and other expressjs.com contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v3.0.
https://expressjs.com/en/guide/migrating-5.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API