OpalでElectronのアプリをつくる(その1)

  • 1
    いいね
  • 0
    コメント

この記事はOpal Advent Calendar 2016の14日目の投稿として書いています。

またまた遅刻です。OpalでElectronアプリをつくろうとしたのですが、なかなか苦労してしまいました。
残念ながら今回の記事だけで完結しなそうです。

この記事には間違いがありました。詳しくは15日目の記事にゆずりますが、ここから先を読むときは注意してください。

electron_opalというのがあるので、これで楽勝なんじゃないかと思ったらこれがなかなかちゃんと動いてくれません。
とりあえず、ElectronでOpalのコードを実行できたのでそこまでの道のりをその1として書こうと思います。

まずはgem installと思いきや、RubyGems.orgに登録されていません。一応gemとして作られているので、git cloneしてきてGemfile

Gemfile
gem 'electron_opal', path: '../electron_opal'

のように書いてローカルのソースコードを参照するようにしました。(たぶんソースをいじらないと動かなそうという予感がしたので…)
README.mdはgithubが生成するデフォルトのままなので何の情報もありませんので、とりあえずソースを眺めます。

lib/electron_opal.rbをみるとRaketaskになっているようなのでとりあえず、Rakefileを書きます。

Rakefile
require 'bundler'
Bundler.require

taskとしては、default,build,debugがあるので、とりあえずbuildを試みます。

rake aborted!
NoMethodError: undefined method `source' for nil:NilClass
...

当然のようにエラーを吐きます。
electron_opal/lib/electron_opal.rb:70でエラーのようなのでソースをみます。
Sprockets::Environment#find_assetnilが返ってきているので、アセットがみつからないということが分ります。
とりあえず、Electronの流儀にそって、main.rbというファイルを作ります。

main.rb
puts 'Hello world'

rake buildします。同様のエラーです。
asset_pathを追加する必要がありそうです。
このへんパスをついかしているので、config.pathに追加すればよさそうです。丁度良くsetupメソッドが定義されています。
Rakefileに以下のように追加します。

Rakefile
setup do |config|
  config.paths << 'app'
end

main.rbapp以下に移動しましょう。

ビルドはできました。

rakeしてみます。

electronコマンドがないと言われるので、npm install -g electronします。

再チャレンジ

スクリーンショット 2016-12-15 1.01.43.png

Electron appがないと言われます。
Electron appとして成立させるためには、package.jsonが必要そうです。

package.json
{
  "name": "electron_opal",
  "version": "0.0.1",
  "main": "build/main.js"
}

最低限、何が必要か分かりませんがこんな感じで。

App threw an error during load
ReferenceError: Opal is not defined

<!-- ここから下の記述に間違いがありました。15日目の記事を参照してください。 -->

Opalが定義されていないと怒られるので、なんとかします。
ここからの戦いが長かったので、結論だけ

lib/electron_opal.rb:68

load_asset_code = Opal::Processor.load_asset_code(env, asset_name) if options[:load_asset_code]

どうもOpal::Processorでロードしているのが良くなさそう。最新のOpal 0.10.3でも試したりしましたがload_asset_codeは無くなっていました。
Opalのドキュメントを確認すると、Opal::Builderを使うのが正しそうです。

lib/electron_opal.rb:48

compile_js(config.app_class, load_asset_code: true)

write_to("#{config.app_class}.js", Opal::Builder.build(config.app_path).to_s, Opal::Builder.build('opal'))

こんな風にOpal::Builderように書きかえて、尚かつ、opal本体をコンパイルして含めるようにします。
app_pathRakefileで指定します。

  config.app_path = File.expand_path('../app/main.rb', __FILE__)

electron_opal.rb:86

    f.write source
    f.write load_code

ここは順序が逆なので、入れかえます。

$ bundle exec rake build
$ bundle exec rake

で無事にHello worldと表示されました。

結構苦労したわりには、まだGUIアプリになっていません。そもそもelectron_opal`が中途半端すぎでした。
次回からはelectron_opalに変わるものを作りながらGUIアプリとして成立するようにしていきたいと思います。
そういうわけでしばらくシリーズものになりそうです。

この投稿は Opal Advent Calendar 201614日目の記事です。