Плагины и расширения

Universal Router — это гибкая и мощная библиотека для маршрутизации в JavaScript, которая поддерживает расширяемость через плагины и middleware. Эти механизмы позволяют внедрять дополнительные функции, модифицировать поведение маршрутизатора и интегрировать сторонние решения без изменения исходного кода маршрутизатора.


Middleware и плагинная архитектура

В основе расширяемости лежит концепция middleware, которые представляют собой функции, вызываемые перед обработкой маршрута. Middleware получает объект контекста context, объект маршрута route и функцию next(), вызывающую следующий middleware или конечный обработчик маршрута. Структура типичной middleware функции:

function exampleMiddleware(context, next) {
    console.log('Текущий путь:', context.path);
    return next();
}

Особенности middleware в Universal Router:

  • Асинхронность: middleware может возвращать промис.
  • Цепочка вызовов: каждый middleware должен вызывать 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

Расширения могут перехватывать ошибки и предоставлять 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);
    };
}

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


Итоги применения плагинов

  • Повторное использование логики: middleware и плагины позволяют инкапсулировать общие задачи.
  • Асинхронная обработка: поддержка промисов и async/await обеспечивает гибкость при работе с динамическими данными.
  • Централизованное управление: ошибки, авторизация и логирование могут обрабатываться в одном месте.
  • Совместимость с другими библиотеками: плагины позволяют легко интегрировать Universal Router с React, Vue, Node.js и другими платформами.

Плагины и middleware являются ключевым инструментом для создания масштабируемых и гибких приложений на основе Universal Router, обеспечивая контроль над маршрутизацией без изменения основной логики маршрутов.