github.com/evanw/esbuild@v0.21.4/npm/esbuild-wasm/bin/esbuild (about) 1 #!/usr/bin/env node 2 3 // Forward to the automatically-generated WebAssembly loader from the Go compiler 4 5 const module_ = require('module'); 6 const path = require('path'); 7 const fs = require('fs'); 8 9 const wasm_exec_node = path.join(__dirname, '..', 'wasm_exec_node.js'); 10 const esbuild_wasm = path.join(__dirname, '..', 'esbuild.wasm'); 11 12 const code = fs.readFileSync(wasm_exec_node, 'utf8'); 13 const wrapper = new Function('require', 'WebAssembly', code); 14 15 function instantiate(bytes, importObject) { 16 // Using this API causes "./esbuild --version" to run around 1 second faster 17 // than using the "WebAssembly.instantiate()" API when run in node (v12.16.2) 18 const module = new WebAssembly.Module(bytes); 19 const instance = new WebAssembly.Instance(module, importObject); 20 return Promise.resolve({ instance, module }); 21 } 22 23 // Node has another bug where using "fs.read" to read from stdin reads 24 // everything successfully and then throws an error, but only on Windows. Go's 25 // WebAssembly support uses "fs.read" so it hits this problem. This is a patch 26 // to try to work around the bug in node. This bug has been reported to node 27 // at least twice in https://github.com/nodejs/node/issues/35997 and in 28 // https://github.com/nodejs/node/issues/19831. This issue has also been 29 // reported to the Go project: https://github.com/golang/go/issues/43913. 30 const read = fs.read; 31 fs.read = function () { 32 const callback = arguments[5]; 33 arguments[5] = function (err, count) { 34 if (count === 0 && err && err.code === 'EOF') { 35 arguments[0] = null; 36 } 37 return callback.apply(this, arguments); 38 }; 39 return read.apply(this, arguments); 40 }; 41 42 // Hack around a Unicode bug in node: https://github.com/nodejs/node/issues/24550. 43 // See this for the matching Go issue: https://github.com/golang/go/issues/43917. 44 const write = fs.write; 45 fs.write = function (fd, buf, offset, length, position, callback) { 46 if (offset === 0 && length === buf.length && position === null) { 47 if (fd === process.stdout.fd) { 48 try { 49 process.stdout.write(buf, err => err ? callback(err, 0, null) : callback(null, length, buf)); 50 } catch (err) { 51 callback(err, 0, null); 52 } 53 return; 54 } 55 if (fd === process.stderr.fd) { 56 try { 57 process.stderr.write(buf, err => err ? callback(err, 0, null) : callback(null, length, buf)); 58 } catch (err) { 59 callback(err, 0, null); 60 } 61 return; 62 } 63 } 64 return write.apply(this, arguments); 65 }; 66 const writeSync = fs.writeSync; 67 fs.writeSync = function (fd, buf) { 68 if (fd === process.stdout.fd) return process.stdout.write(buf), buf.length; 69 if (fd === process.stderr.fd) return process.stderr.write(buf), buf.length; 70 return writeSync.apply(this, arguments); 71 }; 72 73 // WASM code generated with Go 1.17.2+ will crash when run in a situation with 74 // many environment variables: https://github.com/golang/go/issues/49011. An 75 // example of this situation is running a Go-compiled WASM executable in GitHub 76 // Actions. Work around this by filtering node's copy of environment variables 77 // down to only include the environment variables that esbuild currently uses. 78 const esbuildUsedEnvVars = [ 79 'NO_COLOR', 80 'NODE_PATH', 81 'npm_config_user_agent', 82 'WT_SESSION', 83 ] 84 for (let key in process.env) { 85 if (esbuildUsedEnvVars.indexOf(key) < 0) { 86 delete process.env[key] 87 } 88 } 89 90 // Node v19 introduced "globalThis.crypto" https://github.com/nodejs/node/pull/44897. 91 // This broke Go's WebAssembly shim: https://github.com/golang/go/issues/56860. 92 // Hack around this breakage by resetting "globalThis.crypto" to "writable". 93 // Just to be safe, also make it "configurable" in case Go updates their 94 // compiler such that it tries to reconfigure "globalThis.crypto" itself. 95 Object.defineProperty(globalThis, 'crypto', { 96 writable: true, 97 configurable: true, 98 }); 99 100 process.argv.splice(2, 0, esbuild_wasm); 101 wrapper(module_.createRequire(wasm_exec_node), Object.assign(Object.create(WebAssembly), { instantiate }));