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 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 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 227 <label for="ascii"> 228 <input id="ascii" type="checkbox"> 229 ASCII 230 </label> 231 232 <label for="keepNames"> 233 <input id="keepNames" type="checkbox"> 234 Keep Names 235 </label> 236 237 <label for="mangleProps"> 238 <input id="mangleProps" type="checkbox"> 239 Mangle Props 240 </label> 241 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, '&').replace(/</g, '<').replace(/>/g, '>') 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>