github.com/evanw/esbuild@v0.21.4/scripts/browser/index.html (about) 1 <!DOCTYPE html> 2 <script> 3 function setupForProblemCSS(prefix) { 4 // https://github.com/tailwindlabs/tailwindcss/issues/2889 5 const original = ` 6 /* Variant 1 */ 7 .${prefix}-v1 { --a: ; --b: ; max-width: var(--a) var(--b); } 8 .${prefix}-a { --a: 1px; } 9 .${prefix}-b { --b: 2px; } 10 11 /* Variant 2 */ 12 .${prefix}-v2 { max-width: var(--a, ) var(--b, ); } 13 .${prefix}-a { --a: 1px; } 14 .${prefix}-b { --b: 2px; } 15 ` 16 const style = document.createElement('style') 17 const test1a = document.createElement('div') 18 const test1b = document.createElement('div') 19 const test2a = document.createElement('div') 20 const test2b = document.createElement('div') 21 document.head.appendChild(style) 22 document.body.appendChild(test1a) 23 document.body.appendChild(test1b) 24 document.body.appendChild(test2a) 25 document.body.appendChild(test2b) 26 test1a.className = `${prefix}-v1 ${prefix}-a` 27 test1b.className = `${prefix}-v1 ${prefix}-b` 28 test2a.className = `${prefix}-v2 ${prefix}-a` 29 test2b.className = `${prefix}-v2 ${prefix}-b` 30 return [original, css => { 31 style.textContent = css 32 assertStrictEqual(getComputedStyle(test1a).maxWidth, `1px`) 33 assertStrictEqual(getComputedStyle(test1b).maxWidth, `2px`) 34 assertStrictEqual(getComputedStyle(test2a).maxWidth, `1px`) 35 assertStrictEqual(getComputedStyle(test2b).maxWidth, `2px`) 36 }] 37 } 38 39 async function expectThrownError(fn, err) { 40 try { 41 await fn() 42 throw new Error('Expected an error to be thrown') 43 } catch (e) { 44 assertStrictEqual(e.message, err) 45 } 46 } 47 48 function assertStrictEqual(a, b) { 49 if (a !== b) { 50 throw new Error(`Assertion failed: 51 Observed: ${JSON.stringify(a)} 52 Expected: ${JSON.stringify(b)}`); 53 } 54 } 55 56 async function runAllTests({ esbuild }) { 57 const tests = { 58 async defaultExport() { 59 assertStrictEqual(typeof esbuild.version, 'string') 60 assertStrictEqual(esbuild.version, esbuild.default.version) 61 assertStrictEqual(esbuild.version, esbuild.default.default.version) 62 assertStrictEqual(esbuild.version, esbuild.default.default.default.version) 63 }, 64 65 async transformJS() { 66 const { code } = await esbuild.transform('1+2') 67 assertStrictEqual(code, '1 + 2;\n') 68 }, 69 70 async transformTS() { 71 const { code } = await esbuild.transform('1 as any + <any>2', { loader: 'ts' }) 72 assertStrictEqual(code, '1 + 2;\n') 73 }, 74 75 async transformCSS() { 76 const { code } = await esbuild.transform('div { color: red }', { loader: 'css' }) 77 assertStrictEqual(code, 'div {\n color: red;\n}\n') 78 }, 79 80 async problemCSSOriginal() { 81 const [original, runAsserts] = setupForProblemCSS('original') 82 runAsserts(original) 83 }, 84 85 async problemCSSPrettyPrinted() { 86 const [original, runAsserts] = setupForProblemCSS('pretty-print') 87 const { code: prettyPrinted } = await esbuild.transform(original, { loader: 'css' }) 88 runAsserts(prettyPrinted) 89 }, 90 91 async problemCSSMinified() { 92 const [original, runAsserts] = setupForProblemCSS('pretty-print') 93 const { code: minified } = await esbuild.transform(original, { loader: 'css', minify: true }) 94 runAsserts(minified) 95 }, 96 97 async buildFib() { 98 const fibonacciPlugin = { 99 name: 'fib', 100 setup(build) { 101 build.onResolve({ filter: /^fib\((\d+)\)/ }, args => { 102 return { path: args.path, namespace: 'fib' } 103 }) 104 build.onLoad({ filter: /^fib\((\d+)\)/, namespace: 'fib' }, args => { 105 let match = /^fib\((\d+)\)/.exec(args.path), n = +match[1] 106 let contents = n < 2 ? `export default ${n}` : ` 107 import n1 from 'fib(${n - 1}) ${args.path}' 108 import n2 from 'fib(${n - 2}) ${args.path}' 109 export default n1 + n2` 110 return { contents } 111 }) 112 }, 113 } 114 const result = await esbuild.build({ 115 stdin: { 116 contents: ` 117 import x from 'fib(10)' 118 module.exports = x 119 `, 120 }, 121 format: 'cjs', 122 bundle: true, 123 plugins: [fibonacciPlugin], 124 }) 125 assertStrictEqual(result.outputFiles.length, 1) 126 assertStrictEqual(result.outputFiles[0].path, '<stdout>') 127 const code = result.outputFiles[0].text 128 const answer = {} 129 new Function('module', code)(answer) 130 assertStrictEqual(answer.exports, 55) 131 }, 132 133 async buildRelativeIssue693() { 134 const result = await esbuild.build({ 135 stdin: { 136 contents: `const x=1`, 137 }, 138 write: false, 139 outfile: 'esbuild.js', 140 }); 141 assertStrictEqual(result.outputFiles.length, 1) 142 assertStrictEqual(result.outputFiles[0].path, '/esbuild.js') 143 assertStrictEqual(result.outputFiles[0].text, 'const x = 1;\n') 144 }, 145 146 async watch() { 147 const context = await esbuild.context({}) 148 try { 149 await expectThrownError(context.watch, 'Cannot use the "watch" API in this environment') 150 } finally { 151 context.dispose() 152 } 153 }, 154 155 async serve() { 156 const context = await esbuild.context({}) 157 try { 158 await expectThrownError(context.serve, 'Cannot use the "serve" API in this environment') 159 } finally { 160 context.dispose() 161 } 162 }, 163 164 async esbuildBuildSync() { 165 await expectThrownError(esbuild.buildSync, 'The "buildSync" API only works in node') 166 }, 167 168 async esbuildTransformSync() { 169 await expectThrownError(esbuild.transformSync, 'The "transformSync" API only works in node') 170 }, 171 } 172 173 async function runTest(test) { 174 try { 175 await tests[test]() 176 } catch (e) { 177 e.test = test 178 throw e 179 } 180 } 181 182 const promises = [] 183 for (const test in tests) { 184 promises.push(runTest(test)) 185 } 186 await Promise.all(promises) 187 } 188 189 async function loadScript(url) { 190 const tag = document.createElement('script') 191 document.head.appendChild(tag) 192 await new Promise((resolve, reject) => { 193 tag.onload = resolve 194 tag.onerror = () => reject(new Error('Failed to load script: ' + url)) 195 tag.src = url 196 }) 197 const esbuild = window.esbuild 198 delete window.esbuild 199 return esbuild 200 } 201 202 async function testStart() { 203 if (!window.testBegin) window.testBegin = args => { 204 const { esm, min, worker, mime, approach } = JSON.parse(args) 205 console.log(`💬 config: esm=${esm}, min=${min}, worker=${worker}, mime=${mime}, approach=${approach}`) 206 } 207 208 if (!window.testEnd) window.testEnd = args => { 209 if (args === null) console.log(`👍 success`) 210 else { 211 const { test, stack, error } = JSON.parse(args) 212 console.log(`❌ error${test ? ` [${test}]` : ``}: ${error}`) 213 } 214 } 215 216 if (!window.testDone) window.testDone = error => { 217 console.log(`✅ done`) 218 } 219 220 for (const esm of [false, true]) { 221 for (const min of [false, true]) { 222 for (const worker of [false, true]) { 223 for (const mime of ['correct', 'incorrect']) { 224 for (const approach of ['string', 'url', 'module']) { 225 try { 226 testBegin(JSON.stringify({ esm, min, worker, mime, approach })) 227 const esbuild = esm 228 ? await import('/npm/esbuild-wasm/esm/browser' + (min ? '.min' : '') + '.js?' + Math.random()) 229 : await loadScript('/npm/esbuild-wasm/lib/browser' + (min ? '.min' : '') + '.js?' + Math.random()) 230 const url = mime === 'correct' ? '/npm/esbuild-wasm/esbuild.wasm' : '/scripts/browser/esbuild.wasm.bagel' 231 const initializePromise = { 232 string: () => esbuild.initialize({ wasmURL: url, worker }), 233 url: () => esbuild.initialize({ wasmURL: new URL(url, location.href), worker }), 234 module: () => fetch(url) 235 .then(r => r.arrayBuffer()) 236 .then(bytes => WebAssembly.compile(bytes)) 237 .then(module => esbuild.initialize({ wasmModule: module, worker })), 238 }[approach]() 239 await initializePromise 240 await runAllTests({ esbuild }) 241 testEnd(null) 242 } catch (e) { 243 testEnd(JSON.stringify({ 244 test: e.test || null, 245 stack: e.stack || null, 246 error: (e && e.message || e) + '', 247 })) 248 } 249 } 250 } 251 } 252 } 253 } 254 255 testDone() 256 } 257 258 testStart() 259 260 </script>