From a8bfe73321c05dc1ad7dbceae91d24aba921461a Mon Sep 17 00:00:00 2001 From: Pabloader Date: Mon, 8 Jul 2024 21:46:35 +0000 Subject: [PATCH] Fallback to TypeScript compilation for wasm.ts --- src/build/html.ts | 4 +-- src/build/server.ts | 6 +++- src/build/wasmPlugin.ts | 76 +++++++++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/build/html.ts b/src/build/html.ts index b31126b..2a8cd93 100644 --- a/src/build/html.ts +++ b/src/build/html.ts @@ -9,7 +9,7 @@ import lightningcss from 'bun-lightningcss'; import { getGames } from './isGame'; -export async function buildHTML(game: string, production = false) { +export async function buildHTML(game: string, production = false, portable = false) { const html = await Bun.file(path.resolve(import.meta.dir, '..', 'assets', 'index.html')).text(); const bundle = await Bun.build({ outdir: '/tmp', @@ -23,7 +23,7 @@ export async function buildHTML(game: string, production = false) { plugins: [ imagePlugin, fontPlugin, - wasmPlugin, + wasmPlugin({ production, portable }), lightningcss(), ] }); diff --git a/src/build/server.ts b/src/build/server.ts index d5329d2..be94617 100644 --- a/src/build/server.ts +++ b/src/build/server.ts @@ -15,7 +15,11 @@ Bun.serve({ case '/': case 'index.html': try { - const html = await buildHTML(game); + const html = await buildHTML( + game, + url.searchParams.get('production') === 'true', // to debug production builds + url.searchParams.get('portable') === 'true', // to skip AssemblyScript compilation + ); if (html) { return new Response(html, { headers: { diff --git a/src/build/wasmPlugin.ts b/src/build/wasmPlugin.ts index 6776533..e46c2cf 100644 --- a/src/build/wasmPlugin.ts +++ b/src/build/wasmPlugin.ts @@ -2,38 +2,54 @@ import { plugin, type BunPlugin } from "bun"; import path from 'path'; import asc from 'assemblyscript/asc'; -const wasmPlugin: BunPlugin = { - name: "WASM loader", - async setup(build) { - build.onLoad({ filter: /\.wasm\.ts$/ }, async (args) => { - const wasmPath = path.resolve(import.meta.dir, '..', '..', 'dist', 'tmp.wasm'); - const jsPath = wasmPath.replace(/\.wasm$/, '.js'); - const { error, stderr } = await asc.main([ - args.path, - '--outFile', wasmPath, - '--textFile', wasmPath.replace(/\.wasm$/, '.wat'), - '--optimize', '--bindings', 'esm', - ]); +interface WasmLoaderConfig { + production?: boolean; + portable?: boolean; +} - if (error) { - console.error(stderr.toString(), error.message); - throw error; - } else { - const jsContent = await Bun.file(jsPath).text(); - const wasmContent = await Bun.file(wasmPath).arrayBuffer(); - const wasmBuffer = Buffer.from(wasmContent).toString('base64'); - const wasmURL = `data:application/wasm;base64,${wasmBuffer}`; +const wasmPlugin = ({ production, portable }: WasmLoaderConfig = {}): BunPlugin => { + const p: BunPlugin = { + name: "WASM loader", + async setup(build) { + build.onLoad({ filter: /\.wasm\.ts$/ }, async (args) => { + if (portable) { + const contents = await Bun.file(args.path).text(); + return { + contents: `import "assemblyscript/std/portable/index.js";\n${contents}`, + loader: 'tsx', + } + } + const wasmPath = path.resolve(import.meta.dir, '..', '..', 'dist', 'tmp.wasm'); + const jsPath = wasmPath.replace(/\.wasm$/, '.js'); + const ascArgs = [ + args.path, + '--outFile', wasmPath, + '--bindings', 'esm', + ]; + ascArgs.push(production ? '--optimize' : '--debug'); - return { - loader: 'js', - contents: jsContent - .replace(/new URL\([^)]*\)/, `new URL(${JSON.stringify(wasmURL)})`), - }; - } - }); - } + const { error, stderr } = await asc.main(ascArgs); + + if (error) { + console.error(stderr.toString(), error.message); + throw error; + } else { + const jsContent = await Bun.file(jsPath).text(); + const wasmContent = await Bun.file(wasmPath).arrayBuffer(); + const wasmBuffer = Buffer.from(wasmContent).toString('base64'); + const wasmURL = `data:application/wasm;base64,${wasmBuffer}`; + + return { + loader: 'js', + contents: jsContent + .replace(/new URL\([^)]*\)/, `new URL(${JSON.stringify(wasmURL)})`), + }; + } + }); + } + }; + plugin(p); + return p; }; -plugin(wasmPlugin); - export default wasmPlugin; \ No newline at end of file