I want to try using QuickJS compiled to WebAssembly in a browser as a way of executing untrusted user-provided JavaScript in a sandbox.
My plan is to host it locally, not load it from a CDN. I also want to be able to write most of my regular JavaScript without using build tooling - so I want a QuickJS bundle that I can load using a good old-fashioned <script> tag.
This is always harder than I think it will be. In this case the quickjs-emscripten README starts with the following:
1
import { getQuickJS } from"quickjs-emscripten"
2
...
That’s not enough information for someone like me to get started!
Here’s the recipe I figured out that got me to where I wanted to be.
Install and build quickjs-emscripten using npm and webpack#
I do not want to have to run npm and webpack as part of my day-to-day project work, but I’m happy to run them once to get me a bundle that I can use.
I started by installing quickjs-emscripten and webpack in a temporary directory:
Terminal window
1
cd/tmp
2
mkdirqjs
3
cdqjs
4
npminstallquickjs-emscriptenwebpackwebpack-cli
Tools like webpack like to run against an “entry point” - a script that depends on other libraries that it can bundle and minify and tree shake and suchlike.
I just want something I can load into a web page as a script, so I created the simplest entry point I could that appeared to work. I saved this in src/quickjs.js:
1
import { getQuickJS } from"quickjs-emscripten";
2
window.getQuickJS = getQuickJS;
Then I configured webpack (with the help of Claude 3 Opus) by creating this webpack.config.js file:
1
constpath=require('path');
2
3
module.exports= {
4
entry: './src/quickjs.js',
5
output: {
6
filename: 'quickjs.js',
7
path: path.resolve(__dirname, 'dist'),
8
},
9
mode: 'production'
10
};
I started with development as the mode, but production produces a smaller set of files.
I was worried that webpack might have built me a bundle that requires hosting in /dist/ - but thankfully that wasn’t the case.
I tried renaming dist/ to different things and making it part of a nested folder structure. Provided I loaded that initial /path/to/quickjs.js file, the rest of the files were loaded relative to that.
For anyone who wants a usable copy of quickjs-emscripten without having to run npm and webpack themselves, I created a Gist containing the files described above: