QA@IT

Railsを動かすproduction環境にJavaScriptエンジンを入れたくない

3243 PV

Rails 3.2を使用したサイトを構築していますが、execjsに依存してしまっているので自動的にサーバサイドにJavaScript実行環境が必要になります。developmentは、それでも構わないのですが、本番環境に安易にインタープリタを増やしたくありません。execjsを使わない形でRailsアプリケーションを動かす方法はないのでしょうか?


以下編集です。状況を再現するプロジェクトを作りました。https://github.com/shyouhei/rails-without-execjs

% git clone https://github.com/shyouhei/rails-without-execjs.git
% cd rails-without-execjs.git
% bundle install
% bundle exec rails server webrick -e production

として、http://localhost:3000/assets/application.jsにアクセスしてみてください。public/assets/application.jsではないものが見えるかと思います。

回答

これでbundle rake assets:precompileが生成するpublic/assets以下のファイルが表示されるかと思います。

diff --git a/config/environments/production.rb b/config/environments/production.rb
index 1cbb7b4..abe4b72 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -9,13 +9,13 @@ RailsWithoutExecjs::Application.configure do
   config.action_controller.perform_caching = true

   # Disable Rails's static asset server (Apache or nginx will already do this)
-  config.serve_static_assets = false
+  config.serve_static_assets = true

   # Compress JavaScripts and CSS
-  config.assets.compress = true
+  config.assets.compress = false

   # Don't fallback to assets pipeline if a precompiled asset is missed
-  config.assets.compile = true
+  config.assets.compile = false

   # Generate digests for assets URLs
   config.assets.digest = true
編集 履歴 (0)
  • これで望む結果になりました。ありがとうございます。 -

質問の意図は、プロダクションでJSのVMを動かしたくないということですよね?

ごもっともだと思います。したがって、デフォルトではconfig/environments/production.rb

# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false

となっていて、もしコンパイル済みでないassetへのアクセスがあると

Sprockets::Helpers::RailsHelper::AssetPaths::AssetNotPrecompiledError

と例外を投げるはずです。

が、そのリポジトリを見ると

https://github.com/shyouhei/rails-without-execjs/blob/master/config/environments/production.rb#L18

と、わざわざ config.assets.compile = true を指定してあるので、動的にコンパイルするためにVMをロードする必要が出てしまいます。

個人的には、コンパイル後のアセットをgitに入れてしまうのはナンセンスだと思っているので、デプロイ時にcapistranoにコンパイルさせるのがいいと思います。毎回コンパイルするのを避けるために

http://www.bencurtis.com/2011/12/skipping-asset-compilation-with-capistrano/

みたいにして変更があったときのみコンパイルする、などの工夫で、デプロイ速度の低下を最低限におさえることも可能です。

編集 履歴 (0)

therubyracer はどうでしょうか。
https://github.com/cowboyd/therubyracer
Gemfile に書いておけば、勝手に execjs が認識して使ってくれるはずです。サーバ環境によってはビルドできないかもしれませんが。

編集 履歴 (0)
  • いや、だから、そういうのを入れたくないんですよ。 -

execjs を 使っているのは assets pipeline まわりですよね?であれば開発環境で

rake assets:precompile 

をして、できあがった public/assets 配下のファイルをなんからの方法で production 用のサーバに送ってあげれば javascript 実行環境はなくても動かせると思います

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。