You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							101 lines
						
					
					
						
							4.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							101 lines
						
					
					
						
							4.0 KiB
						
					
					
				| #!/usr/bin/env node | |
|  | |
| // Forward to the automatically-generated WebAssembly loader from the Go compiler | |
|  | |
| const crypto = require('crypto'); | |
| const path = require('path'); | |
| const zlib = require('zlib'); | |
| const fs = require('fs'); | |
| const os = require('os'); | |
| 
 | |
| const wasm_exec = path.join(__dirname, '..', 'wasm_exec.js'); | |
| const esbuild_wasm = path.join(__dirname, '..', 'esbuild.wasm'); | |
| 
 | |
| const code = fs.readFileSync(wasm_exec, 'utf8'); | |
| const wrapper = new Function('require', 'module', 'process', 'WebAssembly', code); | |
| 
 | |
| function instantiate(bytes, importObject) { | |
|   // Using this API causes "./esbuild --version" to run around 1 second faster | |
|   // than using the "WebAssembly.instantiate()" API when run in node (v12.16.2) | |
|   const module = new WebAssembly.Module(bytes); | |
|   const instance = new WebAssembly.Instance(module, importObject); | |
|   return Promise.resolve({ instance, module }); | |
| } | |
| 
 | |
| // Node has an unfortunate bug where the node process is unnecessarily kept open while a | |
| // WebAssembly module is being optimized: https://github.com/nodejs/node/issues/36616. | |
| // This means cases where running "esbuild" should take a few milliseconds can end up | |
| // taking many seconds instead. To work around this bug, it is possible to force node to | |
| // exit by calling the operating system's exit function. That's what this code does. | |
| process.on('exit', code => { | |
|   // If it's a non-zero exit code, we can just kill our own process to stop. This will | |
|   // preserve the fact that there is a non-zero exit code although the exit code will | |
|   // be different. We cannot use this if the exit code is supposed to be zero. | |
|   if (code !== 0) { | |
|     try { | |
|       process.kill(process.pid, 'SIGINT'); | |
|     } catch (e) { | |
|     } | |
|     return; | |
|   } | |
| 
 | |
|   // Otherwise if the exit code is zero, try to fall back to a binary N-API module that | |
|   // calls the operating system's "exit(0)" function. | |
|   const nativeModule = `${process.platform}-${os.arch()}-${os.endianness()}.node`; | |
|   const base64 = require('../exit0')[nativeModule]; | |
|   if (base64) { | |
|     try { | |
|       const data = zlib.inflateRawSync(Buffer.from(base64, 'base64')); | |
|       const hash = crypto.createHash('sha256').update(base64).digest().toString('hex').slice(0, 16); | |
|       const tempFile = path.join(os.tmpdir(), `${hash}-${nativeModule}`); | |
|       try { | |
|         if (fs.readFileSync(tempFile).equals(data)) { | |
|           require(tempFile); | |
|         } | |
|       } finally { | |
|         fs.writeFileSync(tempFile, data); | |
|         require(tempFile); | |
|       } | |
|     } catch (e) { | |
|     } | |
|   } | |
| }); | |
| 
 | |
| // Node has another bug where using "fs.read" to read from stdin reads | |
| // everything successfully and then throws an error, but only on Windows. Go's | |
| // WebAssembly support uses "fs.read" so it hits this problem. This is a patch | |
| // to try to work around the bug in node. This bug has been reported to node | |
| // at least twice in https://github.com/nodejs/node/issues/35997 and in | |
| // https://github.com/nodejs/node/issues/19831. This issue has also been | |
| // reported to the Go project: https://github.com/golang/go/issues/43913. | |
| const read = fs.read; | |
| fs.read = function () { | |
|   const callback = arguments[5]; | |
|   arguments[5] = function (err, count) { | |
|     if (count === 0 && err && err.code === 'EOF') { | |
|       arguments[0] = null; | |
|     } | |
|     return callback.apply(this, arguments); | |
|   }; | |
|   return read.apply(this, arguments); | |
| }; | |
| 
 | |
| // WASM code generated with Go 1.17.2+ will crash when run in a situation with | |
| // many environment variables: https://github.com/golang/go/issues/49011. An | |
| // example of this situation is running a Go-compiled WASM executable in GitHub | |
| // Actions. Work around this by filtering node's copy of environment variables | |
| // down to only include the environment variables that esbuild currently uses. | |
| const esbuildUsedEnvVars = [ | |
|   'NO_COLOR', | |
|   'NODE_PATH', | |
|   'npm_config_user_agent', | |
|   'WT_SESSION', | |
| ] | |
| for (let key in process.env) { | |
|   if (esbuildUsedEnvVars.indexOf(key) < 0) { | |
|     delete process.env[key] | |
|   } | |
| } | |
| 
 | |
| const argv = ['node', wasm_exec, esbuild_wasm].concat(process.argv.slice(2)); | |
| wrapper(require, require.main, Object.assign(Object.create(process), { argv }), Object.assign(Object.create(WebAssembly), { instantiate }));
 |