I tried it a few times before, and it was a bit too complicated, so I dropped it and did something else, but the series is nearing completion, so I can't postpone any longer.
Opal Ruby is complicated primarily because it's not meant to be used as JavaScript-like language, it's meant to be used as part of a bigger system, generally with a Ruby backend, so all that wiring is behind the scenes. But we'll use it directly.
For this episode, I'll only do the frontend (renderer) in Opal Ruby, and the backend (main) in JavaScript.
index.js
The backend process will just open public/index.html
:
let { app, BrowserWindow } = require("electron")
function createWindow() {
let win = new BrowserWindow({height: 600, width: 800})
win.loadFile(`${__dirname}/public/index.html`)
}
app.on("ready", createWindow)
app.on("window-all-closed", () => {
app.quit()
})
public/index.html
For the app we'll just show a button, and a count of how many times it was clicked:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ruby Opal Application</title>
<link href="app.css" rel="stylesheet" type="text/css" />
</head>
<body>
<button>Click the button</button>
<div>Click count: <span id="count">0</span></div>
<script src="./build/app.js"></script>
</body>
</html>
The compiled file will go to ./build/app.js
.
public/app.css
We're doing basically mode: dark; display: center;
except with a few more words:
body {
margin: 0;
background-color: #444;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 300%;
min-height: 100vh;
}
button {
font-size: unset;
}
Gemfile
That covers the Electron part, so let's get to the Ruby part. Gemfile
is like package.json
- and there's Gemfile.lock
corresponding to package-lock.json
gem "opal", "~> 1.3"
Rakefile
We need to tell Opal to build the app.js
. There are likely some packages for watching the source folder and doing it automatically, but I decided to do it the hard way for now.
All this could also go into package.json
scripts
section.
require "pathname"
desc "Build JavaScript files"
task "build" do
Pathname("public/build").mkpath
sh "opal src/app.rb -c >public/build/app.js"
end
src/app.rb
And finally the app! Opal Ruby generally requires wrappers around JavaScript objects. There are a few ways to do this - native
module provides $$
which corresponds to JavaScript window
/global
except it wraps every JavaScript object in an Opal Ruby wrapper:
require "native"
counter = 0
button = $$.document.querySelector("button")
count = $$.document.querySelector("#count")
button.addEventListener("click") do
counter += 1
count.innerText = counter
end
Results
Here's the results:
In the next episode we'll write the terminal app in Opal Ruby.
As usual, all the code for the episode is here.
Top comments (0)