esbuild 3.4 KB

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