Slide 1

Slide 1 text

Shigeru Nakajima @ 2023/05/13 Luxiar co.,ltd

Slide 2

Slide 2 text

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.

Slide 36

Slide 36 text

Thank you for your attention.