-
Notifications
You must be signed in to change notification settings - Fork 9
Rails asset pipeline
HerokuのCedarスタック上で動くRailsアプリケーションはアセットパイプラインをローカルかデプロイ時、もしくは実行時にコンパイルした状態にすることができます。新しいユーザの方ならば、この先を進める前にCedar上でRails 3.xのアプリケションを作るためのチュートリアルを読む事をおすすめします。
RailsのアセットパイプラインはHerokuのCedarスタックでサポートされています。新しいパイプラインは、Railsスタックの中でアセットに1級の市民権を与えました。デフォルトで、RailsはJavaScriptを書くためにCoffeeScriptを使用し、CSSを書くためにSCSSを使用します。DHHは彼のRailsカンファレンスでのキーノートの中で素晴らしいイントロダクションをしてくれました。
Railsのアセットパイプラインはアセットをコンパイルし、毎回アプリが起動するたびにコンパイルされるよりも良い、フロントで常にキャッシュされた状態にしておくassets:precompile
rakeタスクを提供します。
Herokuでアセットパイプラインを使う方法は3つあります。
- ローカルでアセットをコンパイルする。
- Slugを作っているときにアセットをコンパイルする。
- 実行時にアセットをコンパイルする。
ローカルであなたのアセットをコンパイルするためには、assets:precompile
タスクをローカルで、あなたのアプリケーション上で実行してください。プロダクション環境のアセットが生成されるように、production
環境を使う事を忘れないでください。
:::term
RAILS_ENV=production bundle exec rake assets:precompile
public/assets
ディレクトリが作成されます。このディレクトリの中に、コンパイルされたアセットのmd5sumsが含まれているmanifest.yml
があると思います。public/assets
をあなたのGitリポジトリにAddする事で、Herokuで利用可能になります。
:::term
git add public/assets
git commit -m "vendor compiled assets"
Pushした時、出力されたメッセージの中に、あなたがローカルでアセットをコンパイルしたことを検知したメッセージがあるはずです :
:::term
-----> Preparing Rails asset pipeline
Detected manifest.yml, assuming assets were compiled locally
もし、ローカルでアセットのコンパイルがガスんでいない場合、私たちはassets:precomplie
タスクをSlugの作成中に実行しようとします。あなたのPush時の出力は以下のようになるでしょう :
:::term
-----> Preparing Rails asset pipeline
Running: rake assets:precompile
私たちのSlugの作成処理にRakeタスクがどのように動くのかという説明がある、下のトラブルシューティングのセクションを確認してください。
もし、assets:precompile
タスクが失敗したら、実行時のアセットの収集がうまく行かなくなり、出力がそれを示します。
:::term
-----> Preparing Rails asset pipeline
Running: rake assets:precompile
ERROR: Unable to connect to memcached
Precompiling assets failed, enabling runtime asset compilation
Injecting rails31_enable_runtime_asset_compilation
デフォルトでは、Railsはアセットが実行時にコンパイルされることを阻止しようとします。そのため、私たちは実行時のアセットコンパイルを可能にするために、このプラグインを差し込んでいます。
静的なアセットのキャッシュは、アプリケーション内でRack::Cacheミドルウェアを使うか、CDNを使ってより分散的な状態で実現をすることができます。あなたのアプリケーションからアセットを提供する事は、Dynoのリソースを要求することになるため、あなたのニーズに合った適切なアセットキャッシュの方法を検討してください。
Slugの作成時にassets:procompileが失敗している場合についての修正や対応は、今回ここにはありません。以下で私たちはなぜ動かないのかという理由について見てみたいと思います。
一番一般的なassets:precompile
の失敗の原因は、アプリケーションが起動するためにその環境の存在に依存していることにあります。あなたのアプリケーションの設定変数はSlug作成時にその環境に存在していません、そのためあなたは、イニシャライザのなかで設定変数(またアドオン)についてnil
の場合を想定してハンドリングするようにステップをふむ必要があります。
もし、以下のようなものを見た場合、 :
:::term
could not connect to server: Connection refused
Is the server running on host "127.0.0.1" and accepting
TCP/IP connections on port xxxx?
これは、あなたのアプリケーションがrake assets:precompile
の一部として、データベースに接続しようとしているところです。なぜなら、設定変数はその環境内で存在していないにもかかわらず、Railsを特定するためにDATABASE_URL
プレースホルダを使用しているためです。Slugの作成時に実行する完全なコマンドは以下の通りです :
env RAILS_ENV=production DATABASE_URL=scheme://user:[email protected]/dbname bundle exec rake assets:precompile 2>&1
-
scheme
はGemfile
から転出された適切なデータベースのアダプタに置き換えられます。
アセットをプリコンパイルしている間、Rails 3.xでは、config/applicaiton.rb
の中で以下の行をこの通りにすることでデータベースの接続と、初期化処理をしないようにすることができます。
:::term
config.assets.initialize_on_precompile = false
Rails 4.x ではこのオプションは削除され、もう必要ありません。
もし、rake assets:precomile
がまだ動いているようであれば、存在していないデータベースをconfig/database.yml
内で設定し、rake assets:precompile
を実行しようとすることで、ローカルでこれをデバッグすることができます。理想的にはあなたはデータベースに接続することなしで、このコマンドが実行できるようになっているべきです。
もし、以前therubyracer
かtherubyracer-heroku
を使っていた場合は、これらのGemがメモリの大部分を消費するため、もう必要となくなり、強く非推奨となりました。
もし、実行時にアセットをコンパイルする必要がある場合、JavaScriptの実行系にアクセスするため、必ずあなたのPATHにbin
を追加してください。heroku config
を使って現在のあなたの設定を確認してください :
:::term
$ heroku config
PATH => vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin
もし、あなたのPATH変数がそれ自身にbin
を含んでいない場合は、以下を実行することで更新をしてください :
:::term
$ heroku config:set PATH=bin:vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin
Adding config vars:
PATH => vendor/bundle/ru...usr/bin:/bin:bin
Restarting app... done, v7.