どうも。Railsを触っているとbundle execをつけなさいとか、bin/railsの方がいいよとか聞きますが、実際にはどうなのかと言うことについて調べました。
結論
こちらの記事がまとめてくださっていました。ちょっと自分なりに補足情報を入れておきたいと思います。
bundle execをつけないとGemfile.lockに基づかずにgemのバージョンが決定される
(bundle execをつけるとGemfile.lockに書かれているバージョンのgemが動く )
普通にrails sとかすると、Gemfile.lockに関係なくgemのバージョンが決定されます。
例えばgemfileにバージョンの指定がない状態で記載されているgemってありますよね?以下のような感じです。
gem 'pg' #バージョンの指定がない
こういった場合って、毎回rails sすると、最新のバージョンが持って来れられることになります。
つまりですね、一年前と今日、もしくは一年後でrails sすると全く異なるバージョンのgemが持ってこられると言うことになるんですね。
そうするとなんか動かないと言うことが出てきたりします。
そういった時のために、gemファイルではバージョンの指定をするのもそうなんですが、gemfile.lockであらかじめ決められているバージョンを使ってあげれば、大丈夫と言うことです。
つまりbundle execをつけてあげることで、昔ちゃんと動いていた状態のgemの依存関係、つまりgemfile.lockに記載されている情報で起動させてあげることができると言うことです。
bin/rspecのように書くとspringの恩恵を受けて動作がはやくなる
このbinについてですが、railsアプリケーションの中にbinと言うフォルダがあると思います。このbinはそちらのフォルダのことを指しています。
そして、binの中にはspringと言う処理の高速化に一役買ってくれるやつ(サーバー)があります。
binをつけてあげることで、springも一緒に起動してくれるので、高速化して良いと言う話です。
rails
コマンドだけはbin
を省略してもbin/rails
と解釈される
こちらですが、多分バージョンが上がってからbinを省略しても大丈夫になったんだと思います?
こちらで調べた感じだとrails 4時代から、railsと書いただけで、bin/railsとしての処理が内部的に走っていたみたいですね。。。
つまりですね、bin/railsと書いていた方が、springの恩恵を受けられて、早く動く時代があったと言うことですね。
ところが現在では、rails コマンドだけでもbin/railsと解釈されるようになったと言うことです。
つまりまとめると
- railsコマンドには何もつけなくてOK。結局bin/railsが走っていることになります。
- binディレクトリにファイルが存在するコマンドはbin/〇〇。例えばrspecなどが高速化の時に、行う処理ですね。bin/をつけることでspringサーバーが動いてくれるので、はやくなります。
- それ以外のコマンドはbundle exec 〇〇で実行します。例えばrubocopなどのリント系ですね。これをbundle execをつけてあげることで、ちゃんとgemfile.lockに書かれているバージョンで動かすことができます。もしつけないと、最新バージョンを引っ張ってきて実行することになると言うことですね。