CodeLog

開発メモ

Rubyからjavascriptを実行するExecJS

Ruby on Railsチュートリアルに沿って勉強中です。

  1. rails new
  2. Gemfileを編集
  3. bundle update && bundle install
  4. rails server
    • ここで以下のようなエラーが発生しました。
Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

チュートリアルには「JavaScriptランタイムがインストールされていないというエラーが表示された場合は、GitHubのexecjsページにあるインストール可能なランタイムを確認してください。Node.jsが特にお勧めです」とのことですが…。
あーありがち - Rubyのexecjsがすごい件」の説明やRubyGem.org「execjs | RubyGems.org | your community gem host」で何となく分かったつもりになりました。

ExecJSとは

  • Rubyスクリプトからjavascriptコードを実行するための仕組み
  • ExecJSがjavascriptエンジンを自動検索(=autodetect)する
  • サポートしているjavascriptエンジンは以下の通り
ExecJS supports these runtimes:

therubyracer - Google V8 embedded within Ruby
therubyrhino - Mozilla Rhino embedded within JRuby
Node.js
Apple JavaScriptCore - Included with Mac OS X
Microsoft Windows Script Host (JScript)

つまり、最初のエラーはExecJSがサポートするjavascriptエンジンがないのでインストールする必要があることを意味していたようです。
動作が速いと評判が良さそうなのでtherubyracerにします。

$ gem list therubyracer -b

*** LOCAL GEMS ***



*** REMOTE GEMS ***

therubyracer (0.12.1, 0.5.2 x86-darwin-10, 0.5.1 x86-darwin-9, 0.5.0 x86-linux x86_64-linux)
therubyracer-discourse (0.12.0)
therubyracer-freebsd (0.10.1)
$ gem install therubyracer
Fetching: ref-1.0.5.gem (100%)
Successfully installed ref-1.0.5
Fetching: libv8-3.16.14.7-x86_64-linux.gem (100%)
Successfully installed libv8-3.16.14.7-x86_64-linux
Fetching: therubyracer-0.12.1.gem (100%)
Building native extensions.  This could take a while...
Successfully installed therubyracer-0.12.1
3 gems installed
$ rails server
`autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)

これで解決すると思いきや、また同じエラーが表示されてしまいました。
次にbundle installで試してみます。

$ gem uninstall therubyracer   # 一度元に戻すためにアンインストール
$ vi Gemfile                  # 最後に「gem 'therubyracer'」を追記
$ bundle install
......
Installing therubyracer 0.12.1 # インストールされたことを確認
......
$ rails s
=> Booting WEBrick
=> Rails 4.0.5 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2015-03-21 22:31:03] INFO  WEBrick 1.3.1
[2015-03-21 22:31:03] INFO  ruby 2.0.0 (2014-11-13) [x86_64-linux]
[2015-03-21 22:31:03] INFO  WEBrick::HTTPServer#start: pid=2906 port=3000

無事に起動したようです。

bundlerはアプリ環境ごとにgemを固定するための仕組みだと思います。
そのため、gemでtherubyracerをインストールしてもGemfile.lockで対象アプリのライブラリは固定されているため、GemFilesにライブラリを書いてbundle installする必要があったのではないかと思います。(違っていたらごめんなさい。)

bundle installとbundle update

  • bundle install
    • Gemfileに更新があれば、インストールされていないgemをインストールして、Gemfile.lockを更新
    • 更新がなければ、Gemfile.lockに従ってgemを更新
    • Gemfile.lockがなければGemfileに従ってgemの更新を行い、Gemfile.lockを作成
  • bundle update
    • Gemfileに従ってgemの更新を行い、Gemfile.lockを上書き