Обновить

React Islands: React-виджеты на чужой HTML-странице

Иногда React нужен не на всю страницу, а точечно: баннер, форма, счётчик. Host при этом — CMS, легаси или другой фреймворк. Поднимать SPA ради пары виджетов избыточно.

Архитектура islands: страница остаётся обычным HTML, а интерактив монтируется отдельными «островами». Библиотека react-islands фиксирует простой контракт: разметка → регистрация → invoke().

Контракт

Host Библиотека data-react-island="<name>" invoke() находит узел и монтирует renderer data-react-island-<attr> уходит в props, если указан в attributes — при mount ставится data-react-island-inited

<div
  data-react-island="banner"
  data-react-island-title="Акция"
  data-react-island-href="/promo"
>
  Fallback до JS
</div>

Использование

import { useEffect } from 'react';
import { Runner, setComponent, getWrapper } from 'react-islands';
import type { ComponentInvokeProps } from 'react-islands';

function Banner({ title, href, innerHTML, onMount }: ComponentInvokeProps & {
  title?: string;
  href?: string;
}) {
  useEffect(() => { onMount?.(); }, [onMount]);

  return (
    <a href={href}>
      <strong>{title}</strong>
      {innerHTML && <span dangerouslySetInnerHTML={{ __html: innerHTML }} />}
    </a>
  );
}

setComponent('banner', (element) => {
  getWrapper({ element, component: Banner, attributes: ['title', 'href'] });
});

Runner.getInstance().invoke();

Повторный invoke() безопасен: already inited узлы пропускаются.

Динамика

const el = document.createElement('div');
el.setAttribute('data-react-island', 'banner');
el.setAttribute('data-react-island-title', 'Ещё баннер');
container.append(el);

runner.render(el);   // смонтировать один
runner.unmount(el);  // снять root перед удалением из DOM
el.remove();

Когда брать

Да: виджеты на CMS/легаси, props из разметки, отдельный bundle островов.
Нет: уже есть React SPA или нужна общая store-шина между виджетами.

Код и демо: gitflic.ru/project/yamakca/react-islands.

Теги:
+3
Комментарии2

Записки из подполья незаконного архивирования фильмов

«Люди, видоизменяющие или уничтожающие художественные работы и наше культурное наследие ради прибылей или демонстрации власти — это варвары, и если законы США продолжат оправдывать такое поведение, то мы точно войдём в историю, как варварское общество.»

— Джордж Лукас, 1988 год

«Для меня её [оригинальной трилогии «Звёздных войн»] больше не существует. Я задумывал этот фильм именно так, и мне жаль, что вы увидели половину целого фильма и полюбили его.»

— Джордж Лукас, 2004 год

Ванкувер, 2011 год: мы с моей соседкой Виллой Росс сидим в одной из характерно стерильных монтажных студий Университета Саймона Фрейзера и уже не знаем, что делать: мы провели все выходные, ваяя из трёх разных копий вестерна Серджо Леоне 1966 года «Хороший, плохой, злой» одну версию — причём все три копии были незаконными рипами. В начале 2000-х этот фильм пал жертвой «реставрации», выполненной компанией MGM: вырезанные Серджо Леоне сцены были возвращены, увеличив время англоязычной версии с 161 до 179 минут; Клинт Иствуд и Илай Уоллак дублировали недостающие диалоги, а место умершего к тому времени Ли Ван Клифа занял похожий на него голосом дублёр. Монофоническая дорожка была переработана в многоканальный звук с неприятно современными звуками выстрелов. Почти десяток лет эта «дополненная» лента оставалась единственной продаваемой версией фильма; подобное очень часто происходит в эпоху ревизионистских студийных реставраций.

Наша цель была простой: спасти фильм от этой вивисекции. Мы планировали соединить звук уже не издававшегося DVD 1998 года (приблизительно похожий на звук международного релиза 1967 года) с видео из недавно привезённого Blu-ray итальянской версии. После того, как мы успешно преодолели многочисленные подводные камни, связанные с риппингом домашних видеозаписей конца 2000-х, наши надежды рухнули из-за катастрофического открытия: итальянская версия оказалась ещё сильнее отличающейся от международной, чем расширенная версия: печально известная сцена пытки была полностью перестроена, а у некоторых кадров отсутствовали начало и конец. Мы почти на десяток лет отказались от этой затеи.

Записки из подполья незаконного архивирования фильмов

Публикации