阅读 148

开发一个简单的在线代码运行页面

 这是我参与更文挑战的第 4 天,活动详情查看: 更文挑战

前言

曾经有用到 EchartsAntV G2 来开发。查看文档的过程中给我印象最深的就是它们 Demo 演示页面对使用者的帮助非常大,它们不仅提供了丰富的示例,并且可以修改代码和实时查看运行效果。

上图是G2 的 Demo 页面

Snipaste_2021-06-07_23-20-32.png

上图是 Echarts 的 Demo 页面

看到这样的功能,不禁勾起了我的好奇心。下面我来介绍一下怎样开发一个简单的在线编辑实时展示结果的页面。

开发思路

想要执行我们输入的代码,我们可以用的方法如下:

  1. eval : eval('console.log("a simple script");');
  2. new Function : new Function('console.log("a simple script");')();
  3. iframe :即新建一个 iframe 标签,在里面动态注入 html 和 js 代码

为了避免影响当前上下文的代码,我们采用 iframe 注入的方式。

接下来我们们只需要,在页面上创建可以输入代码的区域,并且在编辑时动态获取并注入到 iframe 中就可以实现想要的功能了。

代码实战

html 页面结构, 这里我们使用 codemirror 作为代码编辑器。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet"
    href="https://gw.alipayobjects.com/os/antv/assets/lib/codemirror-5.29.0/codemirror-merged.min.css">
  <title>live · code</title>
</head>
<body>
  <main>
    <section>
      <button class="execute">Copy</button>
      <button class="run">Run</button>
      <textarea class="code"></textarea>
    </section>
    <section>
      <div class="preview"></div>
    </section>
  </main>
  <script src="./main.js"></script>
</body>
</html>
复制代码

js 代码

import CodeMirror from "codemirror";

import "./style.css";

const $code = document.querySelector(".code");
const $iframeContainer = document.querySelector(".preview");
const $run = document.querySelector(".run");
const $copy = document.querySelector(".copy");

const htmlEditor = CodeMirror.fromTextArea($code, {
  mode: "text/html",
  extraKeys: {
    "Ctrl-Space": "autocomplete"
  },
  foldGutter: true,
  gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
  lineNumbers: true,
  lineWrapping: false
});

function syncCode() {
  $iframeContainer.innerHTML = "<iframe></iframe>";
  const iframe = document.querySelector('iframe')
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  iframeDoc.open();
  iframeDoc.write(htmlEditor.getValue());
  iframeDoc.close();
}

$run.addEventListener("click", syncCode);
复制代码

上面的代码用 syncCode 就是用来把编辑的代码同步到用来展示效果的 iframe 里面的,这里贴上 DEMO 源码地址, 欢迎大家下载运行。

一个简单运行示例如下

说明

示例代码参照了 antv 旧版本在线 demo 的实现方式。antv 新的实现方式可以点击这里了解,核心代码如下

const execute = debounce(
  (
    code: string,
    node: HTMLDivElement,
    exampleContainer: string | undefined,
  ) => {
    const script = document.createElement('script');
    script.innerHTML = `
      try {
        ${code}
      } catch(e) {
        if (window.__reportErrorInPlayGround) {
          window.__reportErrorInPlayGround(e);
        }
      }
    `;
    // eslint-disable-next-line no-param-reassign
    node.innerHTML = exampleContainer || '<div id="container" />';
    node!.appendChild(script);
  },
  300,
);
复制代码

现有的成熟方案

平时演示时我们可以选用现有的成熟的产品:codepenStackBlitzCodeSandboxjsbin

最后再推荐 React 和 vue 生态下各自的实时代码编辑和预览的组件:

  1. vue-live :

    A lightweight playground for live editing VueJs code in the browser

  2. react-live:

    React Live

    brings you the ability to render React components with editable source code and live preview.

参考资料

  1. js的沙箱内容
  2. 字节跳动的微前端沙盒实践
文章分类
前端
文章标签