This is a JavaScript runtime for the Apoxy Edge Functions. It allows you to write serverless functions in JavaScript that are executed for each in-flight request or as terminating HTTP handler a la Cloudflare Workers.
This runtime is built using these libraries:
- quickjs-wasm-rs - A Rust wrapper around QuickJS that compiles to WebAssembly (aka Javy from Shopify).
- wizer to run user-supplied Javascript code in a WebAssembly sandbox.
- Extism Rust PDK - A Rust library for writing Extism plugins.
It interacts with Apoxy Edge Function runtime via the Extism PDK.
You will want to use a bundler if you want to want to or include modules from NPM, or write the plugin in Typescript, for example.
There are 2 primary constraints to using a bundler:
- Your compiled output must be CJS format, not ESM.
- You must target es2020 or lower.
The easiest way to set this up would be to use esbuild. The following is a quickstart guide to setting up a project:
# Make a new JS project
npm init -y
npm install esbuild --save-dev
mkdir src
mkdir dist
Optionally add a jsconfig.json
or tsconfig.json
to improve intellisense:
{
"compilerOptions": {
"lib": [], // this ensures unsupported globals aren't suggested
"types": ["@extism/js-pdk"], // while this makes the IDE aware of the ones that are
"noEmit": true // this is only relevant for tsconfig.json
},
"include": ["src/**/*"]
}
Add esbuild.js
:
const esbuild = require('esbuild');
// include this if you need some node support:
// npm i @esbuild-plugins/node-modules-polyfill --save-dev
// const { NodeModulesPolyfillPlugin } = require('@esbuild-plugins/node-modules-polyfill')
esbuild
.build({
// supports other types like js or ts
entryPoints: ['src/index.js'],
outdir: 'dist',
bundle: true,
sourcemap: true,
//plugins: [NodeModulesPolyfillPlugin()], // include this if you need some node support
minify: false, // might want to use true for production build
format: 'cjs', // needs to be CJS for now
target: ['es2020'] // don't go over es2020 because quickjs doesn't support it
})
Add a build
script to your package.json
:
{
"name": "your-plugin",
// ...
"scripts": {
// ...
"build": "node esbuild.js && apoxy-js dist/index.js -o dist/plugin.wasm"
},
// ...
}
Before compiling the compiler, you need to install prerequisites.
- Install Rust using rustup
- Install the WASI target platform via
rustup target add --toolchain stable wasm32-wasi
- Install the wasi sdk using the makefile command:
make download-wasi-sdk
- Install CMake (on macOS with homebrew,
brew install cmake
) - Install Binaryen and add it's install location to your PATH (only wasm-opt is required for build process)
- Install 7zip(only for Windows)
Run make to compile the core crate (the engine) and the cli:
make
To test the built compiler (ensure you have Extism installed):
./target/release/apoxy-js bundle.js -o out.wasm
# => "{\"count\":4}"