Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save siuying/4802c479843a48355b6bc72e98146d3d to your computer and use it in GitHub Desktop.
Save siuying/4802c479843a48355b6bc72e98146d3d to your computer and use it in GitHub Desktop.

How to use Bundler and RubyGems on WebAssembly

# Download prebuilt ruby
curl -LO https://github.com/ruby/ruby.wasm/releases/download/2022-05-11-a/ruby-head-wasm32-unknown-wasi-full.tar.gz
tar xfz ruby-head-wasm32-unknown-wasi-full.tar.gz

# Install the same version of native ruby to avoid bundler version mismatch in "BUNDLED WITH" of Gemfile.lock
rvm install 3.2.0-preview1
rvm use 3.2.0-preview1

# Setup Gemfile
bundle init
bundle add gammo

# Install gems in vendor/bundle to mount it on WASI
bundle config set --local path 'vendor/bundle'
bundle install

cat <<EOS > my_app.rb
# 'require "bundler/setup"' is not precisely equivalent to 'bundle exec ...', but enough to load installed gems
require "bundler/setup"
require "gammo"

doc = Gammo.new('<html><body><h1>Hi</h1></body></html>').parse
pp doc.css('h1').first.inner_text
EOS

# Options:
# --mapdir /usr::./head-wasm32-unknown-wasi-full/usr    Map ruby directory
# --mapdir /root::./                                    Map user script directory
# --mapdir /dev::/dev                                   Hack to alllow RubyGems to open /dev/null in Gem::SilentUI
# --env BUNDLE_GEMFILE=/root/Gemfile                    Tell bundler where the Gemfile located because WASI has no PWD concept
wasmtime run \
  --mapdir /usr::./head-wasm32-unknown-wasi-full/usr \
  --mapdir /root::./ \
  --mapdir /dev::/dev \
  --env BUNDLE_GEMFILE=/root/Gemfile \
  head-wasm32-unknown-wasi-full/usr/local/bin/ruby -- /root/my_app.rb

# packing into single WASI app
wasi-vfs pack ./head-wasm32-unknown-wasi-full/usr/local/bin/ruby \
  --mapdir /root::./ \
  --mapdir /usr::./head-wasm32-unknown-wasi-full/usr \
  -o my-ruby-app.wasm
wasmtime my-ruby-app.wasm \
  --mapdir /dev::/dev \
  --env BUNDLE_GEMFILE=/root/Gemfile \
  -- /root/my_app.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment