tagshift

<template> на входе, класс компонента на выходе — и элемент, который обновляется на месте.

Заставка tagshift: логотип <tagshift>, заголовок «Templates in. Elements out.», ниже шаблон карточки с плейсхолдером ${name} и слотами, а стрелка ведёт от него к отрендеренной карточке «Hello, Sam!» с кнопкой Follow на тёмно-синем фоне.

Маленькая библиотека на JavaScript, которая превращает обычный HTML-шаблон <template> в класс компонента. У экземпляра есть props и slots; render() строит элемент при первом вызове и обновляет тот же самый элемент при каждом следующем. Ни зависимостей, ни сборки, ни виртуального DOM — шаблон остаётся обычной разметкой, которая лежит прямо на странице.

Шаблон знает две вещи. Плейсхолдеры ${name} работают в тексте и в значениях атрибутов, а значения вставляются как текст и HTML-ом не становятся никогда. <slot> подчиняется правилам Shadow DOM: слот по умолчанию и именованные, с запасным содержимым, которое видно, пока слоту ничего не передали. В слот можно отдать узлы, строки или любой итерируемый набор из них, и узлы при этом переносятся, а не копируются.

Обновления точечные, а не через сравнение деревьев. Каждый плейсхолдер помнит, где он живёт, поэтому render() пишет только те текстовые узлы и атрибуты, чей результат изменился, а слот перезаполняется, только когда его значение перестало быть тем же самым по Object.is. Обновление, которое бросило ошибку — например, содержимое для слота, которого в шаблоне нет, — оставляет элемент как был. Для разметки в слоте есть тег html: он разбирает её во фрагмент и экранирует каждое подставленное значение.

Циклов, условий и привязки событий в шаблоне нет, и за вашими объектами никто не следит: изменили props — вызвали render(). Список — это массив отрендеренных компонентов, отданный в слот.

JavaScript, MIT, типы для TypeScript написаны руками: npm install tagshift.