Система плагинов

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


Основы системы плагинов

Плагин в Fresh — это JavaScript или TypeScript модуль, который экспортирует одну или несколько функций, называемых хуками (hooks). Эти хуки вызываются в процессе сборки или рендеринга приложения и могут модифицировать:

  • HTML-шаблоны;
  • маршруты приложения;
  • статические ресурсы (CSS, изображения, скрипты);
  • поведение серверного рендеринга.

Каждый плагин имеет доступ к объекту конфигурации приложения, что позволяет интегрировать сторонние библиотеки и инструменты.

export default function myPlugin({ addRoute, modifyHtml }) {
  addRoute("/custom", () => "<h1>Custom Page</h1>");
  modifyHtml((html) => html.replace("</body>", "<script src='/custom.js'></script></body>"));
}

В этом примере плагин добавляет новый маршрут и вставляет кастомный скрипт в HTML перед закрывающим тегом </body>.


Основные хуки плагинов

  1. addRoute(path, handler) Позволяет создавать новые маршруты приложения. Хэндлер может возвращать строку HTML или объект с данными для рендеринга.

  2. modifyHtml(transformer) Позволяет изменять HTML перед отправкой клиенту. transformer — это функция, принимающая исходный HTML и возвращающая модифицированный.

  3. onBuild(callback) Вызывается при сборке приложения. Используется для оптимизации ресурсов, генерации статических страниц или интеграции инструментов сборки.

  4. onRequest(callback) Срабатывает при каждом HTTP-запросе. Может использоваться для логирования, аутентификации или изменения ответа сервера.

  5. addMiddleware(middleware) Позволяет добавлять промежуточные функции, которые обрабатывают запрос до маршрута. Middleware может изменять request или response объект.


Структура плагина

Плагин обычно представляет собой одну функцию по умолчанию или объект с именованными хуками. Структура может быть следующей:

export default {
  onBuild({ buildDir }) {
    console.log("Сборка в директории:", buildDir);
  },
  onRequest({ request, response }) {
    if (!request.headers.get("X-Auth")) {
      response.status = 401;
      response.body = "Unauthorized";
    }
  },
};

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


Подключение плагинов

Плагины регистрируются в конфигурационном файле fresh.config.ts:

import myPlugin from "./plugins/myPlugin.ts";

export default {
  plugins: [myPlugin],
};

Fresh автоматически инициализирует все плагины при старте приложения и вызывает их хуки в соответствующие моменты жизненного цикла.


Взаимодействие между плагинами

Система плагинов Fresh построена с учетом возможности цепочек вызовов. Если несколько плагинов используют один и тот же хук, они вызываются по порядку из массива plugins. Для предотвращения конфликтов рекомендуется:

  • явно обрабатывать возвращаемые значения хуков;
  • использовать чистые функции для модификации данных;
  • документировать порядок подключения, если плагины зависят друг от друга.
modifyHtmlChain(html) {
  plugins.forEach((plugin) => {
    if (plugin.modifyHtml) {
      html = plugin.modifyHtml(html);
    }
  });
  return html;
}

Примеры практического применения

  1. Оптимизация изображений Плагин может автоматически сжимать изображения при сборке:
import { optimizeImage } from "image-utils";

export default function imageOptimizer({ onBuild }) {
  onBuild(({ buildDir }) => {
    // Проход по всем изображениям и сжатие
    optimizeImage(buildDir + "/static/images");
  });
}
  1. Интеграция с аналитикой Добавление стороннего скрипта аналитики через modifyHtml:
export default function analyticsPlugin({ modifyHtml }) {
  modifyHtml((html) => html.replace(
    "</head>",
    `<script src="https://analytics.example.com/script.js"></script></head>`
  ));
}
  1. Аутентификация и логирование Middleware для проверки токена и логирования запросов:
export default function authPlugin({ addMiddleware }) {
  addMiddleware(({ request, response }) => {
    console.log("Запрос к:", request.url);
    if (!request.headers.get("Authorization")) {
      response.status = 403;
      response.body = "Forbidden";
    }
  });
}

Рекомендации по разработке плагинов

  • Использовать TypeScript для строгой типизации хуков.
  • Избегать побочных эффектов, которые могут нарушить цепочку хуков.
  • Писать плагины модульными и легко подключаемыми.
  • Проверять совместимость с другими плагинами.
  • Минимизировать зависимости, чтобы не увеличивать размер сборки приложения.

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