Files
Portal-Chart-Builder/docs/portal-front-integration.md
T

9.8 KiB
Raw Blame History

Связка с portal-front: запуск в dev, деплой в prod, тестовый стенд

Документ про встраивание конструктора в portal-front — React-приложение портала. Про встраивание в админку Bitrix (пользовательский тип свойства инфоблока) — отдельные документы: bitrix-integration.md и backend-quickstart.md.

1. Как это устроено

Портал открывает конструктор в <iframe> в режиме просмотра и передаёт ему схему через postMessage. Три вещи, которые надо знать, прежде чем что-то запускать.

Имя точки входа не константа. Сборка выдаёт index-<hash>.html (см. vite.config.ts, плагин hashIndexHtml), имя меняется при каждой значимой пересборке. Рядом кладётся манифест со стабильным именем:

{ "index": "index-300d7ef5.html" }

Портал читает его при открытии модалки — fetch('app-manifest.js', { cache: 'no-store' }) в src/helpers/chart-builder.ts — и уже к полученному имени дописывает параметры. Поэтому выкладка конструктора не требует пересборки портала.

Режим просмотра включается параметром. Портал сам дописывает ?mode=view: редактор стартует в просмотре, переключатель режимов скрыт, diagram:change портал игнорирует. В этом режиме приложение всегда берёт origin хоста из window.location.origin и игнорирует VITE_BITRIX_ORIGIN — переменная нужна только админке Bitrix, где встраивание идёт в режиме редактирования.

Пути внутри сборки относительные (base: './'), поэтому один и тот же dist/ работает из любого каталога размещения и переменной с путём больше нет.

Контракт обмена — bitrix-integration.md, раздел 4: приложение шлёт diagram:ready, хост в ответ diagram:init с JSON-строкой схемы. На стороне портала это src/hooks/useDiagramBridge.ts; если diagram:ready не пришёл за 10 секунд, в модалке появляется «Не удалось загрузить схему».

2. Dev

Портал на http://localhost:5173, конструктор на http://localhost:5800. Порты разные, но портал проксирует конструктор на свой origin — без этого режим просмотра не заработает (приложение отправит сообщения на 5800, то есть самому себе, а не порталу).

Прокси уже прописан в vite.config.ts портала:

'/local/modules/vniigaz.bpmn/assets': {
  target: 'http://localhost:5800',
  changeOrigin: false,
  rewrite: (path) => path.replace('/local/modules/vniigaz.bpmn/assets', '')
}

Порядок запуска:

cd D:\Development\Work\portal-chart-builder; npm run build
cd D:\Development\Work\portal-chart-builder; npm run preview

Порт 5800 зафиксирован в vite.config.ts (preview.port + strictPort), флаги передавать не нужно. Если порт занят, preview упадёт с ошибкой, а не уедет на соседний порт молча — иначе прокси портала указывал бы в пустоту.

cd D:\Development\Work\portal-front; npm run dev

Переменные окружения не нужны ни там, ни там.

npm run dev самого конструктора для связки не подходит: postMessage-мост включается только в production-сборке (isProd в src/App.tsx), в dev работает devAdapter поверх localStorage. После правок в конструкторе — заново npm run build; preview перезапускать не нужно, он читает файлы с диска.

Проверка, что связка поднята:

curl.exe -s http://localhost:5173/local/modules/vniigaz.bpmn/assets/app-manifest.js

Пустой ответ — не поднят preview или не собран конструктор.

3. Prod (портал, бэк и конструктор на одном домене)

cd D:\Development\Work\portal-chart-builder; npm run build

Дальше очистить каталог local/modules/vniigaz.bpmn/assets/ в дереве сайта и скопировать туда содержимое dist/. Именно очистить: имена файлов содержат хеш, старые сборки не перезаписываются, а накапливаются — и ломают запасной способ поиска точки входа «взять единственный index-*.html».

Портал пересобирается только когда меняется сам портал:

cd D:\Development\Work\portal-front; npm run build

Проверка после выкладки:

curl.exe -s https://ВАШ-ДОМЕН/local/modules/vniigaz.bpmn/assets/app-manifest.js

Имя в ответе должно совпадать с реально лежащим файлом. Открыть index-<hash>.html напрямую в браузере тоже полезно: вечное «Загрузка диаграммы…» там — норма, приложение ждёт diagram:init от родителя, которого при прямом открытии нет. Значит, статика раздаётся правильно.

4. Тестовый стенд и админка Bitrix

Отличие одно: там встраивание идёт в режиме редактирования, без ?mode=view, и только в этом случае учитывается VITE_BITRIX_ORIGIN.

Рекомендация — не задавать её вообще (удалить .env.production.local): origin возьмётся из window.location.origin и совпадёт с любым адресом, по которому открыли админку — localhost:8590, IP или домен. Приложение и админка на одном домене, так что это корректно всегда.

Если переменная всё-таки задаётся, её значение должно совпадать с адресной строкой браузера посимвольно, включая порт: http://192.168.100.146 и http://192.168.100.146:8590 — разные origin. При расхождении обмен молча не состоится, ошибок в консоли не будет.

Второе требование к встраивающей стороне — не писать имя index-<hash>.html строкой, а брать актуальное из app-manifest.js (или искать единственный index-*.html, но тогда очистка каталога при деплое обязательна). Подробности — в backend-quickstart.md, раздел 1.

5. Переменные окружения

Переменная Dev Prod (портал) Админка Bitrix
VITE_BASE_PATH не существует, base: './' то же то же
VITE_BITRIX_ORIGIN игнорируется в mode=view игнорируется в mode=view учитывается; лучше не задавать

6. Если схема не появилась

Что видно Причина Что делать
«Не удалось загрузить схему» в модалке манифест не отдался либо не пришёл diagram:ready за 10 секунд проверить app-manifest.js через curl, затем в Network — дошёл ли index-<hash>.js
Пустой iframe, в консоли 404 на index-<hash>.js файлы сборки не докопированы или скопированы не в тот каталог перекопировать dist/ целиком
Приложение висит на «Загрузка диаграммы…» diagram:ready ушёл не туда: origin хоста не совпал с ожидаемым для админки — сверить VITE_BITRIX_ORIGIN с адресной строкой; для dev — проверить, что конструктор открывается через прокси портала, а не напрямую с 5800
Портал открывает старую версию схемы в каталоге лежат файлы прошлых сборок, app-manifest.js указывает на новый, а старый html закеширован браузером очистить каталог при деплое; хеш в имени сам по себе кэш не победит, если старый файл остаётся на месте