LoginSignup
19
16

More than 5 years have passed since last update.

mini_racerと、シンプルさのメリット

Last updated at Posted at 2018-12-11

Railsのプロジェクトを書いていたところ、ある1つのGemの存在を知りましたが、そこから派生していろいろなことに考えが思い至っていきました。

therubyracerとは

Railsでは、JavaScriptやCSSといったアセットの生成用としてSprocketsという仕組みが組まれていますが、CoffeeScript、Uglifier、autoprefixerなど、アセットのコンパイルにはJavaScriptで書かれたコードを多用するものなので、execjsという仕組みが入っています(過去に自分が書いたもの)。

そして、JavaScriptを動かすランタイムが必要なのですが、Unix系では多くの場合、V8エンジンを組み込んだtherubyracerがよく使われて…いました。

問題点

therubyracerはV8を細かく制御できる…のはいいのですが、細かなところまで使っているのが仇となって、

  • テストも回しづらい
  • V8のアップデートに追随するのが困難

というような状況になり、ついにはセキュリティ問題も含んだ古いV8でしか動かない状態が固定化してしまいました。

新顔のmini_racer

ここで登場したのがdiscourse/mini_racerです。自称「最低限のブリッジ」を謳ってはいますが、ふつうにJavaScriptのコードを呼んで実行する以上のこともできますし、よほど極限的な用途でもない限り事足ります。

ブリッジ部分をシンプルにしたことで、V8のバージョン依存性も緩やかになり、バージョンアップに追随しやすくなっています。そして、libv8自体もバージョンが上がったことで、インストール性が改善されているようです。

シンプルさの価値

Unix哲学にも、「一つのことを行い、またそれをうまくやるプログラムを書け。」という言葉があります。「RubyからJavaScriptを実行するランタイム」の場合、大半のユーザーが求めるものは「execjsで実行できること」でしょうから、あまり複雑なバインディングを取らずに簡潔化する、mini_racerの戦略も間違いなく合理的なものです。

もっとシンプルにしようとすると、別な問題が

とはいえ、libv8もまだまだ巨大なプロダクトで、Rubyに組み込むのがうまくいかないこともあります。これをシンプル化する方策もいくつか考えられます。

  • Duktapeのような、もっと軽量で組み込みに向いたJavaScriptエンジンを使う
  • 別にインストールしたNode.jsを呼び出す形にして、組み込みの煩雑さを回避する

これらの方策でシンプルさは増しますが、引き換えに速度面ではハンデを負うことになります。これは多くの場合に問題となることですが、速度と性能のバランスも時を減れば移り変わっていくので、最適な形を選ぶのが難しいものです。

ただ、execjsのようなレイヤーが入っていれば、使うランタイムも適宜切り替えられますので、このような抽象化レイヤーを入れて部品を入れ替え可能にしておく、というのもあとあと役に立ちうる設計です。

別解

もはやSprocketsには見切りをつけて、アセット類はすべてWebpackに任せる、というような分業も1つの方法かもしれません。ただ、CommonJSやES Modulesで標準化されているJavaScriptはいいとして、CSSをWebpackに載せてしまうと、Webpackが廃れたときに行き詰まる危険性が考えられます。

外部リンク

19
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16