Один шаблон, три рендерера: как строился QRcado

QRcado оборачивает каждый динамический QR-код в фирменную мобильную страницу. Это значит, что один и тот же дизайн должен существовать сразу в трёх местах: живой предпросмотр в конструкторе, образец на маркетинговом сайте и страница, которую телефон действительно открывает после сканирования.
Сначала мы собрали их по отдельности, и они разошлись — как расходится всё, что собрано порознь. Предпросмотр говорил одну ширину, отсканированная страница рисовала другую. Шрифт грузился в приложении и подменялся системным на хостинговой странице. Ничто не ломалось настолько, чтобы уронить тест, и всё было неправильно ровно настолько, чтобы это заметить.
Три реализации одного дизайна — это не запас прочности. Это три места, где дизайн может оказаться неправильным.
Решением было сделать шаблон документом, а не компонентом: структура, токены и секции как данные, один рендерер, который их читает, и два других, потребляющих тот же пакет. Под всё это лёг общий CSS-reset, потому что расхождение так же часто было в контейнере, как и в содержимом.
Выигрыш здесь редакторский, а не архитектурный. Шаблон теперь правится в одном месте и меняется везде, где он появляется, — это единственная версия «единого бренда», которая переживает второго дизайнера.
QRcado — готовый продукт на закрытом тестировании. Он ещё не запущен, и эта заметка о том, как он был сделан, а не о том, кто им пользуется.