从静态网站初始化多个 react-live 组件的优雅方法是什么?

What is an elegant way to initialize multiple react-live components from a static website?

我目前正在创建一个反应组件库,我想将其作为 npm 包提供。我还想提供一个文档,其中包含可用组件的精美实时渲染,例如github 页。

我打算使用 react-live which provides multiple react components to display a live editor and a preview. See an example from the styled-components docs 的实时编辑功能。

react-live 组件接受一个字符串 code,其中包含应在编辑器中显示的初始代码和可在实时编辑器中使用的组件列表 scope

现在我想使用 gohugo 或类似的静态站点生成器来部署我的文档。我想我可以在我的静态站点中提供一个 <div>,它有一个特殊的 class react-live-demo,我将使用 document.getElementsByClassName('react-live-demo') 获取这些容器,循环它们并渲染反应- 实时组件。

我创建了一个显示小示例的代码片段:

const {LiveProvider, LiveEditor, LiveError, LivePreview} = window['react-live'];

// a random component that i want to render in the live editor
const MyComponent = () => (
  <div>
    <h1>react live demo</h1>
    <p>This is a component from the script tag.</p>
  </div>
);

// a wrapper for the react-live editor
const Editor = ({code, scope}) => (
  <LiveProvider code={code} scope={scope}>
    <div className="live-example row">
      <div className="col-xs">
        <LiveEditor />
        <LiveError />
      </div>
      <div className="col-xs">
        <LivePreview />
      </div>
    </div>
  </LiveProvider>
);

// get all containers that have the initial code as innerHTML
const examples = document.querySelectorAll('script[data-name="react-live"]');

examples.forEach(example => {
  // insert a new div before the script tag
  const container = document.createElement('div');
  example.parentNode.insertBefore(container, example.nextSibling);
  
  // render the editor with the code from the script tag
  const code = example.innerHTML.trim();
  ReactDOM.render(<Editor code={code} scope={{MyComponent}} />, container);
});
.static-content {
  background-color: papayawhip;
}

.live-example {
  border: 1px solid orange;
}

.react-live-demo.code {
  display: none;
}

.invalid {
  color: red;
}
<p class="static-content">HERE IS SOME STATIC HTML CONTENT</p>

<script type="text/html" data-name="react-live">
<div>
  <h1>react live demo</h1>
  <p>This code is editable.</p>
</div>
</script>

<p class="static-content">SOME MORE STATIC HTML CONTENT</p>

<script type="text/html" data-name="react-live">
<MyComponent />
</script>





<link href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/react-live@1.7.0/dist/react-live.min.js"></script>

现在的问题是:

如何将代码字符串嵌入到我的静态站点中,以便我可以使用我的 js 代码获取它并将其传递给我的 react-live 组件?

我想过 <pre> 之类的。或者我应该将它作为内部 html 嵌入并阅读吗?但是当 react 组件还没有渲染时,它会被短暂显示。或者我应该使用某种脚本标签并将其作为全局变量使用吗? 主要目标是尽可能轻松地向文档添加实时编辑示例,而无需触及任何 javascript 代码。

但是,如果我将 <MyComponent /> 之类的内容作为 innerHTML 传递,这当然不会起作用,正如您在代码片段中看到的那样。

赞赏该用例的任何最佳实践。

编辑:

根据 的建议,我编辑了代码片段。该解决方案现在读取 innerHTML 设置了 type="text/html 的脚本标签,并创建一个 <div> 容器来插入编辑器。这似乎工作得很好。还有更多想法吗?

在我看来,最好的选择是使用带有自定义类型属性的 <script> 标签。看一下使用 type="text/html 或 Angular <script type="text/ng-template">

Knockout.js template binding

这样浏览器将完全忽略脚本标签,因为它不知道如何解释它。