From fb2a04d07e7e59c155af7539d7cf0d6fce5e3205 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 4 Mar 2024 15:03:52 -0800 Subject: [PATCH] Get wasm to build. --- package.json | 2 +- src/tsbuild.mjs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/tsbuild.mjs diff --git a/package.json b/package.json index ef4ba4f37..7cdc6238b 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,7 @@ }, "scripts": { "clean": "rimraf out && rimraf lib && rimraf vscode-lingua-franca-*.vsix", - "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node", + "esbuild-base": "node src/tsbuild.mjs", "vscode:prepublish": "npm run esbuild-base -- --minify", "compile": "./write-version-to-file.sh src/extension_version.ts && npm run esbuild-base -- --sourcemap", "watch": "npm run esbuild-base -- --sourcemap --watch", diff --git a/src/tsbuild.mjs b/src/tsbuild.mjs new file mode 100644 index 000000000..2f6180747 --- /dev/null +++ b/src/tsbuild.mjs @@ -0,0 +1,67 @@ +// This JS script is needed to compile the TS code. + +import * as esbuild from 'esbuild'; +import path from 'node:path'; +import fs from 'node:fs'; + +let wasmPlugin = { + name: 'wasm', + setup(build) { + // Resolve ".wasm" files to a path with a namespace + build.onResolve({ filter: /\.wasm$/ }, args => { + // If this is the import inside the stub module, import the + // binary itself. Put the path in the "wasm-binary" namespace + // to tell our binary load callback to load the binary file. + if (args.namespace === 'wasm-stub') { + return { + path: args.path, + namespace: 'wasm-binary', + }; + } + + // Otherwise, generate the JavaScript stub module for this + // ".wasm" file. Put it in the "wasm-stub" namespace to tell + // our stub load callback to fill it with JavaScript. + // + // Resolve relative paths to absolute paths here since this + // resolve callback is given "resolveDir", the directory to + // resolve imports against. + if (args.resolveDir === '') { + return; // Ignore unresolvable paths + } + return { + path: path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path), + namespace: 'wasm-stub', + }; + }); + + // Virtual modules in the "wasm-stub" namespace are filled with + // the JavaScript code for compiling the WebAssembly binary. The + // binary itself is imported from a second virtual module. + build.onLoad({ filter: /.*/, namespace: 'wasm-stub' }, async (args) => ({ + contents: `import wasm from ${JSON.stringify(args.path)} + export default (imports) => + WebAssembly.instantiate(wasm, imports).then( + result => result.instance.exports)`, + })); + + // Virtual modules in the "wasm-binary" namespace contain the + // actual bytes of the WebAssembly file. This uses esbuild's + // built-in "binary" loader instead of manually embedding the + // binary data inside JavaScript code ourselves. + build.onLoad({ filter: /.*/, namespace: 'wasm-binary' }, async (args) => ({ + contents: await fs.promises.readFile(args.path), + loader: 'binary', + })); + }, +}; + +await esbuild.build({ + entryPoints: ['./src/extension.js'], + bundle: true, + outfile: 'out/extension.js', + plugins: [wasmPlugin], + external: ['vscode'], + format: 'cjs', + platform: 'node' +});