islandkit
v0.6.0
Published
Framework-agnostic Vue 3 island mounting toolkit for server-rendered sites.
Readme
islandKit
Библиотека, которая монтирует компоненты Vue 3 как независимые «острова» внутрь страниц, отрисованных чем-то другим — темой на PHP, генератором статических сайтов, любым серверным шаблонизатором.
Страница остаётся за хостом: он владеет маршрутизацией, вёрсткой и контентом. Он объявляет, где стоит компонент и какие данные тот получает, — остальное делает библиотека. Vue не забирает страницу себе, он занимает на ней точки.
Как это выглядит со стороны сайта
Объявить точку монтирования и данные для неё:
<div data-ik-island="product-filter" data-ik-props="filter-props">
<!-- Необязательно: разметка, которая видна, пока остров не смонтировался, и
видна навсегда, если JavaScript не сработал. Здесь место контенту,
который должен попасть в поисковую выдачу. -->
</div>
<script type="application/json" id="filter-props">{ "items": [] }</script>Один раз на страницу объявить контекст и подключить бандл:
<script type="application/json" id="ik-context">
{ "host": "my-site", "locale": "ru", "routing": { "base": "/", "ownsUrl": true } }
</script>
<script type="application/json" id="ik-messages">{ "filter.title": "Фильтр" }</script>
<script type="module" src="/assets/islandkit/0.1.0/islands.js"></script>Это вся поверхность интеграции. Островов на странице может быть сколько угодно; каждый получает свой экземпляр приложения, свои пропсы и своё состояние.
Что уже есть
| Остров | Что это |
| --- | --- |
| compatibility-matrix | Таблица совместимости: поиск, фильтры по категории, типу продукта и нашим продуктам, состояние в ссылке. Контракт данных |
Набор интерфейса, из которого острова собираются: IkButton, IkFilterSelect,
IkSearchField, IkTag, IkTooltip. Он доступен и отдельно — точкой входа
islandkit/kit, для сайта, который собирает компонент сам.
Оформление сайт задаёт переменными: полный список того, что можно менять, с
текущими значениями по умолчанию библиотека генерирует сама —
dist/theme.template.css. Ни селекторов, ни !important, ни знания нашей
разметки; подробности — в Внешний вид.
Необязательные атрибуты
| Атрибут | Что делает |
| --- | --- |
| data-ik-lazy | Монтировать при приближении к области видимости, а не при загрузке. Значение false отменяет отложенность для острова, у которого она включена по умолчанию. Браузеры без IntersectionObserver монтируют сразу. |
| data-ik-url-prefix | Пространство имён для параметров адресной строки этого острова, применяется буквально: left_ превращает page в ?left_page=. Нужно, когда два острова на одной странице держат состояние в адресной строке, иначе они пишут одни и те же имена. |
| data-ik-<имя> | Перекрывает одно скалярное значение пропса, чтобы шаблон мог поправить одно поле, не пересобирая JSON. |
Остров попадает в адресную строку только если его определение объявляет
urlSync и страница разрешает это через routing.ownsUrl. При отказе тот же
код компонента работает против хранилища в памяти: ссылка, с которой страницу
открыли, по-прежнему учитывается, а последующие изменения просто перестают быть
шарящимися. Ни одна строка компонента при этом не обращается к адресной строке.
Строки, которые остров ждёт от хоста, перечислены в
dist/messages.template.json — файл генерируется при сборке и служит отправной
точкой для блока #ik-messages.
Остров сообщает наружу обычными событиями DOM на своём элементе (ik:*), а не
колбэками: слушатель ставится прямо в шаблоне, без JS-API и без сборщика.
Обработчик ошибок и аналитику хост передаёт через window.islandKitHost,
объявленный до тега бандла — это единственный канал для функций, всё остальное
идёт данными.
Правила устройства
- Пропсы внутрь, события наружу. Компоненты не читают глобальные переменные, адресную строку и браузерные хранилища. Всё внешнее приходит через контекст хоста, а браузерные возможности — через порты. Это проверяет линтер, и именно это делает компоненты переносимыми и пригодными к серверному рендерингу.
- Отказ наружу, а не внутрь. Отсутствующие данные, битый JSON или незнакомый идентификатор острова никогда не выбрасывают разметку хоста. Один сломанный остров не может уронить страницу.
- Стили подключаются по желанию. Все классы префиксованы и изолированы,
внешний вид задаётся переменными
--ik-*со значениями по умолчанию: набор выглядит правильно без всякой настройки и перекрашивается одним блоком переопределений. - Тексты принадлежат сайту. Библиотека возит только служебные подписи («Очистить», «Загрузка»); продуктовые формулировки приходят извне, а сборочная проверка отвергает обращение к строке, которую никто не объявил.
- Контракт разметки — публичное API. Имена островов и атрибутов подчиняются semver: страницы, которые уже опубликованы, никто не будет пересобирать под переименование.
- Индексируемый контент пока не остров.
kind: 'content'отвергается при регистрации, пока нет серверного рендеринга; такие блоки остаются в шаблонах сайта и берут отсюда токены и компоненты набора.
Подключение через сборщик
import { autoMount, defineIsland, registerIslands } from 'islandkit'
import 'islandkit/style.css'В этом режиме vue — peer-зависимость. Самодостаточная сборка
(islandkit/standalone) везёт Vue внутри и предназначена для хостов без шага
сборки.
Разработка
npm install
npm run dev
npm run verifydev поднимает площадку — реальный путь монтирования, переопределение токенов,
несколько островов на одной странице. verify прогоняет весь набор проверок:
обезличивание, строки, линтеры, типы, тесты, обе сборки, форму пакета и бюджеты
размера.
Дальше
- Подключение к сайту — для тех, кто ведёт хост-сайт: установка, обновление, откат, диагностика.
- Разработка библиотеки — для тех, кто пишет компоненты: слои, цикл добавления острова, тесты, релизы.
- Правила — свод того, что нарушать нельзя, и почему.
