npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

velund

v1.0.8

Published

Ядро согласованного рендеринга

Readme

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