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 }));