Визуализация и инкапсуляция Preact в iframe - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь создать iframe , содержащий Preact, который может быть реализован в разных средах. Iframe может взаимодействовать с родительским окном через события. Я думаю, что пакет должен быть импортирован на npm. ESM также является альтернативой, но я не понимаю, как это можно сделать во время разработки. Я попытался использовать пользовательский элемент , но он не инкапсулирует javascript и приводит к ошибкам перехвата при рендеринге Preact внутри React .

Следующие шаги, которые я считал возможными:
1. Создайте приложение my-fun-app. Экспортирует модуль es, используя микробандл.

import { h, render } from 'preact'
import App from './containers/app'
import { EventBus } from './utilities/bus'

let container
if (typeof window !== 'undefined') {
  container = document.querySelector('.container')
  window.parent.EventBus = new EventBus()
}
render(h(App), document.querySelector('.container'))

export const start = (rootElement, target) => {
  render(h(App), document.querySelector('.container'))
  // render(h(App), rootElement, target)
  if (typeof window !== 'undefined') {
    window.parent.EventBus = new EventBus()
  }
}

2. Далее js импортирует my-fun-app

import React, { useEffect, useRef } from 'react'
// import 'my-fun-app'

const getBlobURL = (code, type) => {
  const blob = new Blob([code], { type })
  return URL.createObjectURL(blob)
}

const MyFunApp = () => {
  const refContainer = useRef(null)

  useEffect(() => {
    let container = document.createElement('div')
    container.id = 'container'
    refContainer.current.contentDocument.body.appendChild(container)
    let moduleScript = document.createElement('script')
    moduleScript.type = 'module'
    const jsURL = getBlobURL(require('my-fun-app', 'text/javascript')
    moduleScript.src = jsURL
    refContainer.current.contentDocument.head.appendChild(moduleScript)
  }, [])

  return (
    <iframe
      ref={refContainer}
      id="my-iframe"
    ></iframe>
  )
}

Пробный рендеринг Preact с

render(<App />, getQuerySelector('#my-iframe').contentWindow.document.body)

, который переводит приложение в iframe, но не инкапсулирует его. В качестве примера, если в поле my-fun-app импортирована реакция-ловушка, возникает некоторая циклическая зависимость, приводящая к ошибке ловушек.

Я медленно дохожу до того, что это невозможно, но почти все возможно. Надеюсь, что вы можете помочь с некоторыми указаниями.

...