Self-introduction
•ledsun@github or twitter
•I am programing various applications.
•Ruby x Rails
•C# x Windows Form
•PHP x Laravel
•JavaScript
Slide 3
Slide 3 text
I am a member of
• For 15 years.
• Platinum sponsor
Slide 4
Slide 4 text
Today I will talk about
1. What is ruby.wasm
2. I want use gem in ruby.wasm
3. Way to approach
4. Strategy
5. Implementation status
6. Difficulties in implementation
7. Future Ambitions
Slide 5
Slide 5 text
What is ruby.wasm
•Ruby scripts run in the browser.
Slide 6
Slide 6 text
Wordle Search
•Do you know Wordle?
• https://www.nytimes.com/games/wordle/index.html
•Wordle Search
•https://wordle-search.onrender.com/
• I created this application that searches for
words according to the Wordle hints.
Slide 7
Slide 7 text
Source code for Wordle Search
Slide 8
Slide 8 text
What is ruby.wasm
•Ruby scripts run in the browser.
•Other sample applications can be found at
the following URL
• https://github.com/ruby/ruby.wasm/wiki/Showcase
Slide 9
Slide 9 text
I want use gem ruby.wasm
•CSV gem can be used.
•Third party gem cannot be used
•File system limitations of ruby.wasm
•ruby.wasm can only use the read-only
file system that ruby.wasm has prepared
in advance.
Slide 10
Slide 10 text
Way to approach
•A look back at the history of JavaScript.
•JavaScript had the same problem.
ruby.wasm CRuby
browser Node.js
gem
npm
Ruby
JavaScript
Slide 11
Slide 11 text
Modules in JavaScript
•In the past
•JavaScript had no concept of modules, only
script tags in the browser.
• Node.js ( 2009 )
• Node.js brought modules to JavaScript.
•import-maps ( 2021 )
• 12 years of trial and error
Slide 12
Slide 12 text
First approach in JavaScript
•Browserify ( 2011 )
•Bundle all dependent JavaScript files before
execution.
•Then the file system becomes unnecessary.
Bundled.js Browserify Index.js
a.js
b.js
Browsers refer only this file
Slide 13
Slide 13 text
Browserify also changes the format of the
module.
•The browser had no module for JavaScript
•Using iife to create a scope and reproduce
the movement of the module
•ES module was introduced to standardize
module syntax (2015)
Slide 14
Slide 14 text
import was not compatible.
•import is an ESmodule instruction
equivalent to Ruby's require.
• Browsers
• import "https://code.jquery.com/jquery-
3.6.0.min.js"
•Node.js
• import “jquery”
• import “./jquery”
There is a difference between file
systems and URLs.
Slide 15
Slide 15 text
Import-maps
•import-maps defines a map of file system
or module names and URLs.
Slide 16
Slide 16 text
Two approaches
•Bundling before execution
•Resolve dynamically at runtime using maps
Slide 17
Slide 17 text
My Choice
•Bundling before execution
•Resolve dynamically at runtime using maps
Write code Bundling Execution
Slide 18
Slide 18 text
Not like a scripting language
Write code Bundling Execution
Write code Execution
Write code Compile Execution
Scripting language
Compiled language
Slide 19
Slide 19 text
Makes me want to tune out the bundling
•Webpack dev-server
•Use cache for faster bundling
•esbuild
• Rebuild in another programming language for
faster bundling
Slide 20
Slide 20 text
Strategy
•How to implement
import-maps for
ruby.wasm
Slide 21
Slide 21 text
Difference between ESModule and Ruby
• In Ruby, there is require and require_relative
•require_relative uses relative paths
Slide 22
Slide 22 text
Relative paths are compatible with file
systems and URLs
•require_relative does not require import-
maps.
File system URL
Slide 23
Slide 23 text
Two-step strategy
1. require_relative
2. require and import-maps
Slide 24
Slide 24 text
Implementation Status
•Demo
•Simple loads work.
•Recursive loads do not work.
Slide 25
Slide 25 text
Difficulties in Implementation
1. Fetch API returns Promise,
but Ruby has no Promise.
2. The default Fiber Stack is small.
3. Requires URL of running Ruby script.
Slide 26
Slide 26 text
Fetch API
returns
Promise, but
Ruby has no
Promise
Slide 27
Slide 27 text
Use evalAsync to wait for Promise
Slide 28
Slide 28 text
The default Fiber Stack is small
•The default stack size for Fiber is 256 kb.
•Calling require_relative twice will cause a
SystemStackError.
Slide 29
Slide 29 text
Setting it to 20 mb solves this problem
Slide 30
Slide 30 text
Requires URL of running Ruby script
•Relative paths point to different URLs
depending on the path of the running Ruby
script.
a.rb b/b.rb
c.rb b/c.rb
require_relative “c.rb” require_relative “c.rb”
Slide 31
Slide 31 text
Requires URL of running Ruby script
•I created a stack that holds the Ruby
scripts running on the JavaScript side.
b/b.rb
a.rb a.rb a.rb
Slide 32
Slide 32 text
Future Ambitions
•Imagine after implementing require and
import-maps.
•Deployment is required to use the gem.
• “gem install” on the server.
• I want UNpkg for ruby.wasm.
Slide 33
Slide 33 text
UNpkg
•UNpkg is a CDN for modules published in
the NPM repository.
Slide 34
Slide 34 text
UNpkg image for ruby.wasm
Slide 35
Slide 35 text
Easier Ruby Programming for Browsers
1. require_relative allows for multi-module
applications.
2. require enables the use of third-party
gems.
3. UNpkg allows third-party gems to be
used without bundle install.