Skip to content

Repository files navigation

Velund – Модульная UI-система на Vite для полиглотных бэкендов

🚀 Обзор

Velund — это не просто плагин для Vite, а интегрированная экосистема для создания кросс-платформенных UI-компонентов. Он позволяет фронтенд-разработчикам создавать компоненты с использованием привычных шаблонизаторов, а Velund компилирует их в готовые к использованию библиотеки, которые могут быть интегрированы и рендерены на любом бэкенде (Node.js, Python, PHP) через четко определенные API.

Velund фокусируется на:

  • Контрактной разработке: Четкие схемы данных между фронтендом и бэкендом.
  • Модульности: Возможность использовать готовые или создавать собственные рендереры и генераторы.
  • Изоляции: UI-компоненты независимы от конкретной логики бэкенда.
  • Автоматизации: Генерация библиотек и DTO для бэкенда.

✨ Основные возможности

  • Агностик к шаблонизатору: Поддержка Twig (@zebrains/velund-twig), Jinja/Nunjucks (@zebrains/velund-jinja), HTML (@velund/html). Система позволяет легко добавлять новые шаблонизаторы.
  • Типизированные компоненты: Строгое определение props и context компонентов с помощью схем TypeBox (транслируются в JSON Schema).
  • Backend-интеграция: Автоматическая генерация специализированных библиотек для бэкенд-языков (Node.js, Python, PHP), которые предоставляют готовый Renderer класс для рендеринга компонентов.
  • Горячая перезагрузка (HMR): Мгновенные обновления UI-компонентов в процессе разработки.
  • Управление ассетами: Автоматическое управление путями к статическим ассетам, готовое к употреблению бэкендом.
  • Асинхронные данные: Поддержка асинхронной подготовки данных (prepare метод) для компонентов.
  • Расширяемая архитектура: Возможность использования готовых или создания собственных рендереров и генераторов благодаря API, предоставляемому @velund/core.

📦 Установка

1. Создание нового проекта с create-velund (рекомендуется)

Используйте CLI-инструмент create-velund для быстрой инициализации проекта:

pnpm create velund
# или
npm create velund@latest
# или
yarn create velund

create-velund интерактивно спросит вас о названии проекта, предпочитаемом шаблонизаторе и генераторе для бэкенда, и автоматически настроит vite.config.ts и установит необходимые зависимости.

2. Добавление Velund в существующий проект Vite

Установите velund и необходимые рендереры/генераторы:

pnpm add velund @zebrains/velund-twig # Для поддержки Twig-шаблонов
# и/или
pnpm add @velund/node # Для генерации Node.js-библиотеки
# и/или другие рендереры/генераторы

🛠️ Базовая настройка vite.config.ts

// vite.config.ts
import { defineConfig } from 'vite';
import velund from 'velund'; // Основной плагин Velund
import twigRenderer from '@zebrains/velund-twig'; // Пример: рендерер для Twig
import phpGenerator from '@zebrains/velund-php'; // Пример: генератор для PHP

export default defineConfig({
  plugins: [
    velund({
      // -- Основной шаблонизатор и генератор для проекта --
      renderer: 'twig', // Указывает основной шаблонизатор (Twig, Jinja, HTML)
      generator: 'php', // Указывает основной генератор для бэкенда (Node.js, Python, PHP)

      // -- Регистрация рендереров --
      // Все используемые рендереры должны быть зарегистрированы здесь.
      // @velund/html уже встроен.
      renderers: [
        twigRenderer(), // Экземпляр Twig-рендерера
      ],

      // -- Регистрация генераторов --
      // Все используемые генераторы должны быть зарегистрированы здесь.
      // @velund/node уже встроен.
      generators: [
        phpGenerator(), // Экземпляр Python-генератора
      ],

      // -- Опции для интеграции с бэкендом --
      assetsUrl: '/assets', // URL-путь по которому бэкенд должен отдавать статические ассеты Velund.
      // Velund ожидает, что бэкенд будет обслуживать dist/assets по этому пути.
      renderUrl: '/__render', // URL-путь для API-эндпоинта, который бэкенд должен предоставить.
      // Используется в dev-режиме для рендеринга компонентов в рантайме.

      // -- Прочие опции --
      strictTemplateExtensions: false, // `true` если нужно строго проверять расширения файлов шаблонов (например, только .twig)
      // nodeConfig?: VelundNodeGeneratorOptions; // Конфигурация для `@velund/node` генератора.
    }),
  ],
});

🧩 Определение UI-компонентов (.vel.ts)

Velund-компоненты определяются в виде TypeScript-файлов (обычно .vel.ts) и являются вашим основным способом создания UI. Вы можете автоматически собирать их через виртуальный модуль virtual:velund/components

// src/components/ProductCard.vel.ts
import { defineComponent } from 'velund/common'; // Хелпер для определения компонента
import { Type } from '@sinclair/typebox'; // Используется для описания схем данных
import template from './ProductCard.twig'; // Путь к файлу шаблона

export default defineComponent({
  name: 'ProductCard', // Уникальное имя компонента
  template, // Путь к связанному файлу шаблона (например, `.twig`, `.j2`, `.html`)

  // -- Схема входных свойств (PropTypes) --
  // `propsSchema` определяет данные, которые компонент принимает извне.
  // Бэкенд-библиотека будет использовать эту схему для валидации входных данных.
  propsSchema: Type.Object({
    id: Type.Number(), // ID продукта
  }),

  // -- Схема контекста шаблона (ContextType) --
  // `contextSchema` определяет структуру данных, которые будут доступны внутри шаблона.
  // Это может быть объединение входных props и данных, полученных в `prepare` методе.
  contextSchema: Type.Object({
    title: Type.String(), // Название продукта
    price: Type.Number(), // Цена продукта
    description: Type.Optional(Type.String()), // Описание (необязательно)
  }),

  // -- Метод подготовки данных (Runtime Data Fetching) --
  // `prepare` - асинхронная функция, которая вызывается для получения или подготовки данных для компонента.
  // Она принимает `props` в соответствии с `propsSchema` и должна возвращать объект,
  // который будет объединен с `props` и передан в шаблон в качестве `context`.
  async prepare(props) {
    // Пример: получить данные о продукте из API
    const res = await fetch(`/api/products/${props.id}`); // Используется `fetch` (доступен в Node.js и браузере)
    const productData = await res.json();
    return productData; // Эти данные будут доступны в шаблоне как часть `context`
  },
});

🔌 Интеграция с бэкендом

Velund не просто генерирует JSON-схемы, он создает полноценные библиотеки для вашего бэкенд-языка.

Как это работает:

  1. Генерация библиотеки: При сборке вашего фронтенд-проекта (npm run build), выбранный generator (например, @velund/node) генерирует библиотеку в вашей build.outDir (например, dist/) директории.
  2. Renderer класс: Эта сгенерированная библиотека предоставляет основной класс Renderer (или аналогичный) и специализированные классы/функции для каждого вашего компонента (например, ProductCard).
  3. API для бэкенда: Бэкенд-разработчик использует этот Renderer класс для:
    • Инициализации (обычно требуется указать путь к скомпилированным шаблонам).
    • Регистрации prepare методов: Если компонент использует асинхронный prepare метод (как в примере выше), бэкенд должен будет предоставить синхронную или асинхронную реализацию этого метода в своей среде. Сгенерированная типизация или описание для IDE поможет бэкенду понять, какие аргументы (props) должен принимать этот метод и какой контекст возвращать.
    • Рендеринга компонента: Вызов метода render(componentName, context, meta?: boolean) предоставит готовый HTML.

Пример использования в Node.js (генерируемый @velund/node):

После сборки фронтенда, вы можете использовать сгенерированную библиотеку в вашем Node.js-проекте:

import express from 'express';
import path from 'path';
import {
  HomePageComponent,
  ProductPageComponent,
  Renderer,
} from '../velund/lib';
const app = express();
const port = 3333;

// Предоставление директории с ассетами
const publicDir = path.join(process.cwd(), 'velund/assets');
app.use('/assets', express.static(publicDir));

// Регистрация prepare-метода дла компонента HomePage
HomePageComponent.registerPrepare(async () => {
  const products = await (
    await fetch('https://fakestoreapi.com/products')
  ).json();
  products[0].title = Date.now() + products[0].title;
  return {
    products,
  };
});

// Регистрация prepare-метода для компонента ProductPage
ProductPageComponent.registerPrepare(async ({ id }) => {
  const product = await (
    await fetch('https://fakestoreapi.com/products/' + id)
  ).json();
  return product;
});

// Инициализация рендер-класса
const renderer = new Renderer();

// Регистрация роутов
app.get('/', async (req, res) => {
  const html = await renderer.render('HomePage', {});
  res.status(200).send(html).end();
});
app.get('/ProductPage', async (req, res) => {
  const r = await renderer.render('ProductPage', req.query);
  res.status(200).send(r).end();
});

app.listen(port, () => {
  console.log(`🚀 Server running at http://localhost:${port}`);
});

Важные нюансы для бэкенда:

  • Сервировка ассетов: Бэкенд должен быть настроен на обслуживание статических файлов из директории Velund dist/assets по пути, указанному в assetsUrl (/assets по умолчанию).
  • Runtime-рендеринг: Бэкенд может реализовать эндпоинт по пути renderUrl (/__render по умолчанию) для динамического рендеринга компонентов в рантайме, используя логику, подобную той, что предоставляют генераторы. Это полезно для SSR или API-запросов.

⚙️ Детальная конфигурация плагина velund

Интерфейс iTwigPluginConfig (определен в src/types.ts) для функции velund():

Опция Тип По умолчанию Описание
renderer string 'html' Обязательный. ID основного рендерера для проекта (например, 'twig', 'jinja', 'html'). Используется для выбора дефолтного рендерера.
generator string 'node' Обязательный. ID основного генератора для проекта (например, 'node', 'python', 'php'). Указывает, какую бэкенд-библиотеку Velund должен генерировать.
assetsUrl string '/assets' Путь URL, по которому бэкенд должен будет обслуживать статические ассеты (JS,CSS, изображения), сгенерированные Vite. Это критически важный контракт для бэкенда.
renderUrl string '/__render' Путь URL для API-эндпоинта, который бэкенд должен будет предоставить для динамического рендеринга компонентов в рантайме. Velund использует этот же URL в режиме разработки для собственного отладочного сервера.
strictTemplateExtensions boolean false Если true, Velund будет строго проверять, что расширения файлов шаблонов соответствуют зарегистрированным для рендереров (например, только .twig для Twig-рендерера).
generators VelundGeneratorDescriptor[] [] Массив экземпляров генераторов, которые Velund должен использовать (например, [pythonGenerator(), phpGenerator()]). @velund/node встроен по умолчанию.
renderers VelundRendererDescriptor[] [] Массив экземпляров рендереров, которые Velund должен использовать (например, [twigRenderer(), jinjaRenderer()]). @velund/html встроен по умолчанию.
nodeConfig VelundNodeGeneratorOptions {} Конфигурация, специфичная для @velund/node генератора (если используется).

📜 Лицензия

MIT © DNTZ

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages