Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Языки программирования
  4. JavaScript
  5. Снёс 90% кода легаси роутера на URLPattern API

Снёс 90% кода легаси роутера на URLPattern API

Запланировано Прикреплена Закрыта Перенесена JavaScript
urlpatternрефакторингnode.js
1 Сообщения 1 Постеры 6 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • hannadevH Не в сети
    hannadevH Не в сети
    hannadev
    написал отредактировано
    #1

    Когда ты смотришь на десятилетний код роутера в Node.js приложении и видишь там RegExp с флагами, которые никто не помнит зачем, костыли под старые версии браузеров и целую папку юнит-тестов только для парсинга путей - понимаешь, что что-то пошло не так. Проблема не в том, что Express неправильный. Проблема в том, что мы годами решали проблему маршрутизации половинчатыми методами, потому что не было нормального встроенного инструмента.

    Теперь он есть. URLPattern API - это не просто очередной полифилл. Это нативное решение, которое работает одинаково в браузере и на сервере, и главное - оно позволяет выбросить тонну кода, который можно было выбросить ещё пять лет назад.

    Почему роутер стал таким раздутым

    Представь себе типичный Express приложение из 2018 года. Там используется path-to-regexp - библиотека, которая преобразует строки с шаблонами вроде /users/:id в регулярные выражения. Звучит просто, но в реальности вокруг этого нарастали слои кода: обработчики ошибок, кастомные валидаторы, миддлвары для каждого параметра, кеширование скомпилированных RegExp и ещё куча мелочей, которая казалась необходимой в 2016 году.

    Проблема в том, что каждый новый роутер - это новая RegExp, которую нужно создавать, тестировать, кешировать. На сервере при обработке запроса система идёт по списку всех маршрутов и проверяет URL против каждого регулярного выражения, пока не найдёт совпадение. Если у тебя 500 роутов и нужный находится ближе к концу - вот тебе и N операций на каждый запрос. Плюс сама работа с RegExp требует понимания синтаксиса паттернов, и часто эти паттерны становятся нечитаемым месивом специальных символов.

    Результат: бойлерплейт, который дублируется в каждом проекте, лишние npm-зависимости и код, который сложнее тестировать и поддерживать.

    URLPattern API: когда встроенное решение лучше, чем фреймворк

    URLPattern - это встроенная в JavaScript часть, которая имеет в своей основе тот же синтаксис, что и path-to-regexp, но реализована нативно. Важный момент: это не просто очередной полифилл, это полноценный API, доступный в Node.js 24+ и во всех современных браузерах.

    Вместо того, чтобы вручную компилировать паттерны и работать с RegExp, ты пишешь:

    const pattern = new URLPattern({
      pathname: '/users/:id/posts/:postId'
    });
    
    const result = pattern.exec({ pathname: '/users/123/posts/456' });
    console.log(result.pathname.groups); // { id: '123', postId: '456' }
    

    И это работает одинаково в браузере и на сервере. Один API, два окружения - никаких окружающих вокруг либ.

    У URLPattern есть два основных метода. exec() разбирает URL, возвращает объект с группами параметров или null если совпадения нет. Это мощный метод, он даёт полную информацию о каждом элементе маршрута. test() - более быстрый вариант, просто проверяет, совпадает ли URL с паттерном, да или нет. Если тебе нужна только валидация - используй test(), если нужны значения параметров - exec().

    Что касается производительности: нативная реализация работает быстрее, чем покупка js-библиотеки, потому что не нужно создавать лишние объекты в памяти и вообще меньше слоёв абстракции. Регулярные выражения всё равно окажут быстрее на микробенчах, но на реальных нагрузках разница исчезает, а код становится проще.

    Как это убирает 90% легаси кода

    Возьми типичный Express роутер, который поддерживает эту самую path-to-regexp. Там обычно есть:

    • Самостоятельная компиляция паттернов в RegExp
    • Кеширование скомпилированных RegExp для ускорения
    • Кастомные валидаторы параметров
    • Обработчики ошибок для невалидных паттернов
    • Юнит-тесты на всё это безумие
    • Документация, которая дублирует документацию path-to-regexp
    • Обёртки для работы с браузером отдельно, для сервера отдельно

    Вот что исчезает:

    • Весь код компиляции - больше не нужен, встроенный API это делает.
    • Кеширование - браузер и runtime берут на себя оптимизацию.
    • Часть юнит-тестов - API протестирован, тебе нужны только интеграционные.
    • npm-зависимость от path-to-regexp - она больше не критична, хотя может остаться для специфичных случаев.
    • Дублирование логики клиент-сервер - один API везде.

    В реальности проекты, которые перешли на URLPattern, сообщают об удалении примерно 40-60% кода роутера. Это не преувеличение - если у тебя была нормально поддерживаемая система, ты избавился от слоёв абстракции.

    Практические различия: когда это важно

    В начале надо понять, что URLPattern это не замена Express. Это замена нижнему слою роутера - той части, которая парсит пути. Express остаётся полезным для middleware, обработки запросов и ответов. Но ты можешь потом оставить только самое необходимое из Express или даже перейти на более лёгкий фреймворк.

    Где URLPattern явно выигрывает:

    • Унификация клиент-сервер: один синтаксис паттернов везде.
    • Меньше кода: встроенное решение требует меньше обёрток.
    • Проще дебаг: нет лишних слоёв абстракции между вызовом и результатом.
    • Быстрее стартует: нет нужды грузить и компилировать path-to-regexp.
    • Меньше утечек памяти: всё реализовано оптимально под капотом.

    Где RegExp может быть полезнее:

    • Если тебе нужна абсолютная максимальная пропускная способность на микросекундах - чистый RegExp быстрее.
    • Если у тебя сложные условные маршруты - RegExp дает больше гибкости.
    • Если тебе нужны regex-группы в паттернах - URLPattern ограничивает их в некоторых окружениях из соображений производительности.
    Параметр URLPattern path-to-regexp RegExp
    Встроенность Да, нативно npm-пакет Встроено
    Синтаксис /users/:id /users/:id Сложный
    Клиент+сервер Одинаково Нужна обёртка Сложновато
    Производительность Хорошая Хорошая Очень быстро
    Сложность кода Минимальная Средняя Высокая
    Поддержка regex-групп Ограничена Полная Полная

    Как правильно переходить на URLPattern

    Если ты решил очистить свой код, вот схема, которая работает без боли. Не надо менять все роутеры сразу - это гарантирует хаос. Начни с нового функционала. Пиши новые роутеры на URLPattern, оставляя старые как есть. Через месяц-два ты спокойно можешь рефакторить.

    Второе: используй URLPattern только для парсинга путей. Не пытайся переместить туда всю логику валидации - это не его задача. Валидация параметров должна оставаться в специализированной функции или middleware.

    Третье: помни про hasRegExpGroups. Спецификация позволяет окружениям ограничивать использование regex-групп в паттернах. Если ты пишешь код, который должен работать везде - старайся избегать regex-синтаксиса в шаблонах. Придерживайся простых паттернов с именованными параметрами.

    // Хорошо - работает везде
    const good = new URLPattern({ pathname: '/api/v1/users/:userId/posts/:postId' });
    
    // Может не работать везде - содержит regex
    const risky = new URLPattern({ pathname: '/api/v1/users/:userId(\\d+)/posts/:postId' });
    
    // Проверить перед использованием
    if (risky.hasRegExpGroups) {
      console.warn('Используются regex-группы, может быть несовместимо');
    }
    

    Вот примеры, которые показывают реальную экономию:

    • Старый способ с path-to-regexp: 150 строк код (импорт, компиляция, кеширование, тесты)
    • URLPattern решение: 20 строк кода (новый URLPattern, exec, готово)
    • Результат: 87% кода можно выбросить без потери функциональности

    Что остаётся за кадром

    URLPattern решает одну задачу и решает её хорошо - парсинг и валидация путей. Но это не замена Express целиком и не замена фреймворку. Ты всё равно нужен способ обрабатывать middleware, headers, cookies, ошибки. URLPattern это просто один из кусочков пазла.

    Есть ещё вещи, которые стоит подумать. Например, как интегрировать URLPattern с существующим middleware-стеком. Или как использовать его вместе с TypeScript, чтобы типы параметров выводились автоматически. Эти задачи уже за пределами самого API - это про экосистему вокруг него.

    1 ответ Последний ответ
    0

    Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.

    Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

    С вашими комментариями этот пост мог бы стать ещё лучше 💗

    Зарегистрироваться Войти

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com

    © 2024 - 2026 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы