Universal Router — это гибкая и мощная библиотека для маршрутизации в JavaScript, которая поддерживает расширяемость через плагины и middleware. Эти механизмы позволяют внедрять дополнительные функции, модифицировать поведение маршрутизатора и интегрировать сторонние решения без изменения исходного кода маршрутизатора.
В основе расширяемости лежит концепция middleware,
которые представляют собой функции, вызываемые перед обработкой
маршрута. Middleware получает объект контекста context,
объект маршрута route и функцию next(),
вызывающую следующий middleware или конечный обработчик маршрута.
Структура типичной middleware функции:
function exampleMiddleware(context, next) {
console.log('Текущий путь:', context.path);
return next();
}
Особенности middleware в Universal Router:
next(), чтобы передать управление следующему в
цепочке.context можно передавать данные между middleware и конечным
обработчиком.Плагины Universal Router обычно реализуются как обёртки над middleware. Они предоставляют повторно используемый функционал, например, логирование, авторизацию, перехват ошибок или динамическую подгрузку компонентов. Пример подключения плагина для логирования:
import UniversalRouter from 'universal-router';
function loggingPlugin() {
return async (context, next) => {
console.log(`Навигация к маршруту: ${context.path}`);
const result = await next();
console.log(`Маршрут обработан: ${context.path}`);
return result;
};
}
const routes = [
{ path: '/', action: () => 'Главная' },
{ path: '/about', action: () => 'О проекте' }
];
const router = new UniversalRouter(routes, {
context: {},
resolveRoute(context, route) {
const middleware = loggingPlugin();
return middleware(context, () => route.action(context));
}
});
В этом примере loggingPlugin внедряет функционал
логирования до и после обработки маршрута, не изменяя логику самого
маршрута.
Плагины позволяют добавлять динамические свойства к маршрутам. Например, можно реализовать плагин для проверки прав доступа:
function authPlugin(userRoles) {
return async (context, next) => {
if (context.route.roles && !context.route.roles.some(role => userRoles.includes(role))) {
throw new Error('Доступ запрещён');
}
return next();
};
}
const routes = [
{ path: '/admin', action: () => 'Панель администратора', roles: ['admin'] },
{ path: '/profile', action: () => 'Профиль пользователя' }
];
const router = new UniversalRouter(routes, {
context: {},
resolveRoute(context, route) {
const middleware = authPlugin(['user']);
return middleware(context, () => route.action(context));
}
});
Такой подход делает маршрутизатор более безопасным и гибким, позволяя внедрять бизнес-логику на уровне маршрутов.
Расширения могут перехватывать ошибки и предоставлять fallback-контент. Middleware для глобальной обработки ошибок:
function errorHandlerPlugin() {
return async (context, next) => {
try {
return await next();
} catch (err) {
console.error('Ошибка маршрутизации:', err.message);
return 'Страница не найдена';
}
};
}
const router = new UniversalRouter(routes, {
context: {},
resolveRoute(context, route) {
const middleware = errorHandlerPlugin();
return middleware(context, () => route.action(context));
}
});
Такой подход гарантирует стабильность приложения и централизованное управление ошибками.
Плагины Universal Router позволяют интегрировать маршрутизатор с различными фреймворками, например, для рендеринга компонентов в React или Vue. Основная идея — использовать middleware для динамической подгрузки компонентов или передачи данных в рендер-функции:
function reactRenderPlugin(render) {
return async (context, next) => {
const component = await next();
render(component);
};
}
В этом случае маршруты остаются чистыми, а рендеринг компонентов делегируется отдельной функции, что упрощает тестирование и повторное использование кода.
async/await обеспечивает гибкость при работе с
динамическими данными.Плагины и middleware являются ключевым инструментом для создания масштабируемых и гибких приложений на основе Universal Router, обеспечивая контроль над маршрутизацией без изменения основной логики маршрутов.