彼女からは、おいちゃんと呼ばれています

ウェブ技術や日々考えたことなどを綴っていきます

Rails 3.2 の development 環境で javascript が二重に実行されてしまうときの対処

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 環境で下記の手順を行えば、解決するはずです。

  1. public/asssets/application.js* を削除
  2. application.js の //= の箇所を一旦削除(あとで戻すので、控えておく)
  3. Web サーバ再起動
  4. ブラウザからアクセス
  5. application.js の //= の箇所を再度記述
  6. Web サーバ再起動 <<

以上です。

*おまけ

偶然、下記の記事を見つけたのですが、上のようにやれば、config.assets.debug はそのままで大丈夫だと思います。

-Rails x jQuery Mobile でフォーム2重送信 - ボクココ