Хуки жизненного цикла плагинов

Fresh — это современный фреймворк для разработки веб-приложений, построенный на Deno и ориентированный на серверный рендеринг с минимальными накладными расходами. Основная концепция Fresh заключается в том, чтобы страницы были максимально быстрыми, используя Edge Rendering и избегая лишнего JavaScript на клиенте, когда это возможно.

Хуки жизненного цикла плагинов

Fresh предоставляет мощный механизм плагинов, которые позволяют расширять функциональность приложения. Хуки жизненного цикла плагинов позволяют вмешиваться в процесс обработки запроса, генерации страниц и управления состоянием на сервере и клиенте.

Типы хуков

  1. preload Этот хук вызывается перед рендерингом страницы. Он используется для подготовки данных, которые понадобятся компонентам или маршрутам. Пример использования:

    export function preload(context) {
        const data = fetchSomeData(context.params.id);
        return { props: { data } };
    }

    Здесь context содержит параметры запроса, параметры маршрута и другие метаданные. Возвращаемый объект автоматически передается в компонент как props.

  2. render Хук render позволяет вмешиваться в процесс рендеринга. Он может модифицировать результат, добавлять метатеги или выполнять серверные вычисления перед отправкой HTML клиенту.

    export function render({ html, props }) {
        const modifiedHtml = html.replace(
            '<title></title>',
            `<title>${props.title}</title>`
        );
        return modifiedHtml;
    }

    Важный момент: render выполняется на сервере и не влияет напрямую на клиентский JavaScript, что минимизирует нагрузку на браузер.

  3. afterRender Хук afterRender срабатывает после генерации HTML и перед отправкой его клиенту. Основное применение — логирование, аналитика или добавление внешних ресурсов.

    export function afterRender({ html, context }) {
        logRender(context.url, Date.now());
        return html;
    }

    Этот хук полезен для мониторинга производительности и интеграции с системами отслеживания.

  4. onRequest Один из самых мощных хуков, который срабатывает на этапе поступления запроса к серверу. Можно реализовать проверку авторизации, маршрутизацию или кэширование.

    export async function onRequest({ request, context }) {
        if (!isAuthorized(request)) {
            return Response.redirect('/login');
        }
        return await context.next();
    }

    Здесь context.next() передает управление следующему обработчику или маршруту. Это аналог middleware в других фреймворках.

Особенности работы хуков

  • Асинхронность: Хуки могут быть асинхронными, что позволяет выполнять запросы к базам данных или внешним API без блокировки рендеринга.
  • Порядок выполнения: onRequestpreloadrenderafterRender. Знание порядка критично для корректного построения цепочек обработки.
  • Контекст: Каждый хук получает context, который включает информацию о запросе, параметры маршрута, текущие props и возможности передачи данных между хуками.

Примеры комплексного использования

export async function onRequest({ request, context }) {
    context.user = await getUserFromToken(request.headers.get('Authorization'));
    return await context.next();
}

export function preload({ context }) {
    const articles = fetchArticlesForUser(context.user.id);
    return { props: { articles } };
}

export function render({ html, props }) {
    return html.replace('<div id="articles"></div>', renderArticles(props.articles));
}

export function afterRender({ context }) {
    console.log(`Page rendered for user ${context.user.id}`);
}

В этом примере полностью показан жизненный цикл обработки запроса: авторизация пользователя → загрузка данных → генерация HTML → логирование.

Принципы эффективного использования хуков

  • Минимизировать вычисления в render и afterRender, чтобы не блокировать сервер.
  • Использовать preload для получения данных, необходимых для рендеринга.
  • Применять onRequest для глобальных задач, таких как проверка авторизации, кэширование или маршрутизация.
  • Разделять хуки на отдельные модули, чтобы улучшить читаемость и поддержку кода.

Хуки жизненного цикла в Fresh обеспечивают гибкость и контроль над процессом рендеринга, позволяя создавать высокопроизводительные веб-приложения с минимальным клиентским JavaScript.