В библиотеке Universal Router при определении маршрутов ключевую роль играет механизм выбора подходящего маршрута для конкретного URL. Приоритет совпадений определяет, какой маршрут будет вызван, если несколько маршрутов потенциально соответствуют текущему пути. Понимание этого механизма критично для построения сложных маршрутизируемых приложений на JavaScript.
Universal Router использует массив объектов маршрутов. Каждый объект может содержать следующие ключевые свойства:
path — строка с шаблоном пути
(/users/:id), поддерживающая параметры и регулярные
выражения.action — функция, выполняемая при совпадении
маршрута.children — вложенные маршруты для иерархической
структуры.name и meta — дополнительные свойства для
идентификации и хранения информации.Маршруты обрабатываются в порядке, в котором они заданы в массиве. Если несколько маршрутов совпадают с URL, первый подходящий маршрут получает приоритет. Это правило является базовым принципом работы маршрутизатора.
const routes = [
{ path: '/users/:id', action: () => 'User profile' },
{ path: '/users/settings', action: () => 'User settings' }
];
const router = new UniversalRouter(routes);
router.resolve('/users/settings'); // вернёт 'User profile', если порядок маршрутов не изменён
В приведённом примере маршрут /users/:id имеет более
общий шаблон, поэтому он срабатывает раньше, чем более конкретный
маршрут /users/settings. Это демонстрирует, что
порядок определения маршрутов напрямую влияет на приоритет
совпадений.
Universal Router определяет приоритет маршрутов не только по порядку, но и с учётом конкретности пути.
/users/settings)
имеют более высокий приоритет, чем динамические
параметры (/users/:id).*) всегда находится на самом
низком уровне приоритетов, так как он предназначен для ловли всех не
совпавших маршрутов.const routes = [
{ path: '/users/settings', action: () => 'User settings' },
{ path: '/users/:id', action: () => 'User profile' },
{ path: '*', action: () => 'Not found' }
];
const router = new UniversalRouter(routes);
router.resolve('/users/123'); // 'User profile'
router.resolve('/users/settings'); // 'User settings'
router.resolve('/unknown/path'); // 'Not found'
Такое распределение приоритетов позволяет безопасно комбинировать конкретные маршруты и универсальные обработчики ошибок.
Для сложных приложений маршруты часто строятся иерархически через
свойство children. При этом Universal Router использует
рекурсивный алгоритм поиска:
children.const routes = [
{
path: '/users',
children: [
{ path: 'settings', action: () => 'User settings' },
{ path: ':id', action: () => 'User profile' }
]
}
];
const router = new UniversalRouter(routes);
router.resolve('/users/42'); // 'User profile'
router.resolve('/users/settings'); // 'User settings'
Важно, что при использовании вложенных маршрутов путь для дочернего маршрута считается относительно родителя. Это обеспечивает корректную обработку приоритетов даже в глубоко вложенных структурах.
Universal Router поддерживает использование регулярных выражений в пути, что позволяет задать более точные или универсальные правила сопоставления.
const routes = [
{ path: '/files/:filename([a-z]+\\.txt)', action: ({ params }) => `Text file: ${params.filename}` },
{ path: '/files/:filename', action: ({ params }) => `Other file: ${params.filename}` }
];
const router = new UniversalRouter(routes);
router.resolve('/files/readme.txt'); // 'Text file: readme.txt'
router.resolve('/files/IMAGE.JPG'); // 'Other file: IMAGE.JPG'
Регулярные выражения повышают конкретность маршрута и, соответственно, его приоритет при совпадении. Универсальный маршрут с более свободным шаблоном срабатывает только тогда, когда более специфические варианты не подходят.
*) в конце списка: служит
ловушкой для необработанных URL.В крупных приложениях рекомендуется сначала группировать маршруты по функциональным блокам, затем внутри блоков располагать:
Такой подход обеспечивает предсказуемость и устраняет конфликты при совпадении URL.
*) должен использоваться как
запасной маршрут для непойманных URL.Такое понимание принципов приоритета совпадений обеспечивает надежную и предсказуемую маршрутизацию в приложениях на JavaScript с использованием Universal Router.