Переход к Express 5
Обзор
Express 5 не сильно отличается от Express 4; хотя он сохраняет тот же базовый API, все же есть изменения, нарушающие совместимость с предыдущей версией. Поэтому приложение, созданное с Express 4, может не работать, если вы обновите его для использования Express 5.
Для установки этой версии вам нужна версия Node.js 18 или выше. Затем выполните следующую команду в каталоге вашего приложения:
npm install "express@^5.0.1"
Затем вы можете запустить свои автоматические тесты, чтобы увидеть, что не работает, и исправить проблемы в соответствии с перечисленными ниже обновлениями. После устранения сбоев тестов запустите приложение, чтобы увидеть, какие ошибки возникают. Вы сразу узнаете, если приложение использует методы или свойства, которые не поддерживаются.
Изменения в Express 5
Удаленные методы и свойства
- app.del()
- app.param(fn)
- Методы с множественным числом в названии
- Двоеточие в начале имени аргумента в 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()
- express.static.mime
Измененные
- Синтаксис сопоставления путей маршрутов
- Обработка отклоненных промисов из middleware и обработчиков
- express.urlencoded
- app.listen
- app.router
- req.body
- req.host
- req.query
- res.clearCookie
- res.status
- res.vary
Улучшения
Удаленные методы и свойства
Если вы используете любой из этих методов или свойств в своем приложении, оно упадет. Поэтому вам нужно будет изменить приложение после обновления до версии 5.
app.del()
Express 5 больше не поддерживает функцию app.del(). Если вы используете эту функцию, будет выброшено исключение. Для регистрации маршрутов HTTP DELETE используйте функцию app.delete() вместо нее.
Изначально del использовалось вместо delete, потому что delete — зарезервированное ключевое слово в JavaScript. Однако начиная с ECMAScript 6, delete и другие зарезервированные ключевые слова могут законно использоваться в качестве имен свойств.
// 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). Она устарела с версии v4.11.0 и Express 5 больше не поддерживает ее.
Методы с множественным числом в названии
Следующие имена методов были приведены в множественное число. В Express 4 использование старых методов приводило к предупреждению об устаревании. Express 5 больше не поддерживает их.
req.acceptsCharset() заменено на req.acceptsCharsets().
req.acceptsEncoding() заменено на req.acceptsEncodings().
req.acceptsLanguage() заменено на req.acceptsLanguages().
// 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.
// 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).
// 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).
// 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).
// 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') были устаревшими.
// 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).
// 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-ответа и отправляет текстовое представление кода: «Не найдено», «Внутренняя ошибка сервера» и т. д. Если вам нужно отправить число, используя функцию res.send(), заключите число в кавычки, чтобы преобразовать его в строку, чтобы Express не интерпретировал его как попытку использовать устаревшую подпись.
// v4
app.get('/user', (req, res) => {
res.send(200)
})
// v5
app.get('/user', (req, res) => {
res.sendStatus(200)
})
res.sendfile()
Функция res.sendfile() была заменена на версию с верблюжьей нотацией res.sendFile() в Express 5.
// v4
app.get('/user', (req, res) => {
res.sendfile('/path/to/file')
})
// v5
app.get('/user', (req, res) => {
res.sendFile('/path/to/file')
})
express.static.mime
В Express 5 mime больше не является экспортируемым свойством поля static. Используйте пакет mime-types для работы с значениями MIME-типов.
// v4
express.static.mime.lookup('json')
// v5
const mime = require('mime-types')
mime.lookup('json')
Измененные
Синтаксис сопоставления путей маршрутов
Синтаксис сопоставления путей маршрутов — это когда строка передаётся в качестве первого параметра 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".
Обработка отклоненных промисов из middleware и обработчиков
Обработка middleware и обработчики запросов, возвращающие отклоненные промисы, теперь обрабатываются путем передачи отклоненного значения в качестве Error обработчику ошибок. Это означает, что использование функций async в качестве middleware и обработчиков стало проще. Когда в функции async выбрасывается исключение или отклоняется промис, await внутри асинхронной функции, эти ошибки передаются обработчику ошибок так, как будто вызывается next(err).
Подробная информация о том, как Express обрабатывает ошибки, содержится в документации по обработке ошибок.
express.urlencoded
Метод express.urlencoded делает опцию extended false по умолчанию.
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 больше не является свойством для записи, а является методом-геттером. Парсер запросов по умолчанию был изменён с «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