github.com/evanw/esbuild@v0.21.4/scripts/try.html (about)

     1  <!-- This is a simple playground to try out esbuild in your browser -->
     2  <!DOCTYPE html>
     3  <html>
     4  
     5  <head>
     6    <meta charset="utf8">
     7    <title>Try esbuild live</title>
     8    <style>
     9      body {
    10        font: 15px/120% sans-serif;
    11        overflow: hidden;
    12      }
    13  
    14      h2,
    15      p {
    16        cursor: default;
    17        user-select: none;
    18      }
    19  
    20      textarea {
    21        resize: none;
    22        width: 100%;
    23        height: 100%;
    24      }
    25  
    26      textarea,
    27      #output .outer {
    28        box-sizing: border-box;
    29        padding: 4px;
    30        color: inherit;
    31        font-size: 13px;
    32        line-height: 110%;
    33        font-family: monospace;
    34        cursor: text;
    35        tab-size: 2;
    36      }
    37  
    38      #output .outer {
    39        white-space: pre-wrap;
    40        overflow-y: auto;
    41      }
    42  
    43      .minified {
    44        word-break: break-all;
    45      }
    46  
    47      textarea:focus {
    48        outline: none;
    49        border: 1px solid #999;
    50      }
    51  
    52      hr {
    53        border: 1px solid #999;
    54        margin: 1em 0;
    55      }
    56  
    57      section {
    58        position: absolute;
    59        top: 0;
    60        bottom: 0;
    61        padding: 0 20px;
    62        box-sizing: border-box;
    63      }
    64  
    65      section p {
    66        line-height: 26px;
    67      }
    68  
    69      #input {
    70        left: 0;
    71        width: 50%;
    72      }
    73  
    74      #output {
    75        right: 0;
    76        width: 50%;
    77      }
    78  
    79      .outer {
    80        position: absolute;
    81        left: 20px;
    82        top: 120px;
    83        right: 20px;
    84        bottom: 20px;
    85      }
    86  
    87      #input .outer {
    88        right: 10px;
    89      }
    90  
    91      #output .outer {
    92        left: 10px;
    93      }
    94  
    95      label {
    96        white-space: nowrap;
    97      }
    98  
    99      body {
   100        background: #EEE;
   101        color: #333;
   102      }
   103  
   104      textarea,
   105      #output .outer {
   106        background: #FFF;
   107        border: 1px solid #CCC;
   108      }
   109  
   110      .terminal-1 {
   111        font-weight: bold;
   112      }
   113  
   114      .terminal-37 {
   115        color: #999;
   116      }
   117  
   118      .terminal-4 {
   119        text-decoration: underline;
   120      }
   121  
   122      .terminal-31 {
   123        color: #D00;
   124      }
   125  
   126      .terminal-32 {
   127        color: #0D0;
   128      }
   129  
   130      .terminal-33 {
   131        color: #CC0;
   132      }
   133  
   134      .terminal-35 {
   135        color: #D0D;
   136      }
   137  
   138      @media (prefers-color-scheme: dark) {
   139        body {
   140          background: #333;
   141          color: #DDD;
   142        }
   143  
   144        textarea,
   145        #output .outer {
   146          background: #111;
   147          border: 1px solid #555;
   148        }
   149  
   150        .terminal-37 {
   151          color: #777;
   152        }
   153      }
   154  
   155    </style>
   156  </head>
   157  
   158  <body>
   159    <section id="input">
   160      <h2>Input</h2>
   161      <p>
   162        <label for="target">
   163          Target: <select id="target">
   164            <option>ES5</option>
   165            <option>ES2015</option>
   166            <option>ES2016</option>
   167            <option>ES2017</option>
   168            <option>ES2018</option>
   169            <option>ES2019</option>
   170            <option>ES2020</option>
   171            <option>ES2021</option>
   172            <option selected>ESNext</option>
   173  
   174            <option>Chrome70</option>
   175            <option>Chrome71</option>
   176            <option>Chrome72</option>
   177            <option>Chrome73</option>
   178            <option>Chrome74</option>
   179            <option>Chrome75</option>
   180            <option>Chrome76</option>
   181            <option>Chrome77</option>
   182            <option>Chrome78</option>
   183            <option>Chrome79</option>
   184  
   185            <option>Chrome80</option>
   186            <option>Chrome81</option>
   187            <option>Chrome82</option>
   188            <option>Chrome83</option>
   189            <option>Chrome84</option>
   190            <option>Chrome85</option>
   191            <option>Chrome86</option>
   192            <option>Chrome87</option>
   193            <option>Chrome88</option>
   194            <option>Chrome89</option>
   195          </select>
   196        </label>
   197        &nbsp; &nbsp;
   198        <label for="loader">
   199          Loader: <select id="loader">
   200            <option selected>JS</option>
   201            <option>JSX</option>
   202            <option>TS</option>
   203            <option>TSX</option>
   204            <option>CSS</option>
   205            <option>JSON</option>
   206            <option>Text</option>
   207            <option>Base64</option>
   208            <option>DataURL</option>
   209            <option>Binary</option>
   210          </select>
   211        </label>
   212        &nbsp; &nbsp;
   213        <label for="format">
   214          Format: <select id="format">
   215            <option selected>Preserve</option>
   216            <option>IIFE</option>
   217            <option>CJS</option>
   218            <option>ESM</option>
   219          </select>
   220        </label>
   221        <br>
   222        <label for="bundle">
   223          <input id="bundle" type="checkbox">
   224          Bundle
   225        </label>
   226        &nbsp; &nbsp;
   227        <label for="ascii">
   228          <input id="ascii" type="checkbox">
   229          ASCII
   230        </label>
   231        &nbsp; &nbsp;
   232        <label for="keepNames">
   233          <input id="keepNames" type="checkbox">
   234          Keep Names
   235        </label>
   236        &nbsp; &nbsp;
   237        <label for="mangleProps">
   238          <input id="mangleProps" type="checkbox">
   239          Mangle Props
   240        </label>
   241        &nbsp; &nbsp;
   242        Minify:
   243        <label for="minify-syntax"><input id="minify-syntax" type="checkbox"> Syntax</label>
   244        <label for="minify-idents"><input id="minify-idents" type="checkbox"> Identifiers</label>
   245        <label for="minify-spaces"><input id="minify-spaces" type="checkbox"> Whitespace</label>
   246      </p>
   247      <div class="outer"><textarea autofocus spellcheck="false"></textarea></div>
   248    </section>
   249    <section id="output">
   250      <h2>Output</h2>
   251      <div class="outer"></div>
   252    </section>
   253    <script src="../npm/esbuild-wasm/lib/browser.js"></script>
   254    <script>
   255      const input = document.querySelector('#input textarea')
   256      const target = document.querySelector('#target')
   257      const loader = document.querySelector('#loader')
   258      const format = document.querySelector('#format')
   259      const minifySyntax = document.querySelector('#minify-syntax')
   260      const minifyIdents = document.querySelector('#minify-idents')
   261      const minifySpaces = document.querySelector('#minify-spaces')
   262      const ascii = document.querySelector('#ascii')
   263      const bundle = document.querySelector('#bundle')
   264      const keepNames = document.querySelector('#keepNames')
   265      const mangleProps = document.querySelector('#mangleProps')
   266      let runIfIdle
   267  
   268      function persistValue(el, key) {
   269        el.onchange = () => {
   270          runIfIdle()
   271          try {
   272            sessionStorage.setItem(key, el.value)
   273          } catch (e) {
   274          }
   275        }
   276        try {
   277          const old = sessionStorage.getItem(key)
   278          if (old !== null) el.value = old
   279        } catch (e) {
   280        }
   281      }
   282  
   283      function persistChecked(el, key) {
   284        el.onchange = () => {
   285          runIfIdle()
   286          try {
   287            sessionStorage.setItem(key, el.checked)
   288          } catch (e) {
   289          }
   290        }
   291        try {
   292          const old = sessionStorage.getItem(key)
   293          if (old !== null) el.checked = old === 'true'
   294        } catch (e) {
   295        }
   296      }
   297  
   298      persistValue(target, 'target')
   299      persistValue(loader, 'loader')
   300      persistValue(format, 'format')
   301      persistChecked(minifySyntax, 'minifySyntax')
   302      persistChecked(minifyIdents, 'minifyIdents')
   303      persistChecked(minifySpaces, 'minifySpaces')
   304      persistChecked(ascii, 'ascii')
   305      persistChecked(bundle, 'bundle')
   306      persistChecked(keepNames, 'keepNames')
   307      persistChecked(mangleProps, 'mangleProps')
   308  
   309      try {
   310        const old = sessionStorage.getItem('input')
   311        if (old !== null) input.value = old
   312      } catch (e) {
   313      }
   314  
   315      esbuild.initialize({
   316        wasmURL: '../npm/esbuild-wasm/esbuild.wasm',
   317      }).then(() => {
   318        const output = document.querySelector('#output .outer')
   319        let debounceTimeout = 0
   320        let isRunning = false
   321        let needsRun = false
   322  
   323        input.oninput = () => {
   324          clearTimeout(debounceTimeout)
   325          debounceTimeout = setTimeout(runIfIdle, 50)
   326        }
   327  
   328        runIfIdle = async () => {
   329          clearTimeout(debounceTimeout)
   330  
   331          if (isRunning) {
   332            needsRun = true
   333            return
   334          }
   335  
   336          isRunning = true
   337          needsRun = false
   338  
   339          const inputValue = input.value
   340          var code, warnings, errors
   341          try {
   342            if (bundle.checked) {
   343              const results = await esbuild.build({
   344                stdin: {
   345                  contents: inputValue,
   346                  loader: loader.value.toLowerCase(),
   347                },
   348                bundle: true,
   349                target: target.value.toLowerCase(),
   350                format: format.value === 'Preserve' ? void 0 : format.value.toLowerCase(),
   351                minifySyntax: minifySyntax.checked,
   352                minifyIdentifiers: minifyIdents.checked,
   353                minifyWhitespace: minifySpaces.checked,
   354                charset: ascii.checked ? 'ascii' : 'utf8',
   355                keepNames: keepNames.checked,
   356                mangleProps: mangleProps.checked ? /_$/ : void 0,
   357                plugins: [{
   358                  name: 'external-all',
   359                  setup(build) {
   360                    build.onResolve({ filter: /.*/ }, args => {
   361                      return { path: args.path, external: true }
   362                    })
   363                  },
   364                }],
   365              })
   366              code = results.outputFiles[0].text
   367              warnings = results.warnings
   368            } else {
   369              ({ code, warnings } = await esbuild.transform(inputValue, {
   370                target: target.value.toLowerCase(),
   371                loader: loader.value.toLowerCase(),
   372                format: format.value === 'Preserve' ? void 0 : format.value.toLowerCase(),
   373                minifySyntax: minifySyntax.checked,
   374                minifyIdentifiers: minifyIdents.checked,
   375                minifyWhitespace: minifySpaces.checked,
   376                charset: ascii.checked ? 'ascii' : 'utf8',
   377                keepNames: keepNames.checked,
   378                mangleProps: mangleProps.checked ? /_$/ : void 0,
   379              }))
   380            }
   381          } catch (error) {
   382            ({ errors, warnings } = error)
   383            if (!errors) {
   384              output.textContent = (error && error.message) || (error + '')
   385              isRunning = false
   386              if (needsRun) runIfIdle()
   387              return
   388            }
   389          }
   390          if (warnings) warnings = await esbuild.formatMessages(warnings, { kind: 'warning', color: true })
   391          if (errors) errors = await esbuild.formatMessages(errors, { kind: 'error', color: true })
   392          const html = (errors || []).concat(warnings || []).map(messageToHTML).join('')
   393          if (code) code = textToHTML(code)
   394          if (code && minifySpaces.checked) code = `<span class="minified">${code}</span>`
   395          output.innerHTML = (html && html + '<hr>' || '') + (code || '')
   396  
   397          try {
   398            sessionStorage.setItem('input', inputValue)
   399          } catch (e) {
   400          }
   401  
   402          isRunning = false
   403          if (needsRun) runIfIdle()
   404        }
   405  
   406        function textToHTML(text) {
   407          return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
   408        }
   409  
   410        function messageToHTML(text) {
   411          let reset = ''
   412          text = textToHTML(text)
   413          text = text.replace(/\033\[([^m]+)m/g, (_, value) => {
   414            if (value === '0') {
   415              value = reset
   416              reset = ''
   417            } else {
   418              reset += '</span>'
   419              value = `<span class="terminal-${value}">`
   420            }
   421            return value
   422          })
   423          text += reset
   424          return text
   425        }
   426  
   427        runIfIdle()
   428      })
   429    </script>
   430  </body>
   431  
   432  </html>