|
|
|
@ -1,21 +1,11 @@
|
|
|
|
|
const fs = require("fs")
|
|
|
|
|
const { execFileSync } = require("child_process")
|
|
|
|
|
const path = require("path")
|
|
|
|
|
const { lookpath } = require("lookpath")
|
|
|
|
|
|
|
|
|
|
const exists = async (dir, file) => {
|
|
|
|
|
return new Promise((res, rej) => {
|
|
|
|
|
fs.access(path.join(dir, file), fs.constants.F_OK, (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
return res(false)
|
|
|
|
|
}
|
|
|
|
|
return res(true)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const fs = require("fs/promises");
|
|
|
|
|
const util = require("util");
|
|
|
|
|
const execFile = util.promisify(require("child_process").execFile);
|
|
|
|
|
const path = require("path");
|
|
|
|
|
const { lookpath } = require("lookpath");
|
|
|
|
|
|
|
|
|
|
module.exports = function (source) {
|
|
|
|
|
const cb = this.async()
|
|
|
|
|
const cb = this.async();
|
|
|
|
|
|
|
|
|
|
const goBin = lookpath("go");
|
|
|
|
|
if (!goBin) {
|
|
|
|
@ -24,62 +14,72 @@ module.exports = function (source) {
|
|
|
|
|
|
|
|
|
|
if (!process.env.GOROOT) {
|
|
|
|
|
return cb(new Error("Could not find GOROOT in environment.\n" +
|
|
|
|
|
"Please try adding this to your script:\nGOROOT=`go env GOROOT` npm run ..."))
|
|
|
|
|
"Please try adding this to your script:\n" +
|
|
|
|
|
"GOROOT=`go env GOROOT` npm run ..."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const parent = path.dirname(this.resourcePath)
|
|
|
|
|
const outFile = this.resourcePath.slice(0, -2) + "wasm"
|
|
|
|
|
let modDir = parent
|
|
|
|
|
let found = false;
|
|
|
|
|
const parent = path.dirname(this.resourcePath);
|
|
|
|
|
const outFile = this.resourcePath.slice(0, -2) + "wasm";
|
|
|
|
|
let modDir = parent;
|
|
|
|
|
|
|
|
|
|
const opts = {
|
|
|
|
|
cwd: parent,
|
|
|
|
|
env: {
|
|
|
|
|
GOPATH: process.env.GOPATH,
|
|
|
|
|
GOPATH: process.env.GOPATH || path.join(process.env.HOME, "go"),
|
|
|
|
|
GOROOT: process.env.GOROOT,
|
|
|
|
|
GOCACHE: path.join(__dirname, ".gocache"),
|
|
|
|
|
GOOS: "js",
|
|
|
|
|
GOARCH: "wasm",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
(async () => {
|
|
|
|
|
const root = path.resolve(path.sep)
|
|
|
|
|
let found = false;
|
|
|
|
|
const root = path.resolve(path.sep);
|
|
|
|
|
while (path.resolve(modDir) != root) {
|
|
|
|
|
if (!(await exists(modDir, 'go.mod'))) {
|
|
|
|
|
modDir = path.join(modDir, '..');
|
|
|
|
|
} else {
|
|
|
|
|
found = true;
|
|
|
|
|
found = await fs.access(path.join(modDir, 'go.mod')).then(() => true).catch(() => false);
|
|
|
|
|
if (found) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
modDir = path.join(modDir, "..");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
|
return cb(new Error("Could not find go.mod in any parent directory of " + this.resourcePath))
|
|
|
|
|
return cb(new Error("Could not find go.mod in any parent directory of " + this.resourcePath));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
execFileSync("go", ["build", "-o", outFile, parent], opts)
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return cb(e)
|
|
|
|
|
const wasmOrigPath = path.join(process.env.GOROOT, "misc", "wasm", "wasm_exec.js");
|
|
|
|
|
const wasmSavePath = path.join(__dirname, 'wasm_exec.js');
|
|
|
|
|
const errorPaths = ["\t" + wasmOrigPath, "\t" + wasmSavePath];
|
|
|
|
|
if (!(await fs.access(wasmOrigPath).then(() => true).catch(() => false)) &&
|
|
|
|
|
!(await fs.access(wasmSavePath).then(() => true).catch(() => false))) {
|
|
|
|
|
return cb(new Error("Could not find wasm_exec.js file. Invalid GOROOT? Searched paths:\n" +
|
|
|
|
|
errorPaths.join(",\n") + "\n"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const wasmOrigPath = path.join(process.env.GOROOT, "misc", "wasm", "wasm_exec.js")
|
|
|
|
|
const wasmEmitPath = path.join(__dirname, 'wasm_exec.js')
|
|
|
|
|
if (!(await exists(__dirname, 'wasm_exec.js'))) {
|
|
|
|
|
fs.copyFileSync(wasmOrigPath, wasmEmitPath)
|
|
|
|
|
|
|
|
|
|
const res = await execFile("go", ["build", "-o", outFile, parent], opts)
|
|
|
|
|
.then(() => true)
|
|
|
|
|
.catch(e => e);
|
|
|
|
|
if (res instanceof Error) {
|
|
|
|
|
return cb(e);
|
|
|
|
|
}
|
|
|
|
|
const contents = fs.readFileSync(outFile)
|
|
|
|
|
fs.unlinkSync(outFile)
|
|
|
|
|
|
|
|
|
|
const emitPath = path.basename(outFile)
|
|
|
|
|
this.emitFile(emitPath, contents)
|
|
|
|
|
this.addContextDependency(modDir)
|
|
|
|
|
found = await fs.access(wasmSavePath).then(() => true).catch(() => false);
|
|
|
|
|
if (!found) fs.copyFile(wasmOrigPath, wasmSavePath);
|
|
|
|
|
|
|
|
|
|
const contents = await fs.readFile(outFile);
|
|
|
|
|
fs.unlink(outFile);
|
|
|
|
|
|
|
|
|
|
const emitPath = path.basename(outFile);
|
|
|
|
|
this.emitFile(emitPath, contents);
|
|
|
|
|
this.addContextDependency(modDir);
|
|
|
|
|
|
|
|
|
|
cb(null,
|
|
|
|
|
`require('!${wasmEmitPath}')
|
|
|
|
|
`require('!${wasmSavePath}');
|
|
|
|
|
import goWasm from '${path.join(__dirname, 'bridge.js')}';
|
|
|
|
|
|
|
|
|
|
const wasm = fetch('${emitPath}').then(response => response.arrayBuffer())
|
|
|
|
|
export default goWasm(wasm)`)
|
|
|
|
|
})()
|
|
|
|
|
}
|
|
|
|
|
const wasm = fetch('${emitPath}').then(response => response.arrayBuffer());
|
|
|
|
|
export default goWasm(wasm);`);
|
|
|
|
|
})();
|
|
|
|
|
}
|
|
|
|
|