Rails 3.2 を使っていて、development 環境で javascript が二重に実行されてしまうという問題に遭遇しました。production 環境では起きていません。
いろいろいじってみたところ、ようやく解決できたので、メモしておきます。
*0. 前提
javascript は下記のように配置されているものとします。
|| |-- app |-- assets |-- javascript |-- application.js |-- foo.js `-- bar.js ||<
application.js の中身は下記のとおり。
|javascript| //= require foo //= require bar ||<
app/views/layouts/application.html.erb での javascript 呼び出し。
|| <%= javascript_include_tag "application" %> ||<
config/environments/development.rb では、自動コンパイルする(application.js に統合させない)ように設定しています。
|ruby|
Expands the lines which load the assets
config.assets.debug = true ||<
*1. 現象
アプリケーションにブラウザからアクセスして、ページのソースを表示させると、javascript の読み込み箇所は下記のようになっています。
|html|
||<
foo.js も bar.js も読み込まれているにも関わらず、読み込まれた application.js の中に foo.js の内容も bar.js の内容も入っているために、あらゆる挙動が二重で行われていました。
本来であれば、読み込まれた application.js は、下記のように(コメントのみ記述されていて)内容を持たないはずです。
|javascript| // This is a manifest file that'll be compiled into application.js, which will include all the files // listed below. // // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path. // // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the // the compiled file. // // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD // GO AFTER THE REQUIRES BELOW. //
; ||<
*2. 原因
|ruby| config.assets.debug = true ||<
と設定した development 環境のみ使っていれば public/assets は空のはずです。
しかし、同じサーバ内で production として assets:precompile したりもしていました。
そのため、public/assets 内に js を統合させた application.js が入っていて、ブラウザがそれを読み込んでいたことが今回の問題の原因でした。
*3. 対策
development 環境として使うサーバと、production 環境として使うサーバを分ける。development 環境として使うサーバでは assets:precompile しないという運用にして、そのうえで、development 環境で下記の手順を行えば、解決するはずです。
- public/asssets/application.js* を削除
- application.js の //= の箇所を一旦削除(あとで戻すので、控えておく)
- Web サーバ再起動
- ブラウザからアクセス
- application.js の //= の箇所を再度記述
- Web サーバ再起動 <<
以上です。
*おまけ
偶然、下記の記事を見つけたのですが、上のようにやれば、config.assets.debug はそのままで大丈夫だと思います。