The latest version of the qjsc build is available (CORS enabled) at:
- bellard/quickjs
- Forked by and modified for Hooks by @RichardAH: RichardAH/quickjslite
- second-state/quickjs-wasi
- As originally forked from: dip-proto/quickjs-wasi
- WebAssembly/wasi-sdk (wasi-sdk-22)
You can conveniently build using Docker.
To build the container image for the build process:
docker build --tag quickjs-wasm-builder .To build the qjsc.wasm JS Compiler WebAssembly binary using the previously created container:
docker run --rm --platform linux/amd64 -v $(pwd)/build:/wasi/build \
quickjs-wasm-builder qjscTo build qjs.wasm (QuickJS Runtime) WebAssembly binary using the previously created container:
docker run --rm --platform linux/amd64 -v $(pwd)/build:/wasi/build \
quickjs-wasm-builder qjsTo run the .wasm binaries, we're using wasmedge: we need a virtual filesystem, stdin, stdout, etc. and
wasmedge happily provides this context:
After building qjsc.wasm:
wasmedge --dir=.:. ./build/qjsc.wasm -c -o whatever.bc whatever.jsAfter building qjs.wasm:
wasmedge --dir=.:. ./build/qjs.wasm -e "console.log('Hello World');"To use the above .wasm files in your browser, create Javascript code like below, and save it as qjsc.mjs.
You can build this .mjs file for the browser with esbuild:
esbuild qjsc.mjs --bundle --minify --tree-shaking=true --platform=browser --format=esm --target=es2017 > qjsc-browser.jsNow you have a qjsc-browser.js file to use in the browser, which you can include as modules:
<script type="module" src="./qjsc-browser.js"></script>qjsc.mjs example source code:
import { WASI } from "@runno/wasi"
import { Buffer } from 'buffer/' // Browser needs this, node (CLI) doesn't
const wasmLocation = 'https://my-site.com/qjsc.wasm' // Must be served with mime type application/wasm!
const result = WASI.start(fetch(wasmLocation), {
args: ["qjsc", "-c", "-o", "/hook.bc", '/hook.js'],
env: { SOME_KEY: "some value" },
stdout: (out) => alert("stdout: " + out),
stderr: (err) => alert("stderr:" + err),
stdin: () => prompt("stdin:"),
fs: {
"/hook.js": {
mode: "string",
content: 'console.log("Hello World!")', // Contents here, read from file / textinput / fs (node) / fetch ...
},
},
})
result.then(r => {
// Sanitize some things to make it ready for a SetHook create code:
const compiledHook = Buffer.from(r.fs?.['/hook.bc']?.content)
.toString('utf-8')
.match(/\{[^0-9a-fx]+?(0x[0-9a-f]{2}[^0-9a-fx]+?)+\}/misg)?.[0]
.slice(1, -1).trim().split(',').map(o => o.trim().slice(-2)).join('')
document.write(compiledHook)
})Upload qjsc.wasm and create a .js file @ the virtual filesystem, e.g. sample.js, and then use argument:
-c -o sample.bc sample.js